<commit_before>#include "classui.h"
#include "listworker.h"
#include <iostream>
#include <string>
#include <algorithm>
#include <vector>
#include <time.h>
#include <stdlib.h>

using namespace std;

ClassUI::ClassUI()
{

}
void ClassUI::mainMenu()
{
    if (firstRun == true)
    {
        cout << "\t" << "Welcome to the Amazing Database! " << endl;
        cout << "--------------------------------------------------------------" << endl;
        cout << "\t" << "   *** Quote of the day ***" << endl;
        cout << getQuotes() << endl;
        firstRun = false;
    }
    string choice;
    do
    {
        cout << "--------------------------------------------------------------" << endl;
        cout << " (1) - "  << "Add a scientist to the database." << endl;
        cout << " (2) - "  << "Remove a scientist from the database." << endl;
        cout << " (3) - "  << "View the entire database." << endl;
        cout << " (4) - "  << "Save the database." << endl;
        cout << " (5) - "  << "Search the database." << endl;
        cout << " (6) - "  << "Sort the database." << endl;
        cout << " (7) - "  << "Edit a scientist." << endl;
        cout << " (8) - "  << "Exit." << endl;
        cout << "Enter your command (1 - 8): ";
        cin >> choice;
        if (choice != "8")
        {
           select(choice);
        }
        else
        {
            list.saveFile();
            runOn = false;
        }
    }while(runOn == true);

    cout << endl;

}
void ClassUI::select(string ch)
{
    if(ch == "1")
    {
        cin.ignore();           // When using editPerson it will ignore the first letter unless this ignore is here rather then in addPerson
        addPerson();
    }
    else if(ch == "2")
    {
        remove();
    }
    else if(ch == "3")
    {
        viewAll();
    }
    else if(ch == "4")
    {
        save();
    }
    else if(ch == "5")
    {
        searching();
    }
    else if(ch == "6")
    {
        sorting();
    }
    else if(ch == "7")
    {
        editPerson();
    }
    else if(ch == "yo")
    {
        yo();
    }
    else
    {
        cout << "Invalid input. Please enter a number between 1 - 7." << endl;
    }
}
void ClassUI::view(int i)
{
    cout << "--------------------------------------------------------------" << endl;
    int nameSize  = list.getNameSize(i);

    cout << list.getName(i);

    if(nameSize > 0 && nameSize <= 7)
    {
        cout << "\t" << "\t" << "\t" << "\t";
    }
    else if(nameSize > 7 && nameSize <= 15)
    {
        cout << "\t" << "\t" << "\t";
    }
    else if(nameSize > 15 && nameSize <= 23)
    {
        cout << "\t" << "\t";
    }
    else if(nameSize > 23 && nameSize <= 31)
    {
        cout << "\t";
    }

    if(list.getGender(i) == 'M' || list.getGender(i) == 'm')
    {
        cout << "|Male" << "\t";
    }
    else
    {
        cout << "|Female" << "\t";
    }

    cout  << "|" << list.getBirth(i);

    if(list.getDeath(i) == 0)
    {
        cout << "\t" << "| n/a"  << "\t" << "|" << list.getAge(i) << endl;
    }
    else
    {
        cout << "\t" << "|" << list.getDeath(i) << "\t" << "|" << list.getAge(i) <<  endl;
    }

    cout << list.getComment(i) << endl;
}
void ClassUI::viewAll()
{
    cout << "--------------------------------------------------------------" << endl;
    cout << "Name" << "\t" << "\t" << "\t" << "\t" << "|Gender " << "|Born " << "\t" << "|Death"  << "\t" << "|Age" << endl;
    for(int i = 0; i < list.personsSize(); i++)
    {
        view(i);
    }
}
void ClassUI::addPerson()
{
    string name;
    string comment;
    char gender;
    char yesOrNo;
    int yearOfBirth = 0;
    int yearOfDeath = 0;

    cout << "--------------------------------------------------------------" << endl;
    cout << "Enter name of the scientist: ";
    std::getline(std::cin,name);
    cout << "Enter a gender (M/F): ";
    cin >> gender;

    if (gender == 'm')
    {
        gender = 'M';
    }
    else if (gender == 'f')
    {
        gender = 'F';
    }

    if (gender == 'm' || gender == 'M' || gender == 'f' || gender == 'F')
    {
       cout << "Enter a year of birth: ";
       cin >> yearOfBirth;
       if (yearOfBirth < 0 || yearOfBirth > 2016)
       {
           cout << "not a valid year of birth" << endl;
           return mainMenu();
       }
       cout << "Is the individual deceased? (y/n) ";
       cin >> yesOrNo;

       if (yesOrNo == 'Y' || yesOrNo == 'y')
       {
            cout << "Enter a year of death: ";
            cin >> yearOfDeath;
            if(yearOfBirth > yearOfDeath)
            {
                cout << "Not a valid year of death" << endl;
                return mainMenu();
            }
       }

       cout << "Enter a comment about the scientist: ";
       cin.ignore();
       std::getline(std::cin,comment);
    }
    else
    {
        cout << "Invalid gender! Try again." << endl;
        return mainMenu();
    }

    cout << "Are you sure that you want to add this scientist? (y/n) ";
    string validatePerson;
    cin >> validatePerson;

    if(validatePerson == "y")
    {
        cout << "New scientist added!" << endl;
        list.addNewPerson(name, gender, yearOfBirth, yearOfDeath, comment);
    }
    else
    {
        cout << "scientist not added!" << endl;
    }
}
void ClassUI::searching()
{
    cout << "-------------Select any of the following commands-------------" << endl;
    cout << "What do you want to search for?" << endl;
    cout << " (1) - Search by name." << endl;
    cout << " (2) - Search by gender." << endl;
    cout << " (3) - Search by year of birth." << endl;
    cout << " (4) - Search by age." << endl;
    cout << " (5) - Return to main menu." << endl;

    search();
}
void ClassUI::search()
{
    string searchChoice;
    cout << "Enter your command (1 - 5): ";
    cin >> searchChoice;
    cout << endl;

    if (searchChoice == "1")
    {
        string namesearch;
        cout << "--------------------------------------------------------------" << endl;
        cout << "Enter a name you want to search for: ";
        cin.ignore();
        std::getline(std::cin,namesearch);
        cout << "--------------------------------------------------------------" << endl;
        for(int i = 0; i < list.personsSize();++i)
        {
            std::size_t found = list.getName(i).find(namesearch);
            if (found!=std::string::npos)
            {
                view(i);
            }
        }

        if(list.nameSearcher(namesearch) == false)
        {
            cout << "Sorry that name is not in our database, but you can add a new scientist in the 'Add section' in the main menu." << endl;
            searching();
        }
    }
    else if (searchChoice == "2")
    {
        char gendersearch;

        cout << "Enter a gender you want to search for: (M/F)";
        cin >> gendersearch;

        if(gendersearch == 'm')
            {
                 gendersearch = 'M';
            }
        else if (gendersearch == 'f')
            {
                 gendersearch = 'F';
            }

        for(int i = 0; i < list.personsSize();++i)
        {
            if(gendersearch == list.getGender(i))
            {
                gendersearch = list.getGender(i);
                view(i);
            }
        }

        if(list.genderSearcher(gendersearch) == false)
        {
            cout << "Sorry that gender is not in our database, but you can add a new scientist in the 'Add section' in the main menu." << endl;
            searching();
        }
    }
    else if (searchChoice == "3")
    {
            int yearsearch;
            cout << "Enter a year you want to search for: ";
            cin >> yearsearch;

            for(int i = 0; i < list.personsSize();++i)
            {
                if(yearsearch == list.getBirth(i))
                {
                    yearsearch = list.getBirth(i);
                    view(i);
                }
            }

            if(list.yearSearcher(yearsearch) == false)
            {
                cout << "Sorry that year is not in our database, but you can add a new scientist in the 'Add section' in the main menu." << endl;
                searching();
            }
    }
    else if (searchChoice == "4")
    {
        int ageSearch;
        cout << "Enter a age you want to search for: ";
        cin >> ageSearch;

        for(int i = 0; i < list.personsSize();++i)
        {
            if(ageSearch == list.getAge(i))
            {
                ageSearch = list.getAge(i);
                view(i);
            }
        }

        if(list.ageSearcher(ageSearch) == false)
        {
            cout << "Sorry that age is not in our database, but you can add a new scientist in the 'Add section' in the main menu." << endl;
            searching();
        }
    }
    else if (searchChoice == "5")
    {
        mainMenu();
    }
    else
    {
        cout << "Error reading input. Please enter a number between 1- 3." << endl;
        search();
    }
}
void ClassUI::remove()
{
    string name;
    cout << "--------------------------------------------------------------" << endl;
    cout << "Enter the full name of the scientist that you want to remove: ";
    cin.ignore();
    std::getline(std::cin,name);

    if (list.removePersonFound(name) == true)
    {
        char validateRemove;
        cout << "Scientist found!" << endl;
        cout << "Are you sure you want to remove this scientist? (y/n): ";
        cin >> validateRemove;

        if(validateRemove == 'y' || validateRemove == 'Y')
        {
            if(list.removePerson(name) == true)
            {
                cout << "Scientist removed!" << endl;
            }
            else
            {
                cout << "Scientist not removed!" << endl;
            }
        }
        else
        {
            cout << "Scientist not removed!" << endl;
        }
    }
    else
    {
        cout << "Serson not found!" << endl;
    }

}
void ClassUI::save()
{
    list.saveFile();
    cout << "Database saved." << endl;
}
void ClassUI::yo()
{
    cout << "--------------------------------------------------------------" << endl;
    cout << endl;
    cout << "`8.`8888.      ,8'     ,o888888o.     " << endl;
    cout << " `8.`8888.    ,8'   . 8888     `88.   " << endl;
    cout << "  `8.`8888.  ,8'   ,8 8888       `8b  " << endl;
    cout << "   `8.`8888.,8'    88 8888        `8b " << endl;
    cout << "    `8.`88888'     88 8888         88 " << endl;
    cout << "     `8. 8888      88 8888         88 " << endl;
    cout << "      `8 8888      88 8888        ,8P " << endl;
    cout << "       8 8888      `8 8888       ,8P  " << endl;
    cout << "       8 8888       ` 8888     ,88'   " << endl;
    cout << "       8 8888          `8888888P'     " << endl;
    cout << endl;
}
string ClassUI::getQuotes()
{
    string quotes[5] = {"\"A good programmer is someone who always looks both ways before crossing a one-way street.\" (Doug Linder)",
                        "\"Programming is like sex. One mistake and you have to support it for the rest of your life.\" (Michael Sinz)",
                        "\"Walking on water and developing software from a specification are easy if both are frozen.\" (Edward V Berard)",
                        "\"One man's crappy software is another man's full time job.\" (Jessica Gaston)",
                        "\"A C program is like a fast dance on a newly waxed dance floor by people carrying razors.\" (Waldi Ravens)"
                       };
    int v1 = 0;
    srand (time(NULL));
    v1 = rand() % 5;
    return quotes[v1];
}
void ClassUI::sorting()
{
    string sortcho;
    cout << "Enter a sort command:" << endl;
    cout << "--------------------------------------------------------------" << endl;
    cout << " (1) - Sort by alphabetical order." << endl;
    cout << " (2) - Sort by chronological order." << endl;
    cout << " (3) - Sort by gender." << endl;
    cout << " (4) - Sort by age." << endl;
    cout << " (5) - Return to main menu." << endl;
    cout << "Enter your command (1 - 5): ";
    cin >> sortcho;
    cout << endl;

    if(sortcho == "1")
    {
        list.sortNames();
         viewAll();
    }
    else if(sortcho == "2")
    {
        list.sortBirth();
         viewAll();
    }
    else if(sortcho == "3")
    {
        list.sortGender();
        viewAll();
    }
    else if(sortcho == "4")
    {
        list.sortAge();
        viewAll();
    }
    else if(sortcho == "5")
    {
        mainMenu();
    }
    else
    {
        cout << "That is not a valid command! Try again." << endl;
        sorting();
    }
}
void ClassUI::editPerson()
{
    string name;
    cout << "Enter the full name of the Scientist that you want to edit: ";
    cin.ignore();
    std::getline(std::cin,name);
    if(list.removePersonFound(name))
    {
        list.removePerson(name);
        addPerson();
    }
    else
    {
        cout << "Scientist not found!" << endl;
    }
}
/*
void ClassUI::clearTheScreen() //A function that we wanted to use but had platform issues following it's use.
{
    #if defined(__linux__) || defined(__unix__) || defined(__APPLE__)
        system("clear");
    #endif

    #if defined(_WIN32) || defined(_WIN64)
        system("cls");
    #endif
}
*/
<commit_msg>gender lagað í add person<commit_after>#include "classui.h"
#include "listworker.h"
#include <iostream>
#include <string>
#include <algorithm>
#include <vector>
#include <time.h>
#include <stdlib.h>

using namespace std;

ClassUI::ClassUI()
{

}
void ClassUI::mainMenu()
{
    if (firstRun == true)
    {
        cout << "\t" << "Welcome to the Amazing Database! " << endl;
        cout << "--------------------------------------------------------------" << endl;
        cout << "\t" << "   *** Quote of the day ***" << endl;
        cout << getQuotes() << endl;
        firstRun = false;
    }
    string choice;
    do
    {
        cout << "--------------------------------------------------------------" << endl;
        cout << " (1) - "  << "Add a scientist to the database." << endl;
        cout << " (2) - "  << "Remove a scientist from the database." << endl;
        cout << " (3) - "  << "View the entire database." << endl;
        cout << " (4) - "  << "Save the database." << endl;
        cout << " (5) - "  << "Search the database." << endl;
        cout << " (6) - "  << "Sort the database." << endl;
        cout << " (7) - "  << "Edit a scientist." << endl;
        cout << " (8) - "  << "Exit." << endl;
        cout << "Enter your command (1 - 8): ";
        cin >> choice;
        if (choice != "8")
        {
           select(choice);
        }
        else
        {
            list.saveFile();
            runOn = false;
        }
    }while(runOn == true);

    cout << endl;

}
void ClassUI::select(string ch)
{
    if(ch == "1")
    {
        cin.ignore();           // When using editPerson it will ignore the first letter unless this ignore is here rather then in addPerson
        addPerson();
    }
    else if(ch == "2")
    {
        remove();
    }
    else if(ch == "3")
    {
        viewAll();
    }
    else if(ch == "4")
    {
        save();
    }
    else if(ch == "5")
    {
        searching();
    }
    else if(ch == "6")
    {
        sorting();
    }
    else if(ch == "7")
    {
        editPerson();
    }
    else if(ch == "yo")
    {
        yo();
    }
    else
    {
        cout << "Invalid input. Please enter a number between 1 - 7." << endl;
    }
}
void ClassUI::view(int i)
{
    cout << "--------------------------------------------------------------" << endl;
    int nameSize  = list.getNameSize(i);

    cout << list.getName(i);

    if(nameSize > 0 && nameSize <= 7)
    {
        cout << "\t" << "\t" << "\t" << "\t";
    }
    else if(nameSize > 7 && nameSize <= 15)
    {
        cout << "\t" << "\t" << "\t";
    }
    else if(nameSize > 15 && nameSize <= 23)
    {
        cout << "\t" << "\t";
    }
    else if(nameSize > 23 && nameSize <= 31)
    {
        cout << "\t";
    }

    if(list.getGender(i) == 'M' || list.getGender(i) == 'm')
    {
        cout << "|Male" << "\t";
    }
    else
    {
        cout << "|Female" << "\t";
    }

    cout  << "|" << list.getBirth(i);

    if(list.getDeath(i) == 0)
    {
        cout << "\t" << "| n/a"  << "\t" << "|" << list.getAge(i) << endl;
    }
    else
    {
        cout << "\t" << "|" << list.getDeath(i) << "\t" << "|" << list.getAge(i) <<  endl;
    }

    cout << list.getComment(i) << endl;
}
void ClassUI::viewAll()
{
    cout << "--------------------------------------------------------------" << endl;
    cout << "Name" << "\t" << "\t" << "\t" << "\t" << "|Gender " << "|Born " << "\t" << "|Death"  << "\t" << "|Age" << endl;
    for(int i = 0; i < list.personsSize(); i++)
    {
        view(i);
    }
}
void ClassUI::addPerson()
{
    string name;
    string comment;
    char gender;
    char yesOrNo;
    int yearOfBirth = 0;
    int yearOfDeath = 0;

    cout << "--------------------------------------------------------------" << endl;
    cout << "Enter name of the scientist: ";
    std::getline(std::cin,name);
    cout << "Enter a gender (M/F): ";
    cin >> gender;

    if (gender == 'm')
    {
        gender = 'M';
    }
    else if (gender == 'f')
    {
        gender = 'F';
    }

    if (gender == 'm' || gender == 'M' || gender == 'f' || gender == 'F')
    {
       cout << "Enter a year of birth: ";
       cin >> yearOfBirth;
       if (yearOfBirth < 0 || yearOfBirth > 2016)
       {
           cout << "not a valid year of birth" << endl;
           return mainMenu();
       }
       cout << "Is the individual deceased? (y/n) ";
       cin >> yesOrNo;

       if (yesOrNo == 'Y' || yesOrNo == 'y')
       {
            cout << "Enter a year of death: ";
            cin >> yearOfDeath;
            if(yearOfBirth > yearOfDeath)
            {
                cout << "Not a valid year of death" << endl;
                return mainMenu();
            }
       }

       cout << "Enter a comment about the scientist: ";
       cin.ignore();
       std::getline(std::cin,comment);
    }
    else
    {
        cout << "Invalid gender! Try again." << endl;
        return mainMenu();
    }

    cout << "Are you sure that you want to add this scientist? (y/n) ";
    string validatePerson;
    cin >> validatePerson;

    if(validatePerson == "y")
    {
        cout << "New scientist added!" << endl;
        list.addNewPerson(name, gender, yearOfBirth, yearOfDeath, comment);
    }
    else
    {
        cout << "scientist not added!" << endl;
    }
}
void ClassUI::searching()
{
    cout << "-------------Select any of the following commands-------------" << endl;
    cout << "What do you want to search for?" << endl;
    cout << " (1) - Search by name." << endl;
    cout << " (2) - Search by gender." << endl;
    cout << " (3) - Search by year of birth." << endl;
    cout << " (4) - Search by age." << endl;
    cout << " (5) - Return to main menu." << endl;

    search();
}
void ClassUI::search()
{
    string searchChoice;
    cout << "Enter your command (1 - 5): ";
    cin >> searchChoice;
    cout << endl;

    if (searchChoice == "1")
    {
        string namesearch;
        cout << "--------------------------------------------------------------" << endl;
        cout << "Enter a name you want to search for: ";
        cin.ignore();
        std::getline(std::cin,namesearch);
        cout << "--------------------------------------------------------------" << endl;
        for(int i = 0; i < list.personsSize();++i)
        {
            std::size_t found = list.getName(i).find(namesearch);
            if (found!=std::string::npos)
            {
                view(i);
            }
        }

        if(list.nameSearcher(namesearch) == false)
        {
            cout << "Sorry that name is not in our database, but you can add a new scientist in the 'Add section' in the main menu." << endl;
            searching();
        }
    }
    else if (searchChoice == "2")
    {
        char gendersearch;

        cout << "Enter a gender you want to search for: (M/F)";
        cin >> gendersearch;

        if(gendersearch == 'm')
            {
                 gendersearch = 'M';
            }
        else if (gendersearch == 'f')
            {
                 gendersearch = 'F';
            }

        for(int i = 0; i < list.personsSize();++i)
        {
            if(gendersearch == list.getGender(i))
            {
                gendersearch = list.getGender(i);
                view(i);
            }
        }

        if(list.genderSearcher(gendersearch) == false)
        {
            cout << "Sorry that gender is not in our database, but you can add a new scientist in the 'Add section' in the main menu." << endl;
            searching();
        }
    }
    else if (searchChoice == "3")
    {
            int yearsearch;
            cout << "Enter a year you want to search for: ";
            cin >> yearsearch;

            for(int i = 0; i < list.personsSize();++i)
            {
                if(yearsearch == list.getBirth(i))
                {
                    yearsearch = list.getBirth(i);
                    view(i);
                }
            }

            if(list.yearSearcher(yearsearch) == false)
            {
                cout << "Sorry that year is not in our database, but you can add a new scientist in the 'Add section' in the main menu." << endl;
                searching();
            }
    }
    else if (searchChoice == "4")
    {
        int ageSearch;
        cout << "Enter a age you want to search for: ";
        cin >> ageSearch;

        for(int i = 0; i < list.personsSize();++i)
        {
            if(ageSearch == list.getAge(i))
            {
                ageSearch = list.getAge(i);
                view(i);
            }
        }

        if(list.ageSearcher(ageSearch) == false)
        {
            cout << "Sorry that age is not in our database, but you can add a new scientist in the 'Add section' in the main menu." << endl;
            searching();
        }
    }
    else if (searchChoice == "5")
    {
        mainMenu();
    }
    else
    {
        cout << "Error reading input. Please enter a number between 1- 3." << endl;
        search();
    }
}
void ClassUI::remove()
{
    string name;
    cout << "--------------------------------------------------------------" << endl;
    cout << "Enter the full name of the scientist that you want to remove: ";
    cin.ignore();
    std::getline(std::cin,name);

    if (list.removePersonFound(name) == true)
    {
        char validateRemove;
        cout << "Scientist found!" << endl;
        cout << "Are you sure you want to remove this scientist? (y/n): ";
        cin >> validateRemove;

        if(validateRemove == 'y' || validateRemove == 'Y')
        {
            if(list.removePerson(name) == true)
            {
                cout << "Scientist removed!" << endl;
            }
            else
            {
                cout << "Scientist not removed!" << endl;
            }
        }
        else
        {
            cout << "Scientist not removed!" << endl;
        }
    }
    else
    {
        cout << "Serson not found!" << endl;
    }

}
void ClassUI::save()
{
    list.saveFile();
    cout << "Database saved." << endl;
}
void ClassUI::yo()
{
    cout << "--------------------------------------------------------------" << endl;
    cout << endl;
    cout << "`8.`8888.      ,8'     ,o888888o.     " << endl;
    cout << " `8.`8888.    ,8'   . 8888     `88.   " << endl;
    cout << "  `8.`8888.  ,8'   ,8 8888       `8b  " << endl;
    cout << "   `8.`8888.,8'    88 8888        `8b " << endl;
    cout << "    `8.`88888'     88 8888         88 " << endl;
    cout << "     `8. 8888      88 8888         88 " << endl;
    cout << "      `8 8888      88 8888        ,8P " << endl;
    cout << "       8 8888      `8 8888       ,8P  " << endl;
    cout << "       8 8888       ` 8888     ,88'   " << endl;
    cout << "       8 8888          `8888888P'     " << endl;
    cout << endl;
}
string ClassUI::getQuotes()
{
    string quotes[5] = {"\"A good programmer is someone who always looks both ways before crossing a one-way street.\" (Doug Linder)",
                        "\"Programming is like sex. One mistake and you have to support it for the rest of your life.\" (Michael Sinz)",
                        "\"Walking on water and developing software from a specification are easy if both are frozen.\" (Edward V Berard)",
                        "\"One man's crappy software is another man's full time job.\" (Jessica Gaston)",
                        "\"A C program is like a fast dance on a newly waxed dance floor by people carrying razors.\" (Waldi Ravens)"
                       };
    int v1 = 0;
    srand (time(NULL));
    v1 = rand() % 5;
    return quotes[v1];
}
void ClassUI::sorting()
{
    string sortcho;
    cout << "Enter a sort command:" << endl;
    cout << "--------------------------------------------------------------" << endl;
    cout << " (1) - Sort by alphabetical order." << endl;
    cout << " (2) - Sort by chronological order." << endl;
    cout << " (3) - Sort by gender." << endl;
    cout << " (4) - Sort by age." << endl;
    cout << " (5) - Return to main menu." << endl;
    cout << "Enter your command (1 - 5): ";
    cin >> sortcho;
    cout << endl;

    if(sortcho == "1")
    {
        list.sortNames();
         viewAll();
    }
    else if(sortcho == "2")
    {
        list.sortBirth();
         viewAll();
    }
    else if(sortcho == "3")
    {
        list.sortGender();
        viewAll();
    }
    else if(sortcho == "4")
    {
        list.sortAge();
        viewAll();
    }
    else if(sortcho == "5")
    {
        mainMenu();
    }
    else
    {
        cout << "That is not a valid command! Try again." << endl;
        sorting();
    }
}
void ClassUI::editPerson()
{
    string name;
    cout << "Enter the full name of the Scientist that you want to edit: ";
    cin.ignore();
    std::getline(std::cin,name);
    if(list.removePersonFound(name))
    {
        list.removePerson(name);
        addPerson();
    }
    else
    {
        cout << "Scientist not found!" << endl;
    }
}
/*
void ClassUI::clearTheScreen() //A function that we wanted to use but had platform issues following it's use.
{
    #if defined(__linux__) || defined(__unix__) || defined(__APPLE__)
        system("clear");
    #endif

    #if defined(_WIN32) || defined(_WIN64)
        system("cls");
    #endif
}
*/
/*
void ClassUI::editComputer()
{
    string cmpname;
    cout << "Enter the full name of the computer that you want to edit: ";
    cin.ignore();
    std::getline(std::cin,cmpname);
    if(list.removePersonFound(cmpname))
    {
        list.removePerson(cmpname);
        addPerson();
    }
    else
    {
        cout << "Computer not found!" << endl;
    }
}
*/
<|endoftext|>


<commit_before>#include "stdafx.h"
#include "sysinv.h"
#include "smbios.h"

LPTSTR CHASSIS_TYPE_STRINGS[] = {
	_T("Unknown"),					// 0x00 Invalid
	_T("Other"),					// 0x01
	_T("Unknown"),					// 0x02
	_T("Desktop"),					// 0x03
	_T("Low Profile Desktop"),		// 0x04
	_T("Pizza Box"),				// 0x05
	_T("Mini Tower"),				// 0x06
	_T("Tower"),					// 0x07
	_T("Portable"),					// 0x08
	_T("Laptop"),					// 0x09
	_T("Notebook"),					// 0x0A
	_T("Hand Held"),				// 0x0B
	_T("Docking Station"),			// 0x0C
	_T("All in One"),				// 0x0D
	_T("Sub Notebook"),				// 0x0E
	_T("Space-saving"),				// 0x0F
	_T("Lunch Box"),				// 0x10
	_T("Main Server Chassis"),		// 0x11
	_T("Expansion Chassis"),		// 0x12
	_T("Sub Chassis"),				// 0x13
	_T("Bus Expansion Chassis"),	// 0x14
	_T("Peripheral Chassis"),		// 0x15
	_T("RAID Chassis"),				// 0x16
	_T("Rack Mount Chassis"),		// 0x17
	_T("Sealed-case PC"),			// 0x18
	_T("Multi-system Chassis"),		// 0x19
	_T("Compact PCI"),				// 0x1A
	_T("Advanced TCA")				// 0x1B
	_T("Blade")						// 0x1C
	_T("Blade Enclosure")			// 0x1D
};

PNODE EnumChassis()
{
	PNODE parentNode = node_alloc(_T("Chassis"), 0);
	PNODE node = NULL;

	PRAW_SMBIOS_DATA smbios = GetSmbiosData();
	PSMBIOS_STRUCT_HEADER header = NULL;
	PBYTE cursor = NULL;

	LPTSTR unicode = NULL;
	TCHAR buffer[MAX_PATH + 1];

	while (NULL != (header = GetNextStructureOfType(header, SMB_TABLE_CHASSIS))) {
		cursor = (PBYTE)header;

		// v2.0+
		if (2 <= smbios->SMBIOSMajorVersion) {
			node = node_append_new(parentNode, _T("Chassis"), 0);

			// 0x04 Manufacturer
			unicode = GetSmbiosString(header, *(cursor + 0x04));
			node_att_set(node, _T("Manufacturer"), unicode, 0);
			LocalFree(unicode);

			// 0x05 Chassis Type
			node_att_set(node, _T("Type"), SAFE_INDEX(CHASSIS_TYPE_STRINGS, *(cursor + 0x05)), 0);

			// 0x06 Version String
			unicode = GetSmbiosString(header, *(cursor + 0x06));
			node_att_set(node, _T("Version"), unicode, 0);
			LocalFree(unicode);

			// 0x07 Serial Number
			unicode = GetSmbiosString(header, *(cursor + 0x06));
			node_att_set(node, _T("SerialNumber"), unicode, 0);
			LocalFree(unicode);

			// 0x08 Asset Tag
			unicode = GetSmbiosString(header, *(cursor + 0x08));
			node_att_set(node, _T("AssetTag"), unicode, 0);
			LocalFree(unicode);
		}
	}

	return parentNode;
}<commit_msg>Improved SMBIOS v2.8 support for Chassis (type 3)<commit_after>#include "stdafx.h"
#include "sysinv.h"
#include "smbios.h"

// 7.4.1 System Enclosure or Chassis Types
LPTSTR CHASSIS_TYPES[] = {
	_T("Unknown"),					// 0x00 Invalid
	_T("Other"),					// 0x01
	_T("Unknown"),					// 0x02
	_T("Desktop"),					// 0x03
	_T("Low Profile Desktop"),		// 0x04
	_T("Pizza Box"),				// 0x05
	_T("Mini Tower"),				// 0x06
	_T("Tower"),					// 0x07
	_T("Portable"),					// 0x08
	_T("Laptop"),					// 0x09
	_T("Notebook"),					// 0x0A
	_T("Hand Held"),				// 0x0B
	_T("Docking Station"),			// 0x0C
	_T("All in One"),				// 0x0D
	_T("Sub Notebook"),				// 0x0E
	_T("Space-saving"),				// 0x0F
	_T("Lunch Box"),				// 0x10
	_T("Main Server Chassis"),		// 0x11
	_T("Expansion Chassis"),		// 0x12
	_T("Sub Chassis"),				// 0x13
	_T("Bus Expansion Chassis"),	// 0x14
	_T("Peripheral Chassis"),		// 0x15
	_T("RAID Chassis"),				// 0x16
	_T("Rack Mount Chassis"),		// 0x17
	_T("Sealed-case PC"),			// 0x18
	_T("Multi-system Chassis"),		// 0x19
	_T("Compact PCI"),				// 0x1A
	_T("Advanced TCA")				// 0x1B
	_T("Blade")						// 0x1C
	_T("Blade Enclosure")			// 0x1D
};

// 7.4.2 System Enclosure or Chassis States
LPCTSTR CHASSIS_STATES[] = {
	_T("Unknown"),							// 0x00 Invalid
	_T("Other"),							// 0x01 Other
	_T("Unknown"),							// 0x02 Unknown
	_T("Safe"),								// 0x03 Safe
	_T("Warning"),							// 0x04 Warning
	_T("Critical"),							// 0x05 Critical
	_T("Non-recoverable")					// 0x06 Non-recoverable
};

// 7.4.3 System Enclosure or Chassis Security Status
LPCTSTR CHASSIS_SECURITY_STATUS[] = {
	_T("Unknown"),							// 0x00 Invalid
	_T("Other"),							// 0x01 Other
	_T("Unknown"),							// 0x02 Unknown
	_T("None"),								// 0x03 None
	_T("External interface locked out"),	// 0x04 External interface locked out
	_T("External interface enabled")		// 0x05 External interface enabled
};

// 7.4 System Enclosure or Chassis (Type 3)
PNODE EnumChassis()
{
	PNODE parentNode = node_alloc(_T("Chassis"), 0);
	PNODE node = NULL;

	PRAW_SMBIOS_DATA smbios = GetSmbiosData();
	PSMBIOS_STRUCT_HEADER header = NULL;

	LPTSTR unicode = NULL;
	TCHAR buffer[MAX_PATH + 1];

	while (NULL != (header = GetNextStructureOfType(header, SMB_TABLE_CHASSIS))) {
		// v2.0+
		if (2 <= smbios->SMBIOSMajorVersion) {
			node = node_append_new(parentNode, _T("Chassis"), 0);

			// 0x04 Manufacturer
			unicode = GetSmbiosString(header, BYTE_AT_OFFSET(header, 0x04));
			node_att_set(node, _T("Manufacturer"), unicode, 0);
			LocalFree(unicode);

			// 0x05 Chassis Type
			node_att_set(node, _T("Type"), SAFE_INDEX(CHASSIS_TYPES, BYTE_AT_OFFSET(header, 0x05)), 0);

			// 0x06 Version String
			unicode = GetSmbiosString(header, BYTE_AT_OFFSET(header, 0x06));
			node_att_set(node, _T("Version"), unicode, 0);
			LocalFree(unicode);

			// 0x07 Serial Number
			unicode = GetSmbiosString(header, BYTE_AT_OFFSET(header, 0x06));
			node_att_set(node, _T("SerialNumber"), unicode, 0);
			LocalFree(unicode);

			// 0x08 Asset Tag
			unicode = GetSmbiosString(header, BYTE_AT_OFFSET(header, 0x08));
			node_att_set(node, _T("AssetTag"), unicode, 0);
			LocalFree(unicode);

			// v2.1+
			if (2 < smbios->SMBIOSMajorVersion || (2 == smbios->SMBIOSMajorVersion && 1 <= smbios->SMBIOSMinorVersion)) {
				// 0x09 Boot-up state
				node_att_set(node, _T("BootupState"), SAFE_INDEX(CHASSIS_STATES, BYTE_AT_OFFSET(header, 0x09)), 0);

				// 0x0A Power supply state
				node_att_set(node, _T("PowerSupplyState"), SAFE_INDEX(CHASSIS_STATES, BYTE_AT_OFFSET(header, 0x0A)), 0);

				// 0x0B Thermal State
				node_att_set(node, _T("ThermalState"), SAFE_INDEX(CHASSIS_STATES, BYTE_AT_OFFSET(header, 0x0B)), 0);

				// 0x0C Security State
				node_att_set(node, _T("SecurityState"), SAFE_INDEX(CHASSIS_SECURITY_STATUS, BYTE_AT_OFFSET(header, 0x0C)), 0);
			}

			// v2.3+
			if (2 < smbios->SMBIOSMajorVersion || (2 == smbios->SMBIOSMajorVersion && 3 <= smbios->SMBIOSMinorVersion)) {
				// 0x0D OEM Defined
				swprintf(buffer, _T("0x%X"), DWORD_AT_OFFSET(header, 0x0D));
				node_att_set(node, _T("OemInfo"), buffer, 0);

				// 0x11 Height (U|1.75"|4.445cm)
				if (0 != BYTE_AT_OFFSET(header, 0x11)) {
					swprintf(buffer, _T("%u"), BYTE_AT_OFFSET(header, 0x11));
					node_att_set(node, _T("HeightU"), buffer, 0);
				}

				// 0x12 Number of power cords
				if (0 != BYTE_AT_OFFSET(header, 0x12)) {
					swprintf(buffer, _T("%u"), BYTE_AT_OFFSET(header, 0x12));
					node_att_set(node, _T("PowerCordCount"), buffer, 0);
				}
			}

			// v2.7+
			if (2 < smbios->SMBIOSMajorVersion || (2 == smbios->SMBIOSMajorVersion && 7 <= smbios->SMBIOSMinorVersion)) {
				// 0x15 + n*m SKU Number
				unicode = GetSmbiosString(header, BYTE_AT_OFFSET(header, 0x15 + BYTE_AT_OFFSET(header, 0x15)));
				node_att_set(node, _T("SkuNumber"), unicode, 0);
				LocalFree(unicode);
			}
		}
	}

	return parentNode;
}<|endoftext|>


<commit_before>#include <chrono>
#include <iostream>
#include <numeric>
#include <vector>

#include "tensorflow/cc/ops/array_ops.h"
#include "tensorflow/cc/ops/const_op.h"
#include "tensorflow/cc/ops/image_ops.h"
#include "tensorflow/cc/saved_model/loader.h"
#include "tensorflow/compiler/tf2tensorrt/trt_convert_api.h"
#include "tensorflow/core/framework/graph.pb.h"
#include "tensorflow/core/framework/tensor.h"
#include "tensorflow/core/graph/default_device.h"
#include "tensorflow/core/platform/init_main.h"
#include "tensorflow/core/platform/logging.h"
#include "tensorflow/core/platform/types.h"
#include "tensorflow/core/public/session.h"
#include "tensorflow/core/util/command_line_flags.h"

using tensorflow::Flag;
using tensorflow::Status;
using tensorflow::string;
using tensorflow::Tensor;

#define TFTRT_ENSURE_OK(x)                                                 \
  do {                                                                     \
    Status s = x;                                                          \
    if (!s.ok()) {                                                         \
      std::cerr << __FILE__ << ":" << __LINE__ << " " << s.error_message() \
                << std::endl;                                              \
      return 1;                                                            \
    }                                                                      \
  } while (0)

// Get the name of the GPU.
const string GetDeviceName(std::unique_ptr<tensorflow::Session>& session) {
  string device_name = "";
  std::vector<tensorflow::DeviceAttributes> devices;
  Status status = session->ListDevices(&devices);
  if (!status.ok()) {
    return device_name;
  }
  for (const auto& d : devices) {
    if (d.device_type() == "GPU" || d.device_type() == "gpu") {
      device_name = d.name();
    }
  }
  return device_name;
}

// Move from the host to the device with `device_name`.
Status MoveToDevice(const string& device_name, Tensor& tensor_host,
                    Tensor* tensor_device) {
  // Create identity graph
  tensorflow::Scope root = tensorflow::Scope::NewRootScope();
  auto x = tensorflow::ops::Placeholder(root, tensor_host.dtype());
  auto y = tensorflow::ops::Identity(root, x);

  tensorflow::GraphDef graphDef;
  TF_RETURN_IF_ERROR(root.ToGraphDef(&graphDef));

  // Create session with identity graph
  std::unique_ptr<tensorflow::Session> session(
      tensorflow::NewSession(tensorflow::SessionOptions()));
  TF_RETURN_IF_ERROR(session->Create(graphDef));

  // Configure to return output on device
  tensorflow::Session::CallableHandle handle;
  tensorflow::CallableOptions opts;
  opts.add_feed("Placeholder:0");
  opts.add_fetch("Identity:0");
  opts.mutable_fetch_devices()->insert({"Identity:0", device_name});
  opts.set_fetch_skip_sync(true);
  TF_RETURN_IF_ERROR(session->MakeCallable(opts, &handle));

  // Execute graph
  std::vector<Tensor> tensors_device;
  Status status =
      session->RunCallable(handle, {tensor_host}, &tensors_device, nullptr);
  *tensor_device = tensors_device.front();
  session->ReleaseCallable(handle);
  return status;
}

// Returns info for nodes listed in the signature definition.
std::vector<tensorflow::TensorInfo> GetNodeInfo(
    const google::protobuf::Map<string, tensorflow::TensorInfo>& signature) {
  std::vector<tensorflow::TensorInfo> info;
  for (const auto& item : signature) {
    info.push_back(item.second);
  }
  return info;
}

// Load the `SavedModel` located at `model_dir`.
Status LoadModel(const string& model_dir, const string& signature_key,
                 tensorflow::SavedModelBundle* bundle,
                 std::vector<tensorflow::TensorInfo>* input_info,
                 std::vector<tensorflow::TensorInfo>* output_info) {
  tensorflow::RunOptions run_options;
  tensorflow::SessionOptions sess_options;
  sess_options.config.mutable_gpu_options()->force_gpu_compatible();
  TF_RETURN_IF_ERROR(tensorflow::LoadSavedModel(sess_options, run_options,
                                                model_dir, {"serve"}, bundle));

  // Get input and output names
  auto signature_map = bundle->GetSignatures();
  const tensorflow::SignatureDef& signature = signature_map[signature_key];
  *input_info = GetNodeInfo(signature.inputs());
  *output_info = GetNodeInfo(signature.outputs());

  return Status::OK();
}

// Create arbitrary inputs matching `input_info` and load them on the device.
Status SetupInputs(const string& device_name, int32_t batch_size,
                   std::vector<tensorflow::TensorInfo>& input_info,
                   std::vector<Tensor>* inputs) {
  std::vector<Tensor> inputs_device;
  for (const auto& info : input_info) {
    auto shape = info.tensor_shape();
    shape.mutable_dim(0)->set_size(batch_size);
    Tensor input_host(info.dtype(), shape);
    Tensor input_device;
    TF_RETURN_IF_ERROR(MoveToDevice(device_name, input_host, &input_device));
    inputs_device.push_back(input_device);
  }
  *inputs = inputs_device;
  return Status::OK();
}

// Configure a `CallableHandle` that feeds from and fetches to a device.
Status SetupCallable(std::unique_ptr<tensorflow::Session>& session,
                     std::vector<tensorflow::TensorInfo>& input_info,
                     std::vector<tensorflow::TensorInfo>& output_info,
                     const string& device_name,
                     tensorflow::Session::CallableHandle* handle) {
  tensorflow::CallableOptions opts;
  for (const auto& info : input_info) {
    const string& name = info.name();
    opts.add_feed(name);
    opts.mutable_feed_devices()->insert({name, device_name});
  }
  for (const auto& info : output_info) {
    const string& name = info.name();
    opts.add_fetch(name);
    opts.mutable_fetch_devices()->insert({name, device_name});
  }
  opts.set_fetch_skip_sync(true);
  return session->MakeCallable(opts, handle);
}

int main(int argc, char* argv[]) {
  // Parse arguments
  string model_path = "/path/to/model/";
  string signature_key = "serving_default";
  int32_t batch_size = 64;
  int32_t warmup_iters = 50;
  int32_t eval_iters = 1000;
  std::vector<Flag> flag_list = {
      Flag("model_path", &model_path, "graph to be executed"),
      Flag("signature_key", &signature_key, "the serving signature to use"),
      Flag("batch_size", &batch_size, "batch size to use for inference"),
      Flag("warmup_iters", &warmup_iters, "number of warmup iterations to run"),
      Flag("eval_iters", &eval_iters, "number of timed iterations to run"),
  };
  string usage = tensorflow::Flags::Usage(argv[0], flag_list);
  const bool parse_result = tensorflow::Flags::Parse(&argc, argv, flag_list);
  if (!parse_result) {
    LOG(ERROR) << usage;
    return -1;
  }

  // We need to call this to set up global state for TensorFlow.
  tensorflow::port::InitMain(argv[0], &argc, &argv);
  if (argc > 1) {
    LOG(ERROR) << "Unknown argument " << argv[1] << "\n" << usage;
    return -1;
  }

  // Setup session
  tensorflow::SavedModelBundle bundle;
  std::vector<tensorflow::TensorInfo> input_info;
  std::vector<tensorflow::TensorInfo> output_info;
  TFTRT_ENSURE_OK(
      LoadModel(model_path, signature_key, &bundle, &input_info, &output_info));

  // Create inputs and move to device
  const string device_name = GetDeviceName(bundle.session);
  std::vector<Tensor> inputs_device;
  TFTRT_ENSURE_OK(
      SetupInputs(device_name, batch_size, input_info, &inputs_device));

  // Configure to feed and fetch from device
  tensorflow::Session::CallableHandle handle;
  TFTRT_ENSURE_OK(SetupCallable(bundle.session, input_info, output_info,
                                device_name, &handle));

  // Run benchmarking
  std::vector<Tensor> outputs;
  std::vector<double> infer_time;
  std::chrono::steady_clock::time_point eval_start_time;
  std::chrono::steady_clock::time_point start_time;
  std::chrono::steady_clock::time_point end_time;
  for (int i = 0; i < warmup_iters + eval_iters; i++) {
    if (i == warmup_iters) {
      LOG(INFO) << "Warmup done";
      eval_start_time = std::chrono::steady_clock::now();
    }

    start_time = std::chrono::steady_clock::now();
    Status status =
        bundle.session->RunCallable(handle, inputs_device, &outputs, nullptr);
    end_time = std::chrono::steady_clock::now();

    TFTRT_ENSURE_OK(status);
    double duration = (end_time - start_time).count() / 1e6;
    infer_time.push_back(duration);
  }
  TFTRT_ENSURE_OK(bundle.session->ReleaseCallable(handle));

  // Print results
  std::sort(infer_time.begin() + warmup_iters, infer_time.end());
  double total_compute_time =
      std::accumulate(infer_time.begin() + warmup_iters, infer_time.end(), 0.0);
  double total_wall_time = (end_time - eval_start_time).count() / 1e6;
  int32_t m = warmup_iters + eval_iters / 2;
  LOG(INFO) << "Total wall time (s): " << total_wall_time / 1e3;
  LOG(INFO) << "Total GPU compute time (s): " << total_compute_time / 1e3;
  LOG(INFO) << "Mean GPU compute time (ms): " << total_compute_time / eval_iters;
  LOG(INFO) << "Median GPU compute time (ms): " << (eval_iters % 2 ? infer_time[m]
                                                                   : (infer_time[m - 1] + infer_time[m]) / 2);
  // Note: Throughput using GPU inference time, rather than wall time
  LOG(INFO) << "Throughput (samples/s): " << 1e3 * eval_iters * batch_size / total_compute_time;
  LOG(INFO) << "First inference latency (ms): " << infer_time.front();

  return 0;
}<commit_msg>Add TODOs for remaining requested changes<commit_after>#include <chrono>
#include <iostream>
#include <numeric>
#include <vector>

#include "tensorflow/cc/ops/array_ops.h"
#include "tensorflow/cc/ops/const_op.h"
#include "tensorflow/cc/ops/image_ops.h"
#include "tensorflow/cc/saved_model/loader.h"
#include "tensorflow/compiler/tf2tensorrt/trt_convert_api.h"
#include "tensorflow/core/framework/graph.pb.h"
#include "tensorflow/core/framework/tensor.h"
#include "tensorflow/core/graph/default_device.h"
#include "tensorflow/core/platform/init_main.h"
#include "tensorflow/core/platform/logging.h"
#include "tensorflow/core/platform/types.h"
#include "tensorflow/core/public/session.h"
#include "tensorflow/core/util/command_line_flags.h"

using tensorflow::Flag;
using tensorflow::Status;
using tensorflow::string;
using tensorflow::Tensor;

#define TFTRT_ENSURE_OK(x)                                                 \
  do {                                                                     \
    Status s = x;                                                          \
    if (!s.ok()) {                                                         \
      std::cerr << __FILE__ << ":" << __LINE__ << " " << s.error_message() \
                << std::endl;                                              \
      return 1;                                                            \
    }                                                                      \
  } while (0)

// Get the name of the GPU.
const string GetDeviceName(std::unique_ptr<tensorflow::Session>& session) {
  string device_name = "";
  std::vector<tensorflow::DeviceAttributes> devices;
  Status status = session->ListDevices(&devices);
  if (!status.ok()) {
    return device_name;
  }
  for (const auto& d : devices) {
    if (d.device_type() == "GPU" || d.device_type() == "gpu") {
      device_name = d.name();
    }
  }
  return device_name;
}

// Move from the host to the device with `device_name`.
Status MoveToDevice(const string& device_name, Tensor& tensor_host,
                    Tensor* tensor_device) {
  // Create identity graph
  tensorflow::Scope root = tensorflow::Scope::NewRootScope();
  auto x = tensorflow::ops::Placeholder(root, tensor_host.dtype());
  auto y = tensorflow::ops::Identity(root, x);

  tensorflow::GraphDef graphDef;
  TF_RETURN_IF_ERROR(root.ToGraphDef(&graphDef));

  // Create session with identity graph
  std::unique_ptr<tensorflow::Session> session(
      tensorflow::NewSession(tensorflow::SessionOptions()));
  TF_RETURN_IF_ERROR(session->Create(graphDef));

  // Configure to return output on device
  tensorflow::Session::CallableHandle handle;
  tensorflow::CallableOptions opts;
  opts.add_feed("Placeholder:0");
  opts.add_fetch("Identity:0");
  opts.mutable_fetch_devices()->insert({"Identity:0", device_name});
  opts.set_fetch_skip_sync(true);
  TF_RETURN_IF_ERROR(session->MakeCallable(opts, &handle));

  // Execute graph
  std::vector<Tensor> tensors_device;
  Status status =
      session->RunCallable(handle, {tensor_host}, &tensors_device, nullptr);
  *tensor_device = tensors_device.front();
  session->ReleaseCallable(handle);
  return status;
}

// Returns info for nodes listed in the signature definition.
std::vector<tensorflow::TensorInfo> GetNodeInfo(
    const google::protobuf::Map<string, tensorflow::TensorInfo>& signature) {
  std::vector<tensorflow::TensorInfo> info;
  for (const auto& item : signature) {
    info.push_back(item.second);
  }
  return info;
}

// Load the `SavedModel` located at `model_dir`.
Status LoadModel(const string& model_dir, const string& signature_key,
                 tensorflow::SavedModelBundle* bundle,
                 std::vector<tensorflow::TensorInfo>* input_info,
                 std::vector<tensorflow::TensorInfo>* output_info) {
  tensorflow::RunOptions run_options;
  tensorflow::SessionOptions sess_options;
  sess_options.config.mutable_gpu_options()->force_gpu_compatible();
  TF_RETURN_IF_ERROR(tensorflow::LoadSavedModel(sess_options, run_options,
                                                model_dir, {"serve"}, bundle));

  // Get input and output names
  auto signature_map = bundle->GetSignatures();
  const tensorflow::SignatureDef& signature = signature_map[signature_key];
  *input_info = GetNodeInfo(signature.inputs());
  *output_info = GetNodeInfo(signature.outputs());

  return Status::OK();
}

// Create arbitrary inputs matching `input_info` and load them on the device.
Status SetupInputs(const string& device_name, int32_t batch_size,
                   std::vector<tensorflow::TensorInfo>& input_info,
                   std::vector<Tensor>* inputs) {
  std::vector<Tensor> inputs_device;
  for (const auto& info : input_info) {
    auto shape = info.tensor_shape();
    shape.mutable_dim(0)->set_size(batch_size);
    Tensor input_host(info.dtype(), shape);
    Tensor input_device;
    TF_RETURN_IF_ERROR(MoveToDevice(device_name, input_host, &input_device));
    inputs_device.push_back(input_device);
  }
  *inputs = inputs_device;
  return Status::OK();
}

// Configure a `CallableHandle` that feeds from and fetches to a device.
Status SetupCallable(std::unique_ptr<tensorflow::Session>& session,
                     std::vector<tensorflow::TensorInfo>& input_info,
                     std::vector<tensorflow::TensorInfo>& output_info,
                     const string& device_name,
                     tensorflow::Session::CallableHandle* handle) {
  tensorflow::CallableOptions opts;
  for (const auto& info : input_info) {
    const string& name = info.name();
    opts.add_feed(name);
    opts.mutable_feed_devices()->insert({name, device_name});
  }
  for (const auto& info : output_info) {
    const string& name = info.name();
    opts.add_fetch(name);
    opts.mutable_fetch_devices()->insert({name, device_name});
  }
  opts.set_fetch_skip_sync(true);
  return session->MakeCallable(opts, handle);
}

int main(int argc, char* argv[]) {
  // Parse arguments
  string model_path = "/path/to/model/";
  string signature_key = "serving_default";
  int32_t batch_size = 64;
  int32_t warmup_iters = 50;
  int32_t eval_iters = 1000;
  std::vector<Flag> flag_list = {
      Flag("model_path", &model_path, "graph to be executed"),
      Flag("signature_key", &signature_key, "the serving signature to use"),
      Flag("batch_size", &batch_size, "batch size to use for inference"),
      Flag("warmup_iters", &warmup_iters, "number of warmup iterations to run"),
      Flag("eval_iters", &eval_iters, "number of timed iterations to run"),
  };
  string usage = tensorflow::Flags::Usage(argv[0], flag_list);
  const bool parse_result = tensorflow::Flags::Parse(&argc, argv, flag_list);
  if (!parse_result) {
    LOG(ERROR) << usage;
    return -1;
  }

  // We need to call this to set up global state for TensorFlow.
  tensorflow::port::InitMain(argv[0], &argc, &argv);
  if (argc > 1) {
    LOG(ERROR) << "Unknown argument " << argv[1] << "\n" << usage;
    return -1;
  }

  // Setup session
  tensorflow::SavedModelBundle bundle;
  std::vector<tensorflow::TensorInfo> input_info;
  std::vector<tensorflow::TensorInfo> output_info;
  TFTRT_ENSURE_OK(
      LoadModel(model_path, signature_key, &bundle, &input_info, &output_info));

  // TODO: Convert model w/ TRT and add flag for this behavior

  // Create inputs and move to device
  // TODO: Measure H2D times over repeated calls and report metrics
  const string device_name = GetDeviceName(bundle.session);
  std::vector<Tensor> inputs_device;
  TFTRT_ENSURE_OK(
      SetupInputs(device_name, batch_size, input_info, &inputs_device));

  // Configure to feed and fetch from device
  tensorflow::Session::CallableHandle handle;
  TFTRT_ENSURE_OK(SetupCallable(bundle.session, input_info, output_info,
                                device_name, &handle));

  // Run benchmarking
  std::vector<Tensor> outputs;
  std::vector<double> infer_time;
  std::chrono::steady_clock::time_point eval_start_time;
  std::chrono::steady_clock::time_point start_time;
  std::chrono::steady_clock::time_point end_time;
  for (int i = 0; i < warmup_iters + eval_iters; i++) {
    if (i == warmup_iters) {
      LOG(INFO) << "Warmup done";
      eval_start_time = std::chrono::steady_clock::now();
    }

    start_time = std::chrono::steady_clock::now();
    Status status =
        bundle.session->RunCallable(handle, inputs_device, &outputs, nullptr);
    end_time = std::chrono::steady_clock::now();

    TFTRT_ENSURE_OK(status);
    double duration = (end_time - start_time).count() / 1e6;
    infer_time.push_back(duration);
  }
  TFTRT_ENSURE_OK(bundle.session->ReleaseCallable(handle));

  // Print results
  std::sort(infer_time.begin() + warmup_iters, infer_time.end());
  double total_compute_time =
      std::accumulate(infer_time.begin() + warmup_iters, infer_time.end(), 0.0);
  double total_wall_time = (end_time - eval_start_time).count() / 1e6;
  int32_t m = warmup_iters + eval_iters / 2;
  LOG(INFO) << "Total wall time (s): " << total_wall_time / 1e3;
  LOG(INFO) << "Total GPU compute time (s): " << total_compute_time / 1e3;
  LOG(INFO) << "Mean GPU compute time (ms): " << total_compute_time / eval_iters;
  LOG(INFO) << "Median GPU compute time (ms): " << (eval_iters % 2 ? infer_time[m]
                                                                   : (infer_time[m - 1] + infer_time[m]) / 2);
  // Note: Throughput using GPU inference time, rather than wall time
  LOG(INFO) << "Throughput (samples/s): " << 1e3 * eval_iters * batch_size / total_compute_time;
  LOG(INFO) << "First inference latency (ms): " << infer_time.front();

  return 0;
}<|endoftext|>


<commit_before>/**************************************************************************
 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
 *                                                                        *
 * Author: The ALICE Off-line Project.                                    *
 * Contributors are mentioned in the code where appropriate.              *
 *                                                                        *
 * Permission to use, copy, modify and distribute this software and its   *
 * documentation strictly for non-commercial purposes is hereby granted   *
 * without fee, provided that the above copyright notice appears in all   *
 * copies and that both the copyright notice and this permission notice   *
 * appear in the supporting documentation. The authors make no claims     *
 * about the suitability of this software for any purpose. It is          *
 * provided "as is" without express or implied warranty.                  *
 **************************************************************************/

/* $Id$ */
/////////////////////////////////////////////////////////////////////////
//                                                                     //
// Class for ITS RecPoint reconstruction                               //
//                                                                     //
////////////////////////////////////////////////////////////////////////

#include <TString.h>
#include "AliRun.h"
#include "AliRunLoader.h"
#include "AliITSDetTypeRec.h"
#include "AliITSLoader.h"
#include "AliITSreconstruction.h"
#include "AliITSgeom.h"

ClassImp(AliITSreconstruction)

//______________________________________________________________________
AliITSreconstruction::AliITSreconstruction():
 fInit(kFALSE),
 fEnt(0),
 fEnt0(0),
 fDetTypeRec(0x0),
 fDfArp(kFALSE),
 fITSgeom(0x0),
 fLoader(0x0),
 fRunLoader(0x0)
{
    // Default constructor.
    // Inputs:
    //  none.
    // Outputs:
    //   none.
    // Return:
    //    A zero-ed constructed AliITSreconstruction class.
    fDet[0] = fDet[1] = fDet[2] = kTRUE;
}
//______________________________________________________________________

AliITSreconstruction::AliITSreconstruction(AliRunLoader *rl):
 fInit(kFALSE),
 fEnt(0),
 fEnt0(0),
 fDetTypeRec(0x0),
 fDfArp(kFALSE),
 fITSgeom(0x0),
 fLoader(0x0),
 fRunLoader(rl)
{
  fDet[0] = fDet[1] = fDet[2] = kTRUE;
}
//______________________________________________________________________
AliITSreconstruction::AliITSreconstruction(const char* filename):
 fInit(kFALSE),
 fEnt(0),
 fEnt0(0),
 fDetTypeRec(0x0),
 fDfArp(kFALSE),
 fITSgeom(0x0),
 fLoader(0x0),
 fRunLoader(0x0)
{
    // Standard constructor.
    // Inputs:
    //  const char* filename    filename containing the digits to be
    //                          reconstructed. If filename = 0 (nil)
    //                          then no file is opened but a file is
    //                          assumed to already be opened. This
    //                          already opened file will be used.
    // Outputs:
    //   none.
    // Return:
    //    A standardly constructed AliITSreconstruction class.

    fDet[0] = fDet[1] = fDet[2] = kTRUE;

    fRunLoader = AliRunLoader::Open(filename);
    if (fRunLoader == 0x0)
     {
       Error("AliITSreconstruction","Can not load the session",filename);
       return;
     }

}

//______________________________________________________________________
AliITSreconstruction::AliITSreconstruction(const AliITSreconstruction &rec):TTask(rec),
fInit(rec.fInit),
fEnt(rec.fEnt),
fEnt0(rec.fEnt0),
fDetTypeRec(rec.fDetTypeRec),
fDfArp(rec.fDfArp),
fITSgeom(rec.fITSgeom),
fLoader(rec.fLoader),
fRunLoader(rec.fRunLoader)
{
    // Copy constructor.

}

//______________________________________________________________________
AliITSreconstruction& AliITSreconstruction::operator=(const AliITSreconstruction& source){
    // Assignment operator.
  this->~AliITSreconstruction();
  new(this) AliITSreconstruction(source);
  return *this;

}

//______________________________________________________________________
AliITSreconstruction::~AliITSreconstruction(){
    //    A destroyed AliITSreconstruction class.

    //fITS      = 0;
    delete fRunLoader;

}
//______________________________________________________________________
Bool_t AliITSreconstruction::Init(){
    // Class Initilizer.
    // Inputs:
    //  none.
    // Outputs:
    //   none.
    // Return:
    //    kTRUE if no errors initilizing this class occurse else kFALSE
    Info("Init","");
    if (fRunLoader == 0x0)
     {
       Error("Init","Run Loader is NULL");
       return kFALSE;
     }
    //  fRunLoader->LoadgAlice();
    //   fRunLoader->LoadHeader();

    fLoader = (AliITSLoader*) fRunLoader->GetLoader("ITSLoader");
    if(!fLoader) {
      Error("Init","ITS loader not found");
      fInit = kFALSE;
    }

    // Now ready to init.

    //fRunLoader->CdGAFile();
    fITSgeom = fLoader->GetITSgeom();

    fDetTypeRec = new AliITSDetTypeRec();
    fDetTypeRec->SetITSgeom(fITSgeom);
    fDetTypeRec->SetDefaults();
    fDet[0] = fDet[1] = fDet[2] = kTRUE;
    fEnt0 = 0;

    //fEnt  = gAlice->GetEventsPerRun();
    fEnt = Int_t(fRunLoader->GetNumberOfEvents());

    fLoader->LoadDigits("read");
    fLoader->LoadRecPoints("recreate");
    if (fLoader->TreeR() == 0x0) fLoader->MakeTree("R");

    fDetTypeRec->SetTreeAddressD(fLoader->TreeD());
    fDetTypeRec->MakeBranchR(fLoader->TreeR());
    fDetTypeRec->SetTreeAddressR(fLoader->TreeR());

    fInit = InitRec();

    Info("Init","  Done\n\n\n");

    return fInit;
}
//______________________________________________________________________
Bool_t AliITSreconstruction::InitRec(){
    // Sets up Reconstruction part of AliITSDetType..
    // Inputs:
    //      none.
    // Outputs:
    //      none.
    // Return:
    //      none.

  fDetTypeRec->SetDefaultClusterFindersV2();
  Info("InitRec","    Done\n");
  return kTRUE;
}
//______________________________________________________________________
void AliITSreconstruction::Exec(const Option_t *opt){
    // Main reconstruction function.
    // Inputs:
    //      Option_t * opt   list of subdetector to digitize. =0 all.
    // Outputs:
    //      none.
    // Return:
    //      none.
    Option_t *lopt;
    Int_t evnt;

    if(strstr(opt,"All")||strstr(opt,"ALL")||strstr(opt,"ITS")||opt==0){
      fDet[0] = fDet[1] = fDet[2] = kTRUE;
      lopt = "All";
    }else{
      fDet[0] = fDet[1] = fDet[2] = kFALSE;
      if(strstr(opt,"SPD")) fDet[kSPD] = kTRUE;
      if(strstr(opt,"SDD")) fDet[kSDD] = kTRUE;
      if(strstr(opt,"SSD")) fDet[kSSD] = kTRUE;
      if(fDet[kSPD] && fDet[kSDD] && fDet[kSSD]) lopt = "All";
      else lopt = opt;
    } // end if strstr(opt,...)

    if(!fInit){
      cout << "Initilization Failed, Can't run Exec." << endl;
      return;
    } // end if !fInit
    for(evnt=0;evnt<fEnt;evnt++)
     {
      Info("Exec","");
      Info("Exec","Processing Event %d",evnt);
      Info("Exec","");

      fRunLoader->GetEvent(evnt);
      if (fLoader->TreeR() == 0x0) fLoader->MakeTree("R");
      fDetTypeRec->MakeBranchR(0);
      fDetTypeRec->SetTreeAddressR(fLoader->TreeR());
      fDetTypeRec->SetTreeAddressD(fLoader->TreeD());
      fDetTypeRec->DigitsToRecPoints(fLoader->TreeD(),fLoader->TreeR(),0,lopt);
    } // end for evnt
}
//______________________________________________________________________
void AliITSreconstruction::SetOutputFile(TString filename){
  // Set a new file name for recpoints.
  // It must be called before Init()
  if(!fLoader)fLoader = (AliITSLoader*) fRunLoader->GetLoader("ITSLoader");
  if(fLoader){
    Info("SetOutputFile","name for rec points is %s",filename.Data());
    fLoader->SetRecPointsFileName(filename);
  }
  else {
    Error("SetOutputFile",
    "ITS loader not available. Not possible to set name: %s",filename.Data());
  }
}
<commit_msg>Do not get main runloader from gAlice<commit_after>/**************************************************************************
 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
 *                                                                        *
 * Author: The ALICE Off-line Project.                                    *
 * Contributors are mentioned in the code where appropriate.              *
 *                                                                        *
 * Permission to use, copy, modify and distribute this software and its   *
 * documentation strictly for non-commercial purposes is hereby granted   *
 * without fee, provided that the above copyright notice appears in all   *
 * copies and that both the copyright notice and this permission notice   *
 * appear in the supporting documentation. The authors make no claims     *
 * about the suitability of this software for any purpose. It is          *
 * provided "as is" without express or implied warranty.                  *
 **************************************************************************/

/* $Id$ */
/////////////////////////////////////////////////////////////////////////
//                                                                     //
// Class for ITS RecPoint reconstruction                               //
//                                                                     //
////////////////////////////////////////////////////////////////////////

#include <TString.h>
#include "AliRun.h"
#include "AliRunLoader.h"
#include "AliITSDetTypeRec.h"
#include "AliITSLoader.h"
#include "AliITSreconstruction.h"
#include "AliITSgeom.h"

ClassImp(AliITSreconstruction)

//______________________________________________________________________
AliITSreconstruction::AliITSreconstruction():
 fInit(kFALSE),
 fEnt(0),
 fEnt0(0),
 fDetTypeRec(0x0),
 fDfArp(kFALSE),
 fITSgeom(0x0),
 fLoader(0x0),
 fRunLoader(0x0)
{
    // Default constructor.
    // Inputs:
    //  none.
    // Outputs:
    //   none.
    // Return:
    //    A zero-ed constructed AliITSreconstruction class.
    fDet[0] = fDet[1] = fDet[2] = kTRUE;
}
//______________________________________________________________________

AliITSreconstruction::AliITSreconstruction(AliRunLoader *rl):
 fInit(kFALSE),
 fEnt(0),
 fEnt0(0),
 fDetTypeRec(0x0),
 fDfArp(kFALSE),
 fITSgeom(0x0),
 fLoader(0x0),
 fRunLoader(rl)
{
  fDet[0] = fDet[1] = fDet[2] = kTRUE;
}
//______________________________________________________________________
AliITSreconstruction::AliITSreconstruction(const char* filename):
 fInit(kFALSE),
 fEnt(0),
 fEnt0(0),
 fDetTypeRec(0x0),
 fDfArp(kFALSE),
 fITSgeom(0x0),
 fLoader(0x0),
 fRunLoader(0x0)
{
    // Standard constructor.
    // Inputs:
    //  const char* filename    filename containing the digits to be
    //                          reconstructed. If filename = 0 (nil)
    //                          then no file is opened but a file is
    //                          assumed to already be opened. This
    //                          already opened file will be used.
    // Outputs:
    //   none.
    // Return:
    //    A standardly constructed AliITSreconstruction class.

    fDet[0] = fDet[1] = fDet[2] = kTRUE;

    fRunLoader = AliRunLoader::Open(filename);
    if (fRunLoader == 0x0)
     {
       Error("AliITSreconstruction","Can not load the session",filename);
       return;
     }

}

//______________________________________________________________________
AliITSreconstruction::AliITSreconstruction(const AliITSreconstruction &rec):TTask(rec),
fInit(rec.fInit),
fEnt(rec.fEnt),
fEnt0(rec.fEnt0),
fDetTypeRec(rec.fDetTypeRec),
fDfArp(rec.fDfArp),
fITSgeom(rec.fITSgeom),
fLoader(rec.fLoader),
fRunLoader(rec.fRunLoader)
{
    // Copy constructor.

}

//______________________________________________________________________
AliITSreconstruction& AliITSreconstruction::operator=(const AliITSreconstruction& source){
    // Assignment operator.
  this->~AliITSreconstruction();
  new(this) AliITSreconstruction(source);
  return *this;

}

//______________________________________________________________________
AliITSreconstruction::~AliITSreconstruction(){
    //    A destroyed AliITSreconstruction class.

    //fITS      = 0;
    delete fRunLoader;

}
//______________________________________________________________________
Bool_t AliITSreconstruction::Init(){
    // Class Initilizer.
    // Inputs:
    //  none.
    // Outputs:
    //   none.
    // Return:
    //    kTRUE if no errors initilizing this class occurse else kFALSE
    Info("Init","");
    if (fRunLoader == 0x0)
     {
       Error("Init","Run Loader is NULL");
       return kFALSE;
     }
    //  fRunLoader->LoadgAlice();
    //   fRunLoader->LoadHeader();

    fLoader = (AliITSLoader*) fRunLoader->GetLoader("ITSLoader");
    if(!fLoader) {
      Error("Init","ITS loader not found");
      fInit = kFALSE;
    }

    // Now ready to init.

    //fRunLoader->CdGAFile();
    fITSgeom = fLoader->GetITSgeom();

    fDetTypeRec = new AliITSDetTypeRec();
    fDetTypeRec->SetITSgeom(fITSgeom);
    fDetTypeRec->SetDefaults();
    fDet[0] = fDet[1] = fDet[2] = kTRUE;
    fEnt0 = 0;

    fEnt = Int_t(fRunLoader->GetNumberOfEvents());

    fLoader->LoadDigits("read");
    fLoader->LoadRecPoints("recreate");
    if (fLoader->TreeR() == 0x0) fLoader->MakeTree("R");

    fDetTypeRec->SetTreeAddressD(fLoader->TreeD());
    fDetTypeRec->MakeBranchR(fLoader->TreeR());
    fDetTypeRec->SetTreeAddressR(fLoader->TreeR());

    fInit = InitRec();

    Info("Init","  Done\n\n\n");

    return fInit;
}
//______________________________________________________________________
Bool_t AliITSreconstruction::InitRec(){
    // Sets up Reconstruction part of AliITSDetType..
    // Inputs:
    //      none.
    // Outputs:
    //      none.
    // Return:
    //      none.

  fDetTypeRec->SetDefaultClusterFindersV2();
  Info("InitRec","    Done\n");
  return kTRUE;
}
//______________________________________________________________________
void AliITSreconstruction::Exec(const Option_t *opt){
    // Main reconstruction function.
    // Inputs:
    //      Option_t * opt   list of subdetector to digitize. =0 all.
    // Outputs:
    //      none.
    // Return:
    //      none.
    Option_t *lopt;
    Int_t evnt;

    if(strstr(opt,"All")||strstr(opt,"ALL")||strstr(opt,"ITS")||opt==0){
      fDet[0] = fDet[1] = fDet[2] = kTRUE;
      lopt = "All";
    }else{
      fDet[0] = fDet[1] = fDet[2] = kFALSE;
      if(strstr(opt,"SPD")) fDet[kSPD] = kTRUE;
      if(strstr(opt,"SDD")) fDet[kSDD] = kTRUE;
      if(strstr(opt,"SSD")) fDet[kSSD] = kTRUE;
      if(fDet[kSPD] && fDet[kSDD] && fDet[kSSD]) lopt = "All";
      else lopt = opt;
    } // end if strstr(opt,...)

    if(!fInit){
      cout << "Initilization Failed, Can't run Exec." << endl;
      return;
    } // end if !fInit
    for(evnt=0;evnt<fEnt;evnt++)
     {
      Info("Exec","");
      Info("Exec","Processing Event %d",evnt);
      Info("Exec","");

      fRunLoader->GetEvent(evnt);
      if (fLoader->TreeR() == 0x0) fLoader->MakeTree("R");
      fDetTypeRec->MakeBranchR(0);
      fDetTypeRec->SetTreeAddressR(fLoader->TreeR());
      fDetTypeRec->SetTreeAddressD(fLoader->TreeD());
      fDetTypeRec->DigitsToRecPoints(fLoader->TreeD(),fLoader->TreeR(),0,lopt);
    } // end for evnt
}
//______________________________________________________________________
void AliITSreconstruction::SetOutputFile(TString filename){
  // Set a new file name for recpoints.
  // It must be called before Init()
  if(!fLoader)fLoader = (AliITSLoader*) fRunLoader->GetLoader("ITSLoader");
  if(fLoader){
    Info("SetOutputFile","name for rec points is %s",filename.Data());
    fLoader->SetRecPointsFileName(filename);
  }
  else {
    Error("SetOutputFile",
    "ITS loader not available. Not possible to set name: %s",filename.Data());
  }
}
<|endoftext|>


<commit_before>#include "GameManager.h"

USING_NS_CC;

Scene *GameManager::createScene() {
  auto scene = Scene::create();
  auto layer = GameManager::create();
  scene->addChild(layer);

  return scene;
}

bool GameManager::init() {
  if (!Layer::init()) {
    return false;
  }

  loadCards();
  arrangeCards();

  // Touchアクションのイベントリスナー
  auto listener = EventListenerTouchOneByOne::create();

  // タッチ開始時の処理
  listener->onTouchBegan = [this](Touch *touch, Event *event) {
    CCLOG("TouchBegan");

    auto loc = touch->getLocation();

    switch (gameState) {
            // 1枚目のカードを選択
        case GameState::OpenFirstCard:
            for (int i = 0; i < cards.size(); i++) {
                // カードがクローズしているかつタッチポイントがカード内に存在する場合
                if (!cards.at(i)->isOpen() && cards.at(i)->inside(loc)) {
                    cards.at(i)->open();
                    selectedFirstCardIndex = i;
                    gameState = GameState::OpenSecondCard;
                    break;
                };
            }
            break;
            // 2枚目のカードを選択
        case GameState::OpenSecondCard:
            for (int i = 0; i < cards.size(); i++) {
                // カードがクローズしているかつタッチポイントがカード内に存在する場合
                if (!cards.at(i)->isOpen() && cards.at(i)->inside(loc)) {
                    cards.at(i)->open();
                    selectedSecondCardIndex = i;
                    gameState = GameState::CheckPair;
                    break;
                };
            }
            break;
            // カードのペアチェック
        case GameState::CheckPair:
            if (cards.at(selectedFirstCardIndex)->getCardNumber() == cards.at(selectedSecondCardIndex)->getCardNumber()) {

                cards.at(selectedFirstCardIndex)->invisible();
                cards.at(selectedSecondCardIndex)->invisible();

                // 残りのペア数を減らす
                remainingNumberOfPairs--;
            }
            // ペアが成立しなかった場合
            else {
                cards.at(selectedFirstCardIndex)->close();
                cards.at(selectedSecondCardIndex)->close();
            }

            // 残りのペアが無くなった場合、ゲームをリセットする
            if (remainingNumberOfPairs == 0) {
                gameState = GameState::ResetGame;
            }
            else {
                gameState = GameState::OpenFirstCard;
            }

            break;
            // ゲームをリセットする
        case GameState::ResetGame:
            remainingNumberOfPairs = MAX_CARD_NUMBER;

            // カードの状態をリセットする
            for (auto& card : cards) {
                card->visible();
                card->close();
            }

            // カードの再配置
            arrangeCards();

            // 新しいゲームを開始する
            gameState = GameState::OpenFirstCard;
            break;
    }

    return true;
  };

  // タッチイベントの登録
  Director::getInstance()
      ->getEventDispatcher()
      ->addEventListenerWithSceneGraphPriority(listener, this);

  return true;
}

// カードをロードする関数
void GameManager::loadCards() {
  for (int i = 1; i <= MAX_CARD_NUMBER; i++) {

    // ハート柄のカードをロードする
    auto heart =
        Card::create(i, StringUtils::format("h%d.png", i), "back_red.png");
    heart->setAnchorPoint(Vec2::ANCHOR_BOTTOM_LEFT);
    addChild(heart);

    // 動的配列へ追加
    cards.pushBack(heart);

    // ダイヤ柄のカードをロードする
    auto diamond =
        Card::create(i, StringUtils::format("d%d.png", i), "back_red.png");
    diamond->setAnchorPoint(Vec2::ANCHOR_BOTTOM_LEFT);
    addChild(diamond);

    // 動的配列へ追加
    cards.pushBack(diamond);
  }
}

// カードを配置する関数
void GameManager::arrangeCards() {
  const Size windowSize = Director::getInstance()->getWinSize();
  const Size cardSize = cards.back()->getCardSize(); // カードサイズは全て同じ
  const Size margin((windowSize.width - cardSize.width * MAX_CARD_ROWS) / (MAX_CARD_ROWS + 1),
                    (windowSize.height - cardSize.height * MAX_CARD_COLS) / (MAX_CARD_COLS + 1));

  int row = 0;
  int col = 0;

  for (auto &card : cards) {
    card->setPosition((cardSize.width + margin.width) * row + margin.width,
                      (cardSize.height + margin.height) * col + margin.height);

    row++;
    if (row % MAX_CARD_ROWS == 0) {
      row = 0;
      col++;
    }
  }
}<commit_msg>簡易版カードシャッフル機能の追加<commit_after>#include "GameManager.h"

USING_NS_CC;

Scene *GameManager::createScene() {
  auto scene = Scene::create();
  auto layer = GameManager::create();
  scene->addChild(layer);

  return scene;
}

bool GameManager::init() {
  if (!Layer::init()) {
    return false;
  }

  loadCards();
  arrangeCards();

  // Touchアクションのイベントリスナー
  auto listener = EventListenerTouchOneByOne::create();

  // タッチ開始時の処理
  listener->onTouchBegan = [this](Touch *touch, Event *event) {
    CCLOG("TouchBegan");

    auto loc = touch->getLocation();

    switch (gameState) {
            // 1枚目のカードを選択
        case GameState::OpenFirstCard:
            for (int i = 0; i < cards.size(); i++) {
                // カードがクローズしているかつタッチポイントがカード内に存在する場合
                if (!cards.at(i)->isOpen() && cards.at(i)->inside(loc)) {
                    cards.at(i)->open();
                    selectedFirstCardIndex = i;
                    gameState = GameState::OpenSecondCard;
                    break;
                };
            }
            break;
            // 2枚目のカードを選択
        case GameState::OpenSecondCard:
            for (int i = 0; i < cards.size(); i++) {
                // カードがクローズしているかつタッチポイントがカード内に存在する場合
                if (!cards.at(i)->isOpen() && cards.at(i)->inside(loc)) {
                    cards.at(i)->open();
                    selectedSecondCardIndex = i;
                    gameState = GameState::CheckPair;
                    break;
                };
            }
            break;
            // カードのペアチェック
        case GameState::CheckPair:
            if (cards.at(selectedFirstCardIndex)->getCardNumber() == cards.at(selectedSecondCardIndex)->getCardNumber()) {

                cards.at(selectedFirstCardIndex)->invisible();
                cards.at(selectedSecondCardIndex)->invisible();

                // 残りのペア数を減らす
                remainingNumberOfPairs--;
            }
            // ペアが成立しなかった場合
            else {
                cards.at(selectedFirstCardIndex)->close();
                cards.at(selectedSecondCardIndex)->close();
            }

            // 残りのペアが無くなった場合、ゲームをリセットする
            if (remainingNumberOfPairs == 0) {
                gameState = GameState::ResetGame;
            }
            else {
                gameState = GameState::OpenFirstCard;
            }

            break;
            // ゲームをリセットする
        case GameState::ResetGame:
            remainingNumberOfPairs = MAX_CARD_NUMBER;

            // カードの状態をリセットする
            for (auto& card : cards) {
                card->visible();
                card->close();
            }

            // カードの再配置
            arrangeCards();

            // 新しいゲームを開始する
            gameState = GameState::OpenFirstCard;
            break;
    }

    return true;
  };

  // タッチイベントの登録
  Director::getInstance()
      ->getEventDispatcher()
      ->addEventListenerWithSceneGraphPriority(listener, this);

  return true;
}

// カードをロードする関数
void GameManager::loadCards() {
  for (int i = 1; i <= MAX_CARD_NUMBER; i++) {

    // ハート柄のカードをロードする
    auto heart =
        Card::create(i, StringUtils::format("h%d.png", i), "back_red.png");
    heart->setAnchorPoint(Vec2::ANCHOR_BOTTOM_LEFT);
    addChild(heart);

    // 動的配列へ追加
    cards.pushBack(heart);

    // ダイヤ柄のカードをロードする
    auto diamond =
        Card::create(i, StringUtils::format("d%d.png", i), "back_red.png");
    diamond->setAnchorPoint(Vec2::ANCHOR_BOTTOM_LEFT);
    addChild(diamond);

    // 動的配列へ追加
    cards.pushBack(diamond);
  }
}

// カードを配置する関数
void GameManager::arrangeCards() {
  // カードのシャッフル(簡易版)
  std::shuffle(cards.begin(), cards.end(), std::mt19937());

  const Size windowSize = Director::getInstance()->getWinSize();
  const Size cardSize = cards.back()->getCardSize(); // カードサイズは全て同じ
  const Size margin((windowSize.width - cardSize.width * MAX_CARD_ROWS) / (MAX_CARD_ROWS + 1),
                    (windowSize.height - cardSize.height * MAX_CARD_COLS) / (MAX_CARD_COLS + 1));

  int row = 0;
  int col = 0;

  for (auto &card : cards) {
    card->setPosition((cardSize.width + margin.width) * row + margin.width,
                      (cardSize.height + margin.height) * col + margin.height);

    row++;
    if (row % MAX_CARD_ROWS == 0) {
      row = 0;
      col++;
    }
  }
}<|endoftext|>


<commit_before>/*****************************************************************************
 * CameraCalibration.cpp
 *
 * Set white balance for given lighting, write parameters to file
 * https://web.stanford.edu/~sujason/ColorBalancing/robustawb.html
 ******************************************************************************/

#include "CameraCalibration.h"

using namespace cv;
using namespace std;

////////////////
// Parameters //
////////////////

#define EXPOSURE        200
#define ISO_VALUE       1

// Image Size
//#define FRAME_WIDTH     3280  // 8 megapixels
//#define FRAME_HEIGHT    2464  // 8 megapixels
#define FRAME_WIDTH       1280  // 720 HD
#define FRAME_HEIGHT      720   // 720 HD

// Balancing Region
#define BALANCE_WIDTH     0.2
#define BALANCE_HEIGHT    0.2

//////////////////////
// Global Variables //
//////////////////////

// Global Variables
string sourcewindow = "Current Image";
VideoCapture cap;
int redbalance = 1600;
int bluebalance = 1600;
int exposure = 5;
Mat bgrframe, yuvframe;

// V4L2 Global Device Object
V4L2Control picamctrl;

////////////////////////
// Callback Functions //
////////////////////////

/*******************************************************************************
 * void mouseCallback(int event, int x, int y, int flags, void* userdata)
 *
 * Write HSV and RGB values of point clicked on to terminal
 * Any mouse movement will call this function
 ******************************************************************************/
void mouseCallback(int event, int x, int y, int flags, void* userdata)
{
  if  ( event == EVENT_LBUTTONDOWN ) // Only run when left button is pressed
  {
    Vec3b bgr = bgrframe.at<Vec3b>(y, x);
    int b = bgr.val[0];
    int g = bgr.val[1];
    int r = bgr.val[2];
    // print out RGB values (sanity check)
    cout << "B: " << b << ",\tG:" << g << ",\tR:" << r << endl;

    Vec3b yuv = yuvframe.at<Vec3b>(y, x);
    int y = yuv.val[0];
    int u = yuv.val[1];
    int v = yuv.val[2];
    // print out YUV values (sanity check)
    cout << "Y: " << y << ",\tU:" << u << ",\tV:" << v << endl;
  }
}

//////////
// Main //
//////////
int main(int argc, char** argv)
{
  // Open the camera!
  cap.open(0); // opens first video device
  picamctrl.open("/dev/video0");

  // check to make sure device properly opened
  if ( !cap.isOpened() )
  {
    cerr << "Error opening the camera (OpenCV)" << endl;
    return -1;
  }

  // Set framerate (OpenCV capture property)
  cap.set(CV_CAP_PROP_FPS,2);

  // Set camera exposure control to manual (driver property)
  picamctrl.set(V4L2_CID_EXPOSURE_AUTO, V4L2_EXPOSURE_MANUAL);

  // Set camera autowhitebalance to manual
  picamctrl.set(V4L2_CID_AUTO_N_PRESET_WHITE_BALANCE,V4L2_WHITE_BALANCE_MANUAL);

  // Disable scene mode
  picamctrl.set(V4L2_CID_SCENE_MODE, V4L2_SCENE_MODE_NONE);

  // Set camera iso to manual
  picamctrl.set(V4L2_CID_ISO_SENSITIVITY_AUTO, 0);

  // Initialize exposure, iso values
  picamctrl.set(V4L2_CID_EXPOSURE_ABSOLUTE, BRIGHT_EXPOSURE);
  picamctrl.set(V4L2_CID_ISO_SENSITIVITY, ISO_VALUE);

  // Set capture camera size (resolution)
  cap.set(CV_CAP_PROP_FRAME_WIDTH,FRAME_WIDTH);
  cap.set(CV_CAP_PROP_FRAME_HEIGHT,FRAME_HEIGHT);

  // Open window on your monitor
  namedWindow( sourcewindow, CV_WINDOW_AUTOSIZE );

  // Create trackbar for exposure setting
//   createTrackbar( " Exposure:", source_window, &exposure, 100, NULL);

  // set the callback function for any mouse event
  setMouseCallback(sourcewindow, mouseCallback, NULL);

  // set default white balance
  picamctrl.set(V4L2_CID_RED_BALANCE, redbalance);
  picamctrl.set(V4L2_CID_BLUE_BALANCE, bluebalance);

  // Calculate region within which we will be balancing the image
  int balanceh_2 = FRAME_HEIGHT * BALANCE_HEIGHT / 2; // half balance box height
  int balancew_2 = FRAME_WIDTH * BALANCE_WIDTH / 2;   // half balance box width
  int framecentery = FRAME_HEIGHT / 2;  // y coord of "center" of frame
  int framecenterx = FRAME_WIDTH / 2;   // x coord of "center" of frame

  // Calculate coordinates of balancing box
  int balancexmin = framecenterx - balancew_2;
  int balancexmax = framecenterx + balancew_2 - 1;
  int balanceymin = framecentery - balanceh_2;
  int balanceymax = framecentery + balanceh_2 - 1;

  // Generate points for bounds of balancing box
  Point b1 = Point(balancexmin, balanceymin);
  Point b2 = Point(balancexmax, balanceymax);

  // Grab all 5 images from the frame buffer in order to clear the buffer
  for(int i=0; i<5; i++)
  {
    cap.grab();
  }

  // Announce that we're done initializing
  cout << "Done Initializing." << endl;

  int key = 0;

  // Loop quickly to pick up images as soon as they are taken
  while(key != 27) // 27 is keycode for escape key
  {
    // 'Grab' frame from webcam's image buffer
    cap.grab();
    // Retrieve encodes image from grab buffer to 'frame' variable
    cap.retrieve( bgrframe );

    // Convert color spaces
    cvtColor(bgrframe, yuvframe, CV_BGR2YCrCb);

    // Obtain average YUV values over our balancing box area.
    Scalar yuvmean = mean(yuvframe(Rect(b1, b2)));
    float ubar = yuvmean[1];  // red
    float vbar = yuvmean[2];  // blue

    // Check whether red (u) or blue (v) is more off.
    if ( abs(ubar) > abs(vbar) )
    {
      // If red is more wrong, adjust red balance
      redbalance -= 1.0*ubar;
      picamctrl.set(V4L2_CID_RED_BALANCE, redbalance);

    }
    else
    {
      // The blue is more wrong, so adjust blue balance
      bluebalance -= 1.0*vbar;
      picamctrl.set(V4L2_CID_BLUE_BALANCE, bluebalance);
    }

    // Draw rectangle in middle of image
    rectangle(bgrframe, b1, b2 , Scalar(255, 255, 0));

    // Display image on current open window
    imshow( sourcewindow, bgrframe );

   // wait 1 ms to check for press of escape key
   key = waitKey(1);
  } // end while

  // close camera
  cap.release();
  picamctrl.close();
}// end main
<commit_msg>variable name error fix<commit_after>/*****************************************************************************
 * CameraCalibration.cpp
 *
 * Set white balance for given lighting, write parameters to file
 * https://web.stanford.edu/~sujason/ColorBalancing/robustawb.html
 ******************************************************************************/

#include "CameraCalibration.h"

using namespace cv;
using namespace std;

////////////////
// Parameters //
////////////////

#define EXPOSURE        200
#define ISO_VALUE       1

// Image Size
//#define FRAME_WIDTH     3280  // 8 megapixels
//#define FRAME_HEIGHT    2464  // 8 megapixels
#define FRAME_WIDTH       1280  // 720 HD
#define FRAME_HEIGHT      720   // 720 HD

// Balancing Region
#define BALANCE_WIDTH     0.2
#define BALANCE_HEIGHT    0.2

//////////////////////
// Global Variables //
//////////////////////

// Global Variables
string sourcewindow = "Current Image";
VideoCapture cap;
int redbalance = 1600;
int bluebalance = 1600;
int exposure = 5;
Mat bgrframe, yuvframe;

// V4L2 Global Device Object
V4L2Control picamctrl;

////////////////////////
// Callback Functions //
////////////////////////

/*******************************************************************************
 * void mouseCallback(int event, int x, int y, int flags, void* userdata)
 *
 * Write HSV and RGB values of point clicked on to terminal
 * Any mouse movement will call this function
 ******************************************************************************/
void mouseCallback(int event, int x, int y, int flags, void* userdata)
{
  if  ( event == EVENT_LBUTTONDOWN ) // Only run when left button is pressed
  {
    Vec3b bgr = bgrframe.at<Vec3b>(y, x);
    int b = bgr.val[0];
    int g = bgr.val[1];
    int r = bgr.val[2];
    // print out RGB values (sanity check)
    cout << "B: " << b << ",\tG:" << g << ",\tR:" << r << endl;

    Vec3b yuv = yuvframe.at<Vec3b>(y, x);
    int y = yuv.val[0];
    int u = yuv.val[1];
    int v = yuv.val[2];
    // print out YUV values (sanity check)
    cout << "Y: " << y << ",\tU:" << u << ",\tV:" << v << endl;
  }
}

//////////
// Main //
//////////
int main(int argc, char** argv)
{
  // Open the camera!
  cap.open(0); // opens first video device
  picamctrl.open("/dev/video0");

  // check to make sure device properly opened
  if ( !cap.isOpened() )
  {
    cerr << "Error opening the camera (OpenCV)" << endl;
    return -1;
  }

  // Set framerate (OpenCV capture property)
  cap.set(CV_CAP_PROP_FPS,2);

  // Set camera exposure control to manual (driver property)
  picamctrl.set(V4L2_CID_EXPOSURE_AUTO, V4L2_EXPOSURE_MANUAL);

  // Set camera autowhitebalance to manual
  picamctrl.set(V4L2_CID_AUTO_N_PRESET_WHITE_BALANCE,V4L2_WHITE_BALANCE_MANUAL);

  // Disable scene mode
  picamctrl.set(V4L2_CID_SCENE_MODE, V4L2_SCENE_MODE_NONE);

  // Set camera iso to manual
  picamctrl.set(V4L2_CID_ISO_SENSITIVITY_AUTO, 0);

  // Initialize exposure, iso values
  picamctrl.set(V4L2_CID_EXPOSURE_ABSOLUTE, EXPOSURE);
  picamctrl.set(V4L2_CID_ISO_SENSITIVITY, ISO_VALUE);

  // Set capture camera size (resolution)
  cap.set(CV_CAP_PROP_FRAME_WIDTH,FRAME_WIDTH);
  cap.set(CV_CAP_PROP_FRAME_HEIGHT,FRAME_HEIGHT);

  // Open window on your monitor
  namedWindow( sourcewindow, CV_WINDOW_AUTOSIZE );

  // Create trackbar for exposure setting
//   createTrackbar( " Exposure:", source_window, &exposure, 100, NULL);

  // set the callback function for any mouse event
  setMouseCallback(sourcewindow, mouseCallback, NULL);

  // set default white balance
  picamctrl.set(V4L2_CID_RED_BALANCE, redbalance);
  picamctrl.set(V4L2_CID_BLUE_BALANCE, bluebalance);

  // Calculate region within which we will be balancing the image
  int balanceh_2 = FRAME_HEIGHT * BALANCE_HEIGHT / 2; // half balance box height
  int balancew_2 = FRAME_WIDTH * BALANCE_WIDTH / 2;   // half balance box width
  int framecentery = FRAME_HEIGHT / 2;  // y coord of "center" of frame
  int framecenterx = FRAME_WIDTH / 2;   // x coord of "center" of frame

  // Calculate coordinates of balancing box
  int balancexmin = framecenterx - balancew_2;
  int balancexmax = framecenterx + balancew_2 - 1;
  int balanceymin = framecentery - balanceh_2;
  int balanceymax = framecentery + balanceh_2 - 1;

  // Generate points for bounds of balancing box
  Point b1 = Point(balancexmin, balanceymin);
  Point b2 = Point(balancexmax, balanceymax);

  // Grab all 5 images from the frame buffer in order to clear the buffer
  for(int i=0; i<5; i++)
  {
    cap.grab();
  }

  // Announce that we're done initializing
  cout << "Done Initializing." << endl;

  int key = 0;

  // Loop quickly to pick up images as soon as they are taken
  while(key != 27) // 27 is keycode for escape key
  {
    // 'Grab' frame from webcam's image buffer
    cap.grab();
    // Retrieve encodes image from grab buffer to 'frame' variable
    cap.retrieve( bgrframe );

    // Convert color spaces
    cvtColor(bgrframe, yuvframe, CV_BGR2YCrCb);

    // Obtain average YUV values over our balancing box area.
    Scalar yuvmean = mean(yuvframe(Rect(b1, b2)));
    float ubar = yuvmean[1];  // red
    float vbar = yuvmean[2];  // blue

    // Check whether red (u) or blue (v) is more off.
    if ( abs(ubar) > abs(vbar) )
    {
      // If red is more wrong, adjust red balance
      redbalance -= 1.0*ubar;
      picamctrl.set(V4L2_CID_RED_BALANCE, redbalance);

    }
    else
    {
      // The blue is more wrong, so adjust blue balance
      bluebalance -= 1.0*vbar;
      picamctrl.set(V4L2_CID_BLUE_BALANCE, bluebalance);
    }

    // Draw rectangle in middle of image
    rectangle(bgrframe, b1, b2 , Scalar(255, 255, 0));

    // Display image on current open window
    imshow( sourcewindow, bgrframe );

   // wait 1 ms to check for press of escape key
   key = waitKey(1);
  } // end while

  // close camera
  cap.release();
  picamctrl.close();
}// end main
<|endoftext|>


<commit_before>//===- CallingConvEmitter.cpp - Generate calling conventions --------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file was developed by Chris Lattner and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This tablegen backend is responsible for emitting descriptions of the calling
// conventions supported by this target.
//
//===----------------------------------------------------------------------===//

#include "CallingConvEmitter.h"
#include "Record.h"
#include "CodeGenTarget.h"
using namespace llvm;

void CallingConvEmitter::run(std::ostream &O) {
  EmitSourceFileHeader("Calling Convention Implementation Fragment", O);

  std::vector<Record*> CCs = Records.getAllDerivedDefinitions("CallingConv");

  // Emit prototypes for all of the CC's so that they can forward ref each
  // other.
  for (unsigned i = 0, e = CCs.size(); i != e; ++i) {
    O << "static bool " << CCs[i]->getName()
      << "(unsigned ValNo, MVT::ValueType ValVT, MVT::ValueType LocVT,\n"
      << std::string(CCs[i]->getName().size()+13, ' ')
      << "CCValAssign::LocInfo LocInfo, unsigned ArgFlags, CCState &State);\n";
  }

  // Emit each calling convention description in full.
  for (unsigned i = 0, e = CCs.size(); i != e; ++i)
    EmitCallingConv(CCs[i], O);
}

void CallingConvEmitter::EmitCallingConv(Record *CC, std::ostream &O) {
  ListInit *CCActions = CC->getValueAsListInit("Actions");
  Counter = 0;

  O << "\n\nstatic bool " << CC->getName()
    << "(unsigned ValNo, MVT::ValueType ValVT, MVT::ValueType LocVT,\n"
    << std::string(CC->getName().size()+13, ' ')
    << "CCValAssign::LocInfo LocInfo, "
    << "unsigned ArgFlags, CCState &State) {\n";

  // Emit all of the actions, in order.
  for (unsigned i = 0, e = CCActions->getSize(); i != e; ++i) {
    O << "\n";
    EmitAction(CCActions->getElementAsRecord(i), 2, O);
  }

  O << "\n  return true;  // CC didn't match.\n";
  O << "}\n";
}

void CallingConvEmitter::EmitAction(Record *Action,
                                    unsigned Indent, std::ostream &O) {
  std::string IndentStr = std::string(Indent, ' ');

  if (Action->isSubClassOf("CCPredicateAction")) {
    O << IndentStr << "if (";

    if (Action->isSubClassOf("CCMatchType")) {
      ListInit *VTs = Action->getValueAsListInit("VTs");
      for (unsigned i = 0, e = VTs->getSize(); i != e; ++i) {
        Record *VT = VTs->getElementAsRecord(i);
        if (i != 0) O << " || \n    " << IndentStr;
        O << "LocVT == " << getEnumName(getValueType(VT));
      }

    } else if (Action->isSubClassOf("CCMatchIf")) {
      O << Action->getValueAsString("Predicate");
    } else {
      Action->dump();
      throw "Unknown CCPredicateAction!";
    }

    O << ") {\n";
    EmitAction(Action->getValueAsDef("SubAction"), Indent+2, O);
    O << IndentStr << "}\n";
  } else {
    if (Action->isSubClassOf("CCDelegateTo")) {
      Record *CC = Action->getValueAsDef("CC");
      O << IndentStr << "if (!" << CC->getName()
        << "(ValNo, ValVT, LocVT, LocInfo, ArgFlags, State))\n"
        << IndentStr << "  return false;\n";
    } else if (Action->isSubClassOf("CCAssignToReg")) {
      ListInit *RegList = Action->getValueAsListInit("RegList");
      if (RegList->getSize() == 1) {
        O << IndentStr << "if (unsigned Reg = State.AllocateReg(";
        O << getQualifiedName(RegList->getElementAsRecord(0)) << ")) {\n";
      } else {
        O << IndentStr << "static const unsigned RegList" << ++Counter
          << "[] = {\n";
        O << IndentStr << "  ";
        for (unsigned i = 0, e = RegList->getSize(); i != e; ++i) {
          if (i != 0) O << ", ";
          O << getQualifiedName(RegList->getElementAsRecord(i));
        }
        O << "\n" << IndentStr << "};\n";
        O << IndentStr << "if (unsigned Reg = State.AllocateReg(RegList"
          << Counter << ", " << RegList->getSize() << ")) {\n";
      }
      O << IndentStr << "  State.addLoc(CCValAssign::getReg(ValNo, ValVT, "
        << "Reg, LocVT, LocInfo));\n";
      O << IndentStr << "  return false;\n";
      O << IndentStr << "}\n";
    } else if (Action->isSubClassOf("CCAssignToStack")) {
      int Size = Action->getValueAsInt("Size");
      int Align = Action->getValueAsInt("Align");

      O << IndentStr << "unsigned Offset" << ++Counter
        << " = State.AllocateStack(" << Size << ", " << Align << ");\n";
      O << IndentStr << "State.addLoc(CCValAssign::getMem(ValNo, ArgVT, Offset"
        << Counter << ", LocVT, LocInfo));\n";
      O << IndentStr << "return false;\n";
    } else if (Action->isSubClassOf("CCPromoteToType")) {

    } else {
      Action->dump();
      throw "Unknown CCAction!";
    }
  }
}

<commit_msg>implement CCPromoteToType<commit_after>//===- CallingConvEmitter.cpp - Generate calling conventions --------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file was developed by Chris Lattner and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This tablegen backend is responsible for emitting descriptions of the calling
// conventions supported by this target.
//
//===----------------------------------------------------------------------===//

#include "CallingConvEmitter.h"
#include "Record.h"
#include "CodeGenTarget.h"
using namespace llvm;

void CallingConvEmitter::run(std::ostream &O) {
  EmitSourceFileHeader("Calling Convention Implementation Fragment", O);

  std::vector<Record*> CCs = Records.getAllDerivedDefinitions("CallingConv");

  // Emit prototypes for all of the CC's so that they can forward ref each
  // other.
  for (unsigned i = 0, e = CCs.size(); i != e; ++i) {
    O << "static bool " << CCs[i]->getName()
      << "(unsigned ValNo, MVT::ValueType ValVT,\n"
      << std::string(CCs[i]->getName().size()+13, ' ')
      << "MVT::ValueType LocVT, CCValAssign::LocInfo LocInfo,\n"
      << std::string(CCs[i]->getName().size()+13, ' ')
      << "unsigned ArgFlags, CCState &State);\n";
  }

  // Emit each calling convention description in full.
  for (unsigned i = 0, e = CCs.size(); i != e; ++i)
    EmitCallingConv(CCs[i], O);
}

void CallingConvEmitter::EmitCallingConv(Record *CC, std::ostream &O) {
  ListInit *CCActions = CC->getValueAsListInit("Actions");
  Counter = 0;

  O << "\n\nstatic bool " << CC->getName()
    << "(unsigned ValNo, MVT::ValueType ValVT,\n"
    << std::string(CC->getName().size()+13, ' ')
    << "MVT::ValueType LocVT, CCValAssign::LocInfo LocInfo,\n"
    << std::string(CC->getName().size()+13, ' ')
    << "unsigned ArgFlags, CCState &State) {\n";
  // Emit all of the actions, in order.
  for (unsigned i = 0, e = CCActions->getSize(); i != e; ++i) {
    O << "\n";
    EmitAction(CCActions->getElementAsRecord(i), 2, O);
  }

  O << "\n  return true;  // CC didn't match.\n";
  O << "}\n";
}

void CallingConvEmitter::EmitAction(Record *Action,
                                    unsigned Indent, std::ostream &O) {
  std::string IndentStr = std::string(Indent, ' ');

  if (Action->isSubClassOf("CCPredicateAction")) {
    O << IndentStr << "if (";

    if (Action->isSubClassOf("CCMatchType")) {
      ListInit *VTs = Action->getValueAsListInit("VTs");
      for (unsigned i = 0, e = VTs->getSize(); i != e; ++i) {
        Record *VT = VTs->getElementAsRecord(i);
        if (i != 0) O << " ||\n    " << IndentStr;
        O << "LocVT == " << getEnumName(getValueType(VT));
      }

    } else if (Action->isSubClassOf("CCMatchIf")) {
      O << Action->getValueAsString("Predicate");
    } else {
      Action->dump();
      throw "Unknown CCPredicateAction!";
    }

    O << ") {\n";
    EmitAction(Action->getValueAsDef("SubAction"), Indent+2, O);
    O << IndentStr << "}\n";
  } else {
    if (Action->isSubClassOf("CCDelegateTo")) {
      Record *CC = Action->getValueAsDef("CC");
      O << IndentStr << "if (!" << CC->getName()
        << "(ValNo, ValVT, LocVT, LocInfo, ArgFlags, State))\n"
        << IndentStr << "  return false;\n";
    } else if (Action->isSubClassOf("CCAssignToReg")) {
      ListInit *RegList = Action->getValueAsListInit("RegList");
      if (RegList->getSize() == 1) {
        O << IndentStr << "if (unsigned Reg = State.AllocateReg(";
        O << getQualifiedName(RegList->getElementAsRecord(0)) << ")) {\n";
      } else {
        O << IndentStr << "static const unsigned RegList" << ++Counter
          << "[] = {\n";
        O << IndentStr << "  ";
        for (unsigned i = 0, e = RegList->getSize(); i != e; ++i) {
          if (i != 0) O << ", ";
          O << getQualifiedName(RegList->getElementAsRecord(i));
        }
        O << "\n" << IndentStr << "};\n";
        O << IndentStr << "if (unsigned Reg = State.AllocateReg(RegList"
          << Counter << ", " << RegList->getSize() << ")) {\n";
      }
      O << IndentStr << "  State.addLoc(CCValAssign::getReg(ValNo, ValVT, "
        << "Reg, LocVT, LocInfo));\n";
      O << IndentStr << "  return false;\n";
      O << IndentStr << "}\n";
    } else if (Action->isSubClassOf("CCAssignToStack")) {
      int Size = Action->getValueAsInt("Size");
      int Align = Action->getValueAsInt("Align");

      O << IndentStr << "unsigned Offset" << ++Counter
        << " = State.AllocateStack(" << Size << ", " << Align << ");\n";
      O << IndentStr << "State.addLoc(CCValAssign::getMem(ValNo, ValVT, Offset"
        << Counter << ", LocVT, LocInfo));\n";
      O << IndentStr << "return false;\n";
    } else if (Action->isSubClassOf("CCPromoteToType")) {
      Record *DestTy = Action->getValueAsDef("DestTy");
      O << IndentStr << "LocVT = " << getEnumName(getValueType(DestTy)) <<";\n";
      O << IndentStr << "LocInfo = (ArgFlags & 1) ? CCValAssign::SExt"
        << " : CCValAssign::ZExt;\n";
    } else {
      Action->dump();
      throw "Unknown CCAction!";
    }
  }
}

<|endoftext|>