<commit_before>#include <iostream>
#include "consoleui.h"
#include "performer.h"
#include "dataaccess.h"

using namespace std;

ConsoleUI::ConsoleUI()
{

}

// Should not contain logic for individual commands, that should be in separate functions!
void ConsoleUI::run()
{
    intro();
    commandHelp();

    string command;

    do
    {
        cout << endl << "Enter a command or help for list of commands: ";
        cin >> command;
        cout << endl;

        if (command == "list")
        {
            displayListOfPerformers();
        }

        else if (command == "add")
        {
            commandAdd();
        }

        else if (command == "search")
        {
            displaySearch();
        }

        else if(command == "sort")
        {
            chooseSort();
        }

        else if (command == "help")
        {
            commandHelp();
        }

        else if (command == "exit")
        {
            cout << "exiting" << endl;
        }

        else
        {
            cout << "invalid command." << endl;
            cout << "type 'help' to see list of commands" << endl;
        }

    }while (command != "exit");
}

void ConsoleUI::displayListOfPerformers()
{
    displayTopTable();

    vector<Performer> pf = _service.getPerformers();

    for (size_t i = 0; i < pf.size(); ++i)
        {
            if(pf[i].getName().length() > 16)
            {
                cout << i+1 << "\t" << pf[i].getName();
                cout << "\t"  << pf[i].getGender() << "\t" << "\t";
                cout << pf[i].getbYear() << "\t\t\t" << pf[i].getdYear();
                cout << "\t\t\t" << pf[i].getNation() << endl;
            }
            else if(pf[i].getName().length() < 16 && pf[i].getName().length() > 8)
            {
                cout << i+1 << "\t" << pf[i].getName();
                cout << "\t\t"  << pf[i].getGender() << "\t" << "\t";
                cout << pf[i].getbYear() << "\t\t\t" << pf[i].getdYear();
                cout << "\t\t\t" << pf[i].getNation() << endl;
            }
            else if(pf[i].getName().length() <= 8)
            {
                cout << i+1 << "\t" << pf[i].getName();
                cout << "\t\t\t"  << pf[i].getGender() << "\t" << "\t";
                cout << pf[i].getbYear() << "\t\t\t" << pf[i].getdYear();
                cout << "\t\t\t" << pf[i].getNation() << endl;
            }
        }
}

void ConsoleUI::displaySearch()
{
    string input;
    cout << "Enter full name to search for, the search is case-sensitive: ";
    cin.ignore();
    getline(cin, input);

    vector <Performer> newVector = _service.search(input);
    if(newVector.size() == 0)
    {
        cout << "Nothing was found!";
    }
    if(newVector.size() > 0)
    {
        displayTopTable();
    }

    for(size_t i = 0; i < newVector.size(); i++)
    {
        if(newVector[i].getName().length() > 16)
        {
            cout << i+1 << "\t" << newVector[i].getName();
            cout << "\t" << newVector[i].getGender() << "\t" << "\t";
            cout << newVector[i].getbYear() << "\t\t\t" << newVector[i].getdYear();
            cout << "\t\t\t" << newVector[i].getNation() << endl;
        }
        else if(newVector[i].getName().length() < 16 && newVector[i].getName().length() > 8)
        {
            cout << i+1 << "\t" << newVector[i].getName();
            cout << "\t\t" << newVector[i].getGender() << "\t" << "\t";
            cout << newVector[i].getbYear() << "\t\t\t" << newVector[i].getdYear();
            cout << "\t\t\t" << newVector[i].getNation() << endl;
        }
        else if(newVector[i].getName().length() <= 8)
        {
            cout << i+1 << "\t" << newVector[i].getName();
            cout << "\t\t\t" << newVector[i].getGender() << "\t" << "\t";
            cout << newVector[i].getbYear() << "\t\t\t" << newVector[i].getdYear();
            cout << "\t\t\t" << newVector[i].getNation() << endl;
        }
    }

}

void ConsoleUI::displaySort(vector<Performer> newVector)
{
    for(size_t i = 0; i < newVector.size(); i++)
    {
        if(newVector[i].getName().length() > 16)
        {
            cout << i+1 << "\t" << newVector[i].getName();
            cout << "\t" << newVector[i].getGender() << "\t" << "\t";
            cout << newVector[i].getbYear() << "\t\t\t" << newVector[i].getdYear();
            cout << "\t\t\t" << newVector[i].getNation() << endl;
        }
        else if(newVector[i].getName().length() < 16 && newVector[i].getName().length() > 8)
        {
            cout << i+1 << "\t" << newVector[i].getName();
            cout << "\t\t" << newVector[i].getGender() << "\t" << "\t";
            cout << newVector[i].getbYear() << "\t\t\t" << newVector[i].getdYear();
            cout << "\t\t\t" << newVector[i].getNation() << endl;
        }
        else if(newVector[i].getName().length() <= 8)
        {
            cout << i+1 << "\t" << newVector[i].getName();
            cout << "\t\t\t" << newVector[i].getGender() << "\t" << "\t";
            cout << newVector[i].getbYear() << "\t\t\t" << newVector[i].getdYear();
            cout << "\t\t\t" << newVector[i].getNation() << endl;
        }
    }
}
string ConsoleUI::inputName()
{
    string name;
    cin.ignore();
    cout << "Enter full name: ";
    getline(cin, name);

    return name;
}

string ConsoleUI::inputGender()
{
    string gender;
    cout << "Enter gender: ";
    do
    {
        getline(cin, gender);
        if(gender == "Male")
        {
            return gender;
        }
        else if (gender == "male")
        {
            gender = "Male";
            return gender;
        }
        else if(gender == "Female")
        {
            return gender;
        }
        else if (gender == "female")
        {
            gender = "Female";
            return gender;
        }
        else
        {
            cout << "That's not a gender!" << endl;
            cout << "Enter gender: ";
        }
    }while(1 == 1);
    return gender;
}

string ConsoleUI::inputBirth()
{
    string birth;
    cout << "Enter year of birth: ";
    getline(cin, birth);
    int value = atoi(birth.c_str());
    while(value < 0 || value > 2016)
    {
        cout << "That's not a valid year" << endl;
        cout << "Enter year of birth: ";
        getline(cin, birth);
        value = atoi(birth.c_str());
    }
    return birth;
}

string ConsoleUI::inputDeath()
{
    string death;
    cout << "Enter year of death or enter '--' if alive: ";
    getline(cin, death);
    int value = atoi(death.c_str());
    if(death == "--"){
        return death;
    }
    while(value < 0 || value > 2016)
    {
        cout << "That's not a valid year" << endl;
        cout << "Enter year of death: ";
        getline(cin, death);
        value = atoi(death.c_str());
    }

    return death;
}
string ConsoleUI::inputNation()
{
    string nation;
    cout << "Enter Nation: ";
    getline(cin, nation);

    return nation;
}

void ConsoleUI::chooseSort()
{
    int choice;
    cout << "Choose 1 to sort in alphabetical order" << endl;
    cout << "Choose 2 to sort by birth year" << endl;
    cout << "Choose 3 to sort by gender" << endl;
    cout << "Choose 4 to sort by nationality" << endl;
    cout << "Choice: ";
    cin >> choice;

    if(choice == 1)
    {
        vector<Performer> newVector = _service.sortByName();
        cout << endl;
        cout << "              " << "---- List ordered alphabetically by first name ----" << endl;
        cout << endl;
        cout << "Nr" << "\t" << "Name" << "\t\t\t" << "Gender";
        cout << "\t\t" << "Birth year" << "\t\t" << "Deceased" << "\t\t" <<"Nationality" << endl;
        for (int i = 0; i < 54*2; ++i)
        {
            cout << "=";
        }
        cout << endl;
        displaySort(newVector);
    }

    else if(choice == 2)
    {
      cout << endl;
      cout << "                      " << "---- List ordered by birth year ----" << endl;
      cout << endl;
      cout << "Nr" << "\t" << "Name" << "\t\t\t" << "Gender";
      cout << "\t\t" << "Birth year" << "\t\t" << "Deceased" << "\t\t" <<"Nationality" << endl;
      for (int i = 0; i < 54*2; ++i)
      {
          cout << "=";
      }
      cout << endl;
      vector <Performer> newVector = _service.sortBybYear();
      displaySort(newVector);

     }

    else if(choice == 3)
    {
        cout << endl;
        cout << "                       " << "---- List ordered by gender ----" << endl;
        cout << endl;
        cout << "Nr" << "\t" << "Name" << "\t\t\t" << "Gender";
        cout << "\t\t" << "Birth year" << "\t\t" << "Deceased" << "\t\t" <<"Nationality" << endl;
        for (int i = 0; i < 54*2; ++i)
        {
            cout << "=";
        }
        cout << endl;
        vector <Performer> newVector = _service.sortByGender();
        displaySort(newVector);
    }
    else if(choice == 4)
    {
        vector<Performer> newVector = _service.sortByNationality();
        cout << endl;
        cout << "              " << "---- List ordered alphabetically by nationality ----" << endl;
        cout << endl;
        cout << "Nr" << "\t" << "Name" << "\t\t\t" << "Gender";
        cout << "\t\t" << "Birth year" << "\t\t" << "Deceased" << "\t\t" <<"Nationality" << endl;
        for (int i = 0; i < 54*2; ++i)
        {
            cout << "=";
        }
        cout << endl;
        displaySort(newVector);
    }

    else {
        cout << "Invalid choice!";
    }
}

void ConsoleUI::commandHelp()
{
    cout << "list   - This will list all computer scientists in the system" << endl;
    cout << "add    - This will add a new computer scientists" << endl;
    cout << "search - Searches for a given computer scientist" << endl;
    cout << "sort   - Sorts the computer scientists by choice" << endl;
    cout << "help   - Displays list of commands" << endl;
    cout << "exit   - This will close the application" << endl;
}

void ConsoleUI::commandAdd()
{
    string name = inputName();
    string gender = inputGender();
    string birth = inputBirth();
    string death = inputDeath();
    int value = 0;
    int value2 = 0;

    if(death != "--")
    {
    value = atoi(birth.c_str());
    value2 = atoi(death.c_str());
    }
    while(value2 < value)
    {
        cout << "Death year can't be less than birth year!" << endl;
        death = inputDeath();
        if(death == "--")
        {
            break;
        }
        value2 = atoi(death.c_str());

    }
    string nation = inputNation();
    _service.addPerformer(name, gender, birth, death, nation);
    cout << endl;
    cout << name << " has been added to the database!" << endl;
}

void ConsoleUI::intro()
{
    cout << endl;
    cout << "This program is designed to keep track of some details on known computer scientists. " << endl;
    cout << "User is able to enter known characters from the history of computer science into a database." << endl;
    cout << "The program can display a list of the characters that have been entered into the database." << endl;
    cout << "It is also possible to perform a search of a specific person from the list." << endl << endl;
    for (int i = 0; i < 45*2; ++i)
    {
        cout << "=";
    }
    cout << endl;
    cout << endl;
    cout << "Please enter one of the following commands to continue:" << endl;
    cout << endl;
}

void ConsoleUI::displayTopTable()
{
    cout << endl;
    cout << "            " << "---- List of all computer scientists in the system ----" << endl;
    cout << endl;
    cout << "Nr" << "\t" << "Name" << "\t\t\t" << "Gender";
    cout << "\t\t" << "Birth year" << "\t\t" << "Deceased" << "\t\t" <<"Nationality" << endl;
    for (int i = 0; i < 54*2; ++i)
    {
        cout << "=";
    }
    cout << endl;
}
<commit_msg>villutekk i nafni<commit_after>#include <iostream>
#include "consoleui.h"
#include "performer.h"
#include "dataaccess.h"

using namespace std;

ConsoleUI::ConsoleUI()
{

}

// Should not contain logic for individual commands, that should be in separate functions!
void ConsoleUI::run()
{
    intro();
    commandHelp();

    string command;

    do
    {
        cout << endl << "Enter a command or help for list of commands: ";
        cin >> command;
        cout << endl;

        if (command == "list")
        {
            displayListOfPerformers();
        }

        else if (command == "add")
        {
            commandAdd();
        }

        else if (command == "search")
        {
            displaySearch();
        }

        else if(command == "sort")
        {
            chooseSort();
        }

        else if (command == "help")
        {
            commandHelp();
        }

        else if (command == "exit")
        {
            cout << "exiting" << endl;
        }

        else
        {
            cout << "invalid command." << endl;
            cout << "type 'help' to see list of commands" << endl;
        }

    }while (command != "exit");
}

void ConsoleUI::displayListOfPerformers()
{
    displayTopTable();

    vector<Performer> pf = _service.getPerformers();

    for (size_t i = 0; i < pf.size(); ++i)
        {
            if(pf[i].getName().length() > 16)
            {
                cout << i+1 << "\t" << pf[i].getName();
                cout << "\t"  << pf[i].getGender() << "\t" << "\t";
                cout << pf[i].getbYear() << "\t\t\t" << pf[i].getdYear();
                cout << "\t\t\t" << pf[i].getNation() << endl;
            }
            else if(pf[i].getName().length() < 16 && pf[i].getName().length() > 8)
            {
                cout << i+1 << "\t" << pf[i].getName();
                cout << "\t\t"  << pf[i].getGender() << "\t" << "\t";
                cout << pf[i].getbYear() << "\t\t\t" << pf[i].getdYear();
                cout << "\t\t\t" << pf[i].getNation() << endl;
            }
            else if(pf[i].getName().length() <= 8)
            {
                cout << i+1 << "\t" << pf[i].getName();
                cout << "\t\t\t"  << pf[i].getGender() << "\t" << "\t";
                cout << pf[i].getbYear() << "\t\t\t" << pf[i].getdYear();
                cout << "\t\t\t" << pf[i].getNation() << endl;
            }
        }
}

void ConsoleUI::displaySearch()
{
    string input;
    cout << "Enter full name to search for, the search is case-sensitive: ";
    cin.ignore();
    getline(cin, input);

    vector <Performer> newVector = _service.search(input);
    if(newVector.size() == 0)
    {
        cout << "Nothing was found!";
    }
    if(newVector.size() > 0)
    {
        displayTopTable();
    }

    for(size_t i = 0; i < newVector.size(); i++)
    {
        if(newVector[i].getName().length() > 16)
        {
            cout << i+1 << "\t" << newVector[i].getName();
            cout << "\t" << newVector[i].getGender() << "\t" << "\t";
            cout << newVector[i].getbYear() << "\t\t\t" << newVector[i].getdYear();
            cout << "\t\t\t" << newVector[i].getNation() << endl;
        }
        else if(newVector[i].getName().length() < 16 && newVector[i].getName().length() > 8)
        {
            cout << i+1 << "\t" << newVector[i].getName();
            cout << "\t\t" << newVector[i].getGender() << "\t" << "\t";
            cout << newVector[i].getbYear() << "\t\t\t" << newVector[i].getdYear();
            cout << "\t\t\t" << newVector[i].getNation() << endl;
        }
        else if(newVector[i].getName().length() <= 8)
        {
            cout << i+1 << "\t" << newVector[i].getName();
            cout << "\t\t\t" << newVector[i].getGender() << "\t" << "\t";
            cout << newVector[i].getbYear() << "\t\t\t" << newVector[i].getdYear();
            cout << "\t\t\t" << newVector[i].getNation() << endl;
        }
    }

}

void ConsoleUI::displaySort(vector<Performer> newVector)
{
    for(size_t i = 0; i < newVector.size(); i++)
    {
        if(newVector[i].getName().length() > 16)
        {
            cout << i+1 << "\t" << newVector[i].getName();
            cout << "\t" << newVector[i].getGender() << "\t" << "\t";
            cout << newVector[i].getbYear() << "\t\t\t" << newVector[i].getdYear();
            cout << "\t\t\t" << newVector[i].getNation() << endl;
        }
        else if(newVector[i].getName().length() < 16 && newVector[i].getName().length() > 8)
        {
            cout << i+1 << "\t" << newVector[i].getName();
            cout << "\t\t" << newVector[i].getGender() << "\t" << "\t";
            cout << newVector[i].getbYear() << "\t\t\t" << newVector[i].getdYear();
            cout << "\t\t\t" << newVector[i].getNation() << endl;
        }
        else if(newVector[i].getName().length() <= 8)
        {
            cout << i+1 << "\t" << newVector[i].getName();
            cout << "\t\t\t" << newVector[i].getGender() << "\t" << "\t";
            cout << newVector[i].getbYear() << "\t\t\t" << newVector[i].getdYear();
            cout << "\t\t\t" << newVector[i].getNation() << endl;
        }
    }
}
string ConsoleUI::inputName()
{
    string name;
    cin.ignore();
    cout << "Enter full name: ";
    getline(cin, name);

    int nameLength = name.length();

    for(int i = 0;i < nameLength;i++)
     {
        while(!isalpha(name[i]))
               {
                   cout << "Invalid name, try again:";
                    getline(cin, name);
                    nameLength = name.length();
                }
    }
    return name;
}

string ConsoleUI::inputGender()
{
    string gender;
    cout << "Enter gender: ";
    do
    {
        getline(cin, gender);
        if(gender == "Male")
        {
            return gender;
        }
        else if (gender == "male")
        {
            gender = "Male";
            return gender;
        }
        else if(gender == "Female")
        {
            return gender;
        }
        else if (gender == "female")
        {
            gender = "Female";
            return gender;
        }
        else
        {
            cout << "That's not a gender!" << endl;
            cout << "Enter gender: ";
        }
    }while(1 == 1);
    return gender;
}

string ConsoleUI::inputBirth()
{
    string birth;
    cout << "Enter year of birth: ";
    getline(cin, birth);
    int value = atoi(birth.c_str());
    while(value < 0 || value > 2016)
    {
        cout << "That's not a valid year" << endl;
        cout << "Enter year of birth: ";
        getline(cin, birth);
        value = atoi(birth.c_str());
    }
    return birth;
}

string ConsoleUI::inputDeath()
{
    string death;
    cout << "Enter year of death or enter '--' if alive: ";
    getline(cin, death);
    int value = atoi(death.c_str());
    if(death == "--"){
        return death;
    }
    while(value < 0 || value > 2016)
    {
        cout << "That's not a valid year" << endl;
        cout << "Enter year of death: ";
        getline(cin, death);
        value = atoi(death.c_str());
    }

    return death;
}
string ConsoleUI::inputNation()
{
    string nation;
    cout << "Enter Nation: ";
    getline(cin, nation);

    return nation;
}

void ConsoleUI::chooseSort()
{
    int choice;
    cout << "Choose 1 to sort in alphabetical order" << endl;
    cout << "Choose 2 to sort by birth year" << endl;
    cout << "Choose 3 to sort by gender" << endl;
    cout << "Choose 4 to sort by nationality" << endl;
    cout << "Choice: ";
    cin >> choice;

    if(choice == 1)
    {
        vector<Performer> newVector = _service.sortByName();
        cout << endl;
        cout << "              " << "---- List ordered alphabetically by first name ----" << endl;
        cout << endl;
        cout << "Nr" << "\t" << "Name" << "\t\t\t" << "Gender";
        cout << "\t\t" << "Birth year" << "\t\t" << "Deceased" << "\t\t" <<"Nationality" << endl;
        for (int i = 0; i < 54*2; ++i)
        {
            cout << "=";
        }
        cout << endl;
        displaySort(newVector);
    }

    else if(choice == 2)
    {
      cout << endl;
      cout << "                      " << "---- List ordered by birth year ----" << endl;
      cout << endl;
      cout << "Nr" << "\t" << "Name" << "\t\t\t" << "Gender";
      cout << "\t\t" << "Birth year" << "\t\t" << "Deceased" << "\t\t" <<"Nationality" << endl;
      for (int i = 0; i < 54*2; ++i)
      {
          cout << "=";
      }
      cout << endl;
      vector <Performer> newVector = _service.sortBybYear();
      displaySort(newVector);

     }

    else if(choice == 3)
    {
        cout << endl;
        cout << "                       " << "---- List ordered by gender ----" << endl;
        cout << endl;
        cout << "Nr" << "\t" << "Name" << "\t\t\t" << "Gender";
        cout << "\t\t" << "Birth year" << "\t\t" << "Deceased" << "\t\t" <<"Nationality" << endl;
        for (int i = 0; i < 54*2; ++i)
        {
            cout << "=";
        }
        cout << endl;
        vector <Performer> newVector = _service.sortByGender();
        displaySort(newVector);
    }
    else if(choice == 4)
    {
        vector<Performer> newVector = _service.sortByNationality();
        cout << endl;
        cout << "              " << "---- List ordered alphabetically by nationality ----" << endl;
        cout << endl;
        cout << "Nr" << "\t" << "Name" << "\t\t\t" << "Gender";
        cout << "\t\t" << "Birth year" << "\t\t" << "Deceased" << "\t\t" <<"Nationality" << endl;
        for (int i = 0; i < 54*2; ++i)
        {
            cout << "=";
        }
        cout << endl;
        displaySort(newVector);
    }

    else {
        cout << "Invalid choice!";
    }
}

void ConsoleUI::commandHelp()
{
    cout << "list   - This will list all computer scientists in the system" << endl;
    cout << "add    - This will add a new computer scientists" << endl;
    cout << "search - Searches for a given computer scientist" << endl;
    cout << "sort   - Sorts the computer scientists by choice" << endl;
    cout << "help   - Displays list of commands" << endl;
    cout << "exit   - This will close the application" << endl;
}

void ConsoleUI::commandAdd()
{
    string name = inputName();
    string gender = inputGender();
    string birth = inputBirth();
    string death = inputDeath();
    int value = 0;
    int value2 = 0;

    if(death != "--")
    {
    value = atoi(birth.c_str());
    value2 = atoi(death.c_str());
    }
    while(value2 < value)
    {
        cout << "Death year can't be less than birth year!" << endl;
        death = inputDeath();
        if(death == "--")
        {
            break;
        }
        value2 = atoi(death.c_str());

    }
    string nation = inputNation();
    _service.addPerformer(name, gender, birth, death, nation);
    cout << endl;
    cout << name << " has been added to the database!" << endl;
}

void ConsoleUI::intro()
{
    cout << endl;
    cout << "This program is designed to keep track of some details on known computer scientists. " << endl;
    cout << "User is able to enter known characters from the history of computer science into a database." << endl;
    cout << "The program can display a list of the characters that have been entered into the database." << endl;
    cout << "It is also possible to perform a search of a specific person from the list." << endl << endl;
    for (int i = 0; i < 45*2; ++i)
    {
        cout << "=";
    }
    cout << endl;
    cout << endl;
    cout << "Please enter one of the following commands to continue:" << endl;
    cout << endl;
}

void ConsoleUI::displayTopTable()
{
    cout << endl;
    cout << "            " << "---- List of all computer scientists in the system ----" << endl;
    cout << endl;
    cout << "Nr" << "\t" << "Name" << "\t\t\t" << "Gender";
    cout << "\t\t" << "Birth year" << "\t\t" << "Deceased" << "\t\t" <<"Nationality" << endl;
    for (int i = 0; i < 54*2; ++i)
    {
        cout << "=";
    }
    cout << endl;
}
<|endoftext|>


<commit_before>#include "SDLApplication.h"
#include "SDLGamepad.h"

#ifdef HX_MACOS
#include <CoreFoundation/CoreFoundation.h>
#endif

#ifdef EMSCRIPTEN
#include "emscripten.h"
#endif

namespace lime {

	AutoGCRoot* Application::callback = 0;
	SDLApplication* SDLApplication::currentApplication = 0;

	SDLApplication::SDLApplication () {

		if (SDL_Init (SDL_INIT_VIDEO | SDL_INIT_GAMECONTROLLER | SDL_INIT_TIMER) != 0) {

			printf ("Could not initialize SDL: %s.\n", SDL_GetError ());

		}

		currentApplication = this;

		framePeriod = 1000.0 / 60.0;

		#ifdef EMSCRIPTEN
		emscripten_cancel_main_loop ();
		emscripten_set_main_loop (UpdateFrame, 0, 0);
		emscripten_set_main_loop_timing (EM_TIMING_RAF, 1);
		#endif

		currentUpdate = 0;
		lastUpdate = 0;
		nextUpdate = 0;

		GamepadEvent gamepadEvent;
		KeyEvent keyEvent;
		MouseEvent mouseEvent;
		RenderEvent renderEvent;
		TextEvent textEvent;
		TouchEvent touchEvent;
		UpdateEvent updateEvent;
		WindowEvent windowEvent;

		#ifdef HX_MACOS
		CFURLRef resourcesURL = CFBundleCopyResourcesDirectoryURL (CFBundleGetMainBundle ());
		char path[PATH_MAX];

		if (CFURLGetFileSystemRepresentation (resourcesURL, TRUE, (UInt8 *)path, PATH_MAX)) {

			chdir (path);

		}

		CFRelease (resourcesURL);
		#endif

	}

	SDLApplication::~SDLApplication () {

	}

	int SDLApplication::Exec () {

		Init ();

		#ifdef EMSCRIPTEN

		return 0;

		#else

		while (active) {

			Update ();

		}

		return Quit ();

		#endif

	}

	void SDLApplication::HandleEvent (SDL_Event* event) {

		switch (event->type) {

			case SDL_USEREVENT:

				currentUpdate = SDL_GetTicks ();
				updateEvent.deltaTime = currentUpdate - lastUpdate;
				lastUpdate = currentUpdate;

				while (nextUpdate <= currentUpdate) {

					nextUpdate += framePeriod;

				}

				UpdateEvent::Dispatch (&updateEvent);
				RenderEvent::Dispatch (&renderEvent);
				break;

			case SDL_APP_WILLENTERBACKGROUND:

				windowEvent.type = WINDOW_DEACTIVATE;
				WindowEvent::Dispatch (&windowEvent);
				break;

			case SDL_APP_WILLENTERFOREGROUND:

				windowEvent.type = WINDOW_ACTIVATE;
				WindowEvent::Dispatch (&windowEvent);
				break;

			case SDL_CONTROLLERAXISMOTION:
			case SDL_CONTROLLERBUTTONDOWN:
			case SDL_CONTROLLERBUTTONUP:
			case SDL_CONTROLLERDEVICEADDED:
			case SDL_CONTROLLERDEVICEREMOVED:

				ProcessGamepadEvent (event);
				break;

			case SDL_JOYAXISMOTION:
			case SDL_JOYBALLMOTION:
			case SDL_JOYBUTTONDOWN:
			case SDL_JOYBUTTONUP:
			case SDL_JOYHATMOTION:
			case SDL_JOYDEVICEADDED:
			case SDL_JOYDEVICEREMOVED:

				//joy
				break;

			case SDL_KEYDOWN:
			case SDL_KEYUP:

				ProcessKeyEvent (event);
				break;

			case SDL_MOUSEMOTION:
			case SDL_MOUSEBUTTONDOWN:
			case SDL_MOUSEBUTTONUP:
			case SDL_MOUSEWHEEL:

				ProcessMouseEvent (event);
				break;

			case SDL_TEXTINPUT:
			case SDL_TEXTEDITING:

				ProcessTextEvent (event);
				break;

			case SDL_WINDOWEVENT:

				switch (event->window.event) {

					case SDL_WINDOWEVENT_ENTER:
					case SDL_WINDOWEVENT_LEAVE:
					case SDL_WINDOWEVENT_SHOWN:
					case SDL_WINDOWEVENT_HIDDEN:
					case SDL_WINDOWEVENT_FOCUS_GAINED:
					case SDL_WINDOWEVENT_FOCUS_LOST:
					case SDL_WINDOWEVENT_MINIMIZED:
					case SDL_WINDOWEVENT_MOVED:
					case SDL_WINDOWEVENT_RESTORED:

						ProcessWindowEvent (event);
						break;

					case SDL_WINDOWEVENT_EXPOSED:

						RenderEvent::Dispatch (&renderEvent);
						break;

					case SDL_WINDOWEVENT_SIZE_CHANGED:

						ProcessWindowEvent (event);
						RenderEvent::Dispatch (&renderEvent);
						break;

					case SDL_WINDOWEVENT_CLOSE:

						ProcessWindowEvent (event);
						active = false;
						break;

				}

				break;

			case SDL_QUIT:

				//quit
				active = false;
				break;

		}

	}

	void SDLApplication::Init () {

		active = true;
		lastUpdate = SDL_GetTicks ();
		nextUpdate = lastUpdate;

	}

	void SDLApplication::ProcessGamepadEvent (SDL_Event* event) {

		if (GamepadEvent::callback) {

			switch (event->type) {

				case SDL_CONTROLLERAXISMOTION:

					gamepadEvent.type = AXIS_MOVE;
					gamepadEvent.axis = event->caxis.axis;
					gamepadEvent.id = event->caxis.which;
					gamepadEvent.axisValue = event->caxis.value / 32768.0;

					GamepadEvent::Dispatch (&gamepadEvent);
					break;

				case SDL_CONTROLLERBUTTONDOWN:

					gamepadEvent.type = BUTTON_DOWN;
					gamepadEvent.button = event->cbutton.button;
					gamepadEvent.id = event->cbutton.which;

					GamepadEvent::Dispatch (&gamepadEvent);
					break;

				case SDL_CONTROLLERBUTTONUP:

					gamepadEvent.type = BUTTON_UP;
					gamepadEvent.button = event->cbutton.button;
					gamepadEvent.id = event->cbutton.which;

					GamepadEvent::Dispatch (&gamepadEvent);
					break;

				case SDL_CONTROLLERDEVICEADDED:

					if (SDLGamepad::Connect (event->cdevice.which)) {

						gamepadEvent.type = CONNECT;
						gamepadEvent.id = SDLGamepad::GetInstanceID (event->cdevice.which);

						GamepadEvent::Dispatch (&gamepadEvent);

					}

					break;

				case SDL_CONTROLLERDEVICEREMOVED: {

					gamepadEvent.type = DISCONNECT;
					gamepadEvent.id = event->cdevice.which;

					GamepadEvent::Dispatch (&gamepadEvent);
					SDLGamepad::Disconnect (event->cdevice.which);
					break;

				}

			}

		}

	}

	void SDLApplication::ProcessKeyEvent (SDL_Event* event) {

		if (KeyEvent::callback) {

			switch (event->type) {

				case SDL_KEYDOWN: keyEvent.type = KEY_DOWN; break;
				case SDL_KEYUP: keyEvent.type = KEY_UP; break;

			}

			keyEvent.keyCode = event->key.keysym.sym;
			keyEvent.modifier = event->key.keysym.mod;

			KeyEvent::Dispatch (&keyEvent);

		}

	}

	void SDLApplication::ProcessMouseEvent (SDL_Event* event) {

		if (MouseEvent::callback) {

			switch (event->type) {

				case SDL_MOUSEMOTION:

					mouseEvent.type = MOUSE_MOVE;
					mouseEvent.x = event->motion.x;
					mouseEvent.y = event->motion.y;
					mouseEvent.movementX = event->motion.xrel;
					mouseEvent.movementY = event->motion.yrel;
					break;

				case SDL_MOUSEBUTTONDOWN:

					mouseEvent.type = MOUSE_DOWN;
					mouseEvent.button = event->button.button - 1;
					mouseEvent.x = event->button.x;
					mouseEvent.y = event->button.y;
					break;

				case SDL_MOUSEBUTTONUP:

					mouseEvent.type = MOUSE_UP;
					mouseEvent.button = event->button.button - 1;
					mouseEvent.x = event->button.x;
					mouseEvent.y = event->button.y;
					break;

				case SDL_MOUSEWHEEL:

					mouseEvent.type = MOUSE_WHEEL;
					mouseEvent.x = event->wheel.x;
					mouseEvent.y = event->wheel.y;
					break;

			}

			MouseEvent::Dispatch (&mouseEvent);

		}

	}

	void SDLApplication::ProcessTextEvent (SDL_Event* event) {

		if (TextEvent::callback) {

			switch (event->type) {

				case SDL_TEXTINPUT:

					textEvent.type = TEXT_INPUT;
					break;

				case SDL_TEXTEDITING:

					textEvent.type = TEXT_EDIT;
					textEvent.start = event->edit.start;
					textEvent.length = event->edit.length;
					break;

			}

			strcpy (textEvent.text, event->text.text);

			TextEvent::Dispatch (&textEvent);

		}

	}

	void SDLApplication::ProcessTouchEvent (SDL_Event* event) {

	}

	void SDLApplication::ProcessWindowEvent (SDL_Event* event) {

		if (WindowEvent::callback) {

			switch (event->window.event) {

				case SDL_WINDOWEVENT_SHOWN: windowEvent.type = WINDOW_ACTIVATE; break;
				case SDL_WINDOWEVENT_CLOSE: windowEvent.type = WINDOW_CLOSE; break;
				case SDL_WINDOWEVENT_HIDDEN: windowEvent.type = WINDOW_DEACTIVATE; break;
				case SDL_WINDOWEVENT_ENTER: windowEvent.type = WINDOW_ENTER; break;
				case SDL_WINDOWEVENT_FOCUS_GAINED: windowEvent.type = WINDOW_FOCUS_IN; break;
				case SDL_WINDOWEVENT_FOCUS_LOST: windowEvent.type = WINDOW_FOCUS_OUT; break;
				case SDL_WINDOWEVENT_LEAVE: windowEvent.type = WINDOW_LEAVE; break;
				case SDL_WINDOWEVENT_MINIMIZED: windowEvent.type = WINDOW_MINIMIZE; break;

				case SDL_WINDOWEVENT_MOVED:

					windowEvent.type = WINDOW_MOVE;
					windowEvent.x = event->window.data1;
					windowEvent.y = event->window.data2;
					break;

				case SDL_WINDOWEVENT_SIZE_CHANGED:

					windowEvent.type = WINDOW_RESIZE;
					windowEvent.width = event->window.data1;
					windowEvent.height = event->window.data2;
					break;

				case SDL_WINDOWEVENT_RESTORED: windowEvent.type = WINDOW_RESTORE; break;

			}

			WindowEvent::Dispatch (&windowEvent);

		}

	}

	int SDLApplication::Quit () {

		windowEvent.type = WINDOW_DEACTIVATE;
		WindowEvent::Dispatch (&windowEvent);

		SDL_Quit ();

		return 0;

	}

	void SDLApplication::RegisterWindow (SDLWindow *window) {

		#ifdef IPHONE
		SDL_iPhoneSetAnimationCallback (window->sdlWindow, 1, UpdateFrame, NULL);
		#endif

	}

	void SDLApplication::SetFrameRate (double frameRate) {

		if (frameRate > 0) {

			framePeriod = 1000.0 / frameRate;

		} else {

			framePeriod = 1000.0;

		}

	}

	static SDL_TimerID timerID = 0;
	bool timerActive = false;
	bool firstTime = true;

	Uint32 OnTimer (Uint32 interval, void *) {

		SDL_Event event;
		SDL_UserEvent userevent;
		userevent.type = SDL_USEREVENT;
		userevent.code = 0;
		userevent.data1 = NULL;
		userevent.data2 = NULL;
		event.type = SDL_USEREVENT;
		event.user = userevent;

		timerActive = false;
		timerID = 0;

		SDL_PushEvent (&event);

		return 0;

	}

	bool SDLApplication::Update () {

		SDL_Event event;
		event.type = -1;

		#if (!defined (IPHONE) && !defined (EMSCRIPTEN))

		if (active && (firstTime || SDL_WaitEvent (&event))) {

			firstTime = false;

			HandleEvent (&event);
			event.type = -1;
			if (!active)
				return active;

		#endif

			while (SDL_PollEvent (&event)) {

				HandleEvent (&event);
				event.type = -1;
				if (!active)
					return active;

			}

			currentUpdate = SDL_GetTicks ();

		#if defined (IPHONE)

			if (currentUpdate >= nextUpdate) {

				event.type = SDL_USEREVENT;
				HandleEvent (&event);
				event.type = -1;

			}

		#elif defined (EMSCRIPTEN)

			event.type = SDL_USEREVENT;
			HandleEvent (&event);
			event.type = -1;

		#else

			if (currentUpdate >= nextUpdate) {

				SDL_RemoveTimer (timerID);
				OnTimer (0, 0);

			} else if (!timerActive) {

				timerActive = true;
				timerID = SDL_AddTimer (nextUpdate - currentUpdate, OnTimer, 0);

			}

		}

		#endif

		return active;

	}

	void SDLApplication::UpdateFrame () {

		currentApplication->Update ();

	}

	void SDLApplication::UpdateFrame (void*) {

		UpdateFrame ();

	}

	Application* CreateApplication () {

		return new SDLApplication ();

	}

}

#ifdef ANDROID
int SDL_main (int argc, char *argv[]) { return 0; }
#endif<commit_msg>Implement touch support in SDLApplication<commit_after>#include "SDLApplication.h"
#include "SDLGamepad.h"

#ifdef HX_MACOS
#include <CoreFoundation/CoreFoundation.h>
#endif

#ifdef EMSCRIPTEN
#include "emscripten.h"
#endif

namespace lime {

	AutoGCRoot* Application::callback = 0;
	SDLApplication* SDLApplication::currentApplication = 0;

	SDLApplication::SDLApplication () {

		if (SDL_Init (SDL_INIT_VIDEO | SDL_INIT_GAMECONTROLLER | SDL_INIT_TIMER) != 0) {

			printf ("Could not initialize SDL: %s.\n", SDL_GetError ());

		}

		currentApplication = this;

		framePeriod = 1000.0 / 60.0;

		#ifdef EMSCRIPTEN
		emscripten_cancel_main_loop ();
		emscripten_set_main_loop (UpdateFrame, 0, 0);
		emscripten_set_main_loop_timing (EM_TIMING_RAF, 1);
		#endif

		currentUpdate = 0;
		lastUpdate = 0;
		nextUpdate = 0;

		GamepadEvent gamepadEvent;
		KeyEvent keyEvent;
		MouseEvent mouseEvent;
		RenderEvent renderEvent;
		TextEvent textEvent;
		TouchEvent touchEvent;
		UpdateEvent updateEvent;
		WindowEvent windowEvent;

		#ifdef HX_MACOS
		CFURLRef resourcesURL = CFBundleCopyResourcesDirectoryURL (CFBundleGetMainBundle ());
		char path[PATH_MAX];

		if (CFURLGetFileSystemRepresentation (resourcesURL, TRUE, (UInt8 *)path, PATH_MAX)) {

			chdir (path);

		}

		CFRelease (resourcesURL);
		#endif

	}

	SDLApplication::~SDLApplication () {

	}

	int SDLApplication::Exec () {

		Init ();

		#ifdef EMSCRIPTEN

		return 0;

		#else

		while (active) {

			Update ();

		}

		return Quit ();

		#endif

	}

	void SDLApplication::HandleEvent (SDL_Event* event) {

		switch (event->type) {

			case SDL_USEREVENT:

				currentUpdate = SDL_GetTicks ();
				updateEvent.deltaTime = currentUpdate - lastUpdate;
				lastUpdate = currentUpdate;

				while (nextUpdate <= currentUpdate) {

					nextUpdate += framePeriod;

				}

				UpdateEvent::Dispatch (&updateEvent);
				RenderEvent::Dispatch (&renderEvent);
				break;

			case SDL_APP_WILLENTERBACKGROUND:

				windowEvent.type = WINDOW_DEACTIVATE;
				WindowEvent::Dispatch (&windowEvent);
				break;

			case SDL_APP_WILLENTERFOREGROUND:

				windowEvent.type = WINDOW_ACTIVATE;
				WindowEvent::Dispatch (&windowEvent);
				break;

			case SDL_CONTROLLERAXISMOTION:
			case SDL_CONTROLLERBUTTONDOWN:
			case SDL_CONTROLLERBUTTONUP:
			case SDL_CONTROLLERDEVICEADDED:
			case SDL_CONTROLLERDEVICEREMOVED:

				ProcessGamepadEvent (event);
				break;

			case SDL_JOYAXISMOTION:
			case SDL_JOYBALLMOTION:
			case SDL_JOYBUTTONDOWN:
			case SDL_JOYBUTTONUP:
			case SDL_JOYHATMOTION:
			case SDL_JOYDEVICEADDED:
			case SDL_JOYDEVICEREMOVED:

				//joy
				break;

			case SDL_KEYDOWN:
			case SDL_KEYUP:

				ProcessKeyEvent (event);
				break;

			case SDL_MOUSEMOTION:
			case SDL_MOUSEBUTTONDOWN:
			case SDL_MOUSEBUTTONUP:
			case SDL_MOUSEWHEEL:

				ProcessMouseEvent (event);
				break;

			case SDL_FINGERMOTION:
			case SDL_FINGERDOWN:
			case SDL_FINGERUP:

				ProcessTouchEvent (event);
				break;

			case SDL_TEXTINPUT:
			case SDL_TEXTEDITING:

				ProcessTextEvent (event);
				break;

			case SDL_WINDOWEVENT:

				switch (event->window.event) {

					case SDL_WINDOWEVENT_ENTER:
					case SDL_WINDOWEVENT_LEAVE:
					case SDL_WINDOWEVENT_SHOWN:
					case SDL_WINDOWEVENT_HIDDEN:
					case SDL_WINDOWEVENT_FOCUS_GAINED:
					case SDL_WINDOWEVENT_FOCUS_LOST:
					case SDL_WINDOWEVENT_MINIMIZED:
					case SDL_WINDOWEVENT_MOVED:
					case SDL_WINDOWEVENT_RESTORED:

						ProcessWindowEvent (event);
						break;

					case SDL_WINDOWEVENT_EXPOSED:

						RenderEvent::Dispatch (&renderEvent);
						break;

					case SDL_WINDOWEVENT_SIZE_CHANGED:

						ProcessWindowEvent (event);
						RenderEvent::Dispatch (&renderEvent);
						break;

					case SDL_WINDOWEVENT_CLOSE:

						ProcessWindowEvent (event);
						active = false;
						break;

				}

				break;

			case SDL_QUIT:

				//quit
				active = false;
				break;

		}

	}

	void SDLApplication::Init () {

		active = true;
		lastUpdate = SDL_GetTicks ();
		nextUpdate = lastUpdate;

	}

	void SDLApplication::ProcessGamepadEvent (SDL_Event* event) {

		if (GamepadEvent::callback) {

			switch (event->type) {

				case SDL_CONTROLLERAXISMOTION:

					gamepadEvent.type = AXIS_MOVE;
					gamepadEvent.axis = event->caxis.axis;
					gamepadEvent.id = event->caxis.which;
					gamepadEvent.axisValue = event->caxis.value / 32768.0;

					GamepadEvent::Dispatch (&gamepadEvent);
					break;

				case SDL_CONTROLLERBUTTONDOWN:

					gamepadEvent.type = BUTTON_DOWN;
					gamepadEvent.button = event->cbutton.button;
					gamepadEvent.id = event->cbutton.which;

					GamepadEvent::Dispatch (&gamepadEvent);
					break;

				case SDL_CONTROLLERBUTTONUP:

					gamepadEvent.type = BUTTON_UP;
					gamepadEvent.button = event->cbutton.button;
					gamepadEvent.id = event->cbutton.which;

					GamepadEvent::Dispatch (&gamepadEvent);
					break;

				case SDL_CONTROLLERDEVICEADDED:

					if (SDLGamepad::Connect (event->cdevice.which)) {

						gamepadEvent.type = CONNECT;
						gamepadEvent.id = SDLGamepad::GetInstanceID (event->cdevice.which);

						GamepadEvent::Dispatch (&gamepadEvent);

					}

					break;

				case SDL_CONTROLLERDEVICEREMOVED: {

					gamepadEvent.type = DISCONNECT;
					gamepadEvent.id = event->cdevice.which;

					GamepadEvent::Dispatch (&gamepadEvent);
					SDLGamepad::Disconnect (event->cdevice.which);
					break;

				}

			}

		}

	}

	void SDLApplication::ProcessKeyEvent (SDL_Event* event) {

		if (KeyEvent::callback) {

			switch (event->type) {

				case SDL_KEYDOWN: keyEvent.type = KEY_DOWN; break;
				case SDL_KEYUP: keyEvent.type = KEY_UP; break;

			}

			keyEvent.keyCode = event->key.keysym.sym;
			keyEvent.modifier = event->key.keysym.mod;

			KeyEvent::Dispatch (&keyEvent);

		}

	}

	void SDLApplication::ProcessMouseEvent (SDL_Event* event) {

		if (MouseEvent::callback) {

			switch (event->type) {

				case SDL_MOUSEMOTION:

					mouseEvent.type = MOUSE_MOVE;
					mouseEvent.x = event->motion.x;
					mouseEvent.y = event->motion.y;
					mouseEvent.movementX = event->motion.xrel;
					mouseEvent.movementY = event->motion.yrel;
					break;

				case SDL_MOUSEBUTTONDOWN:

					mouseEvent.type = MOUSE_DOWN;
					mouseEvent.button = event->button.button - 1;
					mouseEvent.x = event->button.x;
					mouseEvent.y = event->button.y;
					break;

				case SDL_MOUSEBUTTONUP:

					mouseEvent.type = MOUSE_UP;
					mouseEvent.button = event->button.button - 1;
					mouseEvent.x = event->button.x;
					mouseEvent.y = event->button.y;
					break;

				case SDL_MOUSEWHEEL:

					mouseEvent.type = MOUSE_WHEEL;
					mouseEvent.x = event->wheel.x;
					mouseEvent.y = event->wheel.y;
					break;

			}

			MouseEvent::Dispatch (&mouseEvent);

		}

	}

	void SDLApplication::ProcessTextEvent (SDL_Event* event) {

		if (TextEvent::callback) {

			switch (event->type) {

				case SDL_TEXTINPUT:

					textEvent.type = TEXT_INPUT;
					break;

				case SDL_TEXTEDITING:

					textEvent.type = TEXT_EDIT;
					textEvent.start = event->edit.start;
					textEvent.length = event->edit.length;
					break;

			}

			strcpy (textEvent.text, event->text.text);

			TextEvent::Dispatch (&textEvent);

		}

	}

	void SDLApplication::ProcessTouchEvent (SDL_Event* event) {

		if (TouchEvent::callback) {

			switch (event->type) {
				case SDL_FINGERMOTION:

					touchEvent.type = TOUCH_MOVE;
					touchEvent.x = event->tfinger.x;
					touchEvent.y = event->tfinger.y;
					touchEvent.id = event->tfinger.fingerId;
					break;

				case SDL_FINGERDOWN:

					touchEvent.type = TOUCH_START;
					touchEvent.x = event->tfinger.x;
					touchEvent.y = event->tfinger.y;
					touchEvent.id = event->tfinger.fingerId;
					break;

				case SDL_FINGERUP:

					touchEvent.type = TOUCH_END;
					touchEvent.x = event->tfinger.x;
					touchEvent.y = event->tfinger.y;
					touchEvent.id = event->tfinger.fingerId;
					break;
			}

			TouchEvent::Dispatch (&touchEvent);

		}

	}

	void SDLApplication::ProcessWindowEvent (SDL_Event* event) {

		if (WindowEvent::callback) {

			switch (event->window.event) {

				case SDL_WINDOWEVENT_SHOWN: windowEvent.type = WINDOW_ACTIVATE; break;
				case SDL_WINDOWEVENT_CLOSE: windowEvent.type = WINDOW_CLOSE; break;
				case SDL_WINDOWEVENT_HIDDEN: windowEvent.type = WINDOW_DEACTIVATE; break;
				case SDL_WINDOWEVENT_ENTER: windowEvent.type = WINDOW_ENTER; break;
				case SDL_WINDOWEVENT_FOCUS_GAINED: windowEvent.type = WINDOW_FOCUS_IN; break;
				case SDL_WINDOWEVENT_FOCUS_LOST: windowEvent.type = WINDOW_FOCUS_OUT; break;
				case SDL_WINDOWEVENT_LEAVE: windowEvent.type = WINDOW_LEAVE; break;
				case SDL_WINDOWEVENT_MINIMIZED: windowEvent.type = WINDOW_MINIMIZE; break;

				case SDL_WINDOWEVENT_MOVED:

					windowEvent.type = WINDOW_MOVE;
					windowEvent.x = event->window.data1;
					windowEvent.y = event->window.data2;
					break;

				case SDL_WINDOWEVENT_SIZE_CHANGED:

					windowEvent.type = WINDOW_RESIZE;
					windowEvent.width = event->window.data1;
					windowEvent.height = event->window.data2;
					break;

				case SDL_WINDOWEVENT_RESTORED: windowEvent.type = WINDOW_RESTORE; break;

			}

			WindowEvent::Dispatch (&windowEvent);

		}

	}

	int SDLApplication::Quit () {

		windowEvent.type = WINDOW_DEACTIVATE;
		WindowEvent::Dispatch (&windowEvent);

		SDL_Quit ();

		return 0;

	}

	void SDLApplication::RegisterWindow (SDLWindow *window) {

		#ifdef IPHONE
		SDL_iPhoneSetAnimationCallback (window->sdlWindow, 1, UpdateFrame, NULL);
		#endif

	}

	void SDLApplication::SetFrameRate (double frameRate) {

		if (frameRate > 0) {

			framePeriod = 1000.0 / frameRate;

		} else {

			framePeriod = 1000.0;

		}

	}

	static SDL_TimerID timerID = 0;
	bool timerActive = false;
	bool firstTime = true;

	Uint32 OnTimer (Uint32 interval, void *) {

		SDL_Event event;
		SDL_UserEvent userevent;
		userevent.type = SDL_USEREVENT;
		userevent.code = 0;
		userevent.data1 = NULL;
		userevent.data2 = NULL;
		event.type = SDL_USEREVENT;
		event.user = userevent;

		timerActive = false;
		timerID = 0;

		SDL_PushEvent (&event);

		return 0;

	}

	bool SDLApplication::Update () {

		SDL_Event event;
		event.type = -1;

		#if (!defined (IPHONE) && !defined (EMSCRIPTEN))

		if (active && (firstTime || SDL_WaitEvent (&event))) {

			firstTime = false;

			HandleEvent (&event);
			event.type = -1;
			if (!active)
				return active;

		#endif

			while (SDL_PollEvent (&event)) {

				HandleEvent (&event);
				event.type = -1;
				if (!active)
					return active;

			}

			currentUpdate = SDL_GetTicks ();

		#if defined (IPHONE)

			if (currentUpdate >= nextUpdate) {

				event.type = SDL_USEREVENT;
				HandleEvent (&event);
				event.type = -1;

			}

		#elif defined (EMSCRIPTEN)

			event.type = SDL_USEREVENT;
			HandleEvent (&event);
			event.type = -1;

		#else

			if (currentUpdate >= nextUpdate) {

				SDL_RemoveTimer (timerID);
				OnTimer (0, 0);

			} else if (!timerActive) {

				timerActive = true;
				timerID = SDL_AddTimer (nextUpdate - currentUpdate, OnTimer, 0);

			}

		}

		#endif

		return active;

	}

	void SDLApplication::UpdateFrame () {

		currentApplication->Update ();

	}

	void SDLApplication::UpdateFrame (void*) {

		UpdateFrame ();

	}

	Application* CreateApplication () {

		return new SDLApplication ();

	}

}

#ifdef ANDROID
int SDL_main (int argc, char *argv[]) { return 0; }
#endif
<|endoftext|>


<commit_before>/**
 * @file lrsdp_function.cpp
 * @author Ryan Curtin
 * @author Abhishek Laddha
 *
 * Implementation of the LRSDPFunction class, and also template specializations
 * for faster execution with the AugLagrangian optimizer.
 */
#include "lrsdp_function.hpp"

using namespace mlpack;
using namespace mlpack::optimization;
using namespace std;

LRSDPFunction::LRSDPFunction(const size_t numSparseConstraints,
                             const size_t numDenseConstraints,
                             const arma::mat& initialPoint):
    sparseC(initialPoint.n_rows, initialPoint.n_rows),
    denseC(initialPoint.n_rows, initialPoint.n_rows),
    hasModifiedSparseObjective(false),
    hasModifiedDenseObjective(false),
    sparseA(numSparseConstraints),
    sparseB(numSparseConstraints),
    denseA(numDenseConstraints),
    denseB(numDenseConstraints),
    initialPoint(initialPoint)
{
  denseC.zeros();
  if (initialPoint.n_rows < initialPoint.n_cols)
    Log::Warn << "LRSDPFunction::LRSDPFunction(): solution matrix will have "
        << "more columns than rows.  It may be more efficient to find the "
        << "transposed solution." << endl;
}

double LRSDPFunction::Evaluate(const arma::mat& coordinates) const
{
  return -accu(coordinates * trans(coordinates));
}

void LRSDPFunction::Gradient(const arma::mat& /* coordinates */,
                     arma::mat& /* gradient */) const
{
  Log::Fatal << "LRSDP::Gradient() not implemented for arbitrary optimizers!"
      << std::endl;
}

double LRSDPFunction::EvaluateConstraint(const size_t index,
                                 const arma::mat& coordinates) const
{
  const arma::mat rrt = coordinates * trans(coordinates);
  if (index < NumSparseConstraints())
    return trace(sparseA[index] * rrt) - sparseB[index];
  const size_t index1 = index - NumSparseConstraints();
  return trace(denseA[index1] * rrt) - denseB[index1];
}

void LRSDPFunction::GradientConstraint(const size_t /* index */,
                               const arma::mat& /* coordinates */,
                               arma::mat& /* gradient */) const
{
  Log::Fatal << "LRSDP::GradientConstraint() not implemented for arbitrary "
      << "optimizers!" << std::endl;
}

// Return a string representation of the object.
std::string LRSDPFunction::ToString() const
{
  std::ostringstream convert;
  convert << "LRSDPFunction [" << this << "]" << std::endl;
  convert << "  Number of constraints: " << NumConstraints() << std::endl;
  convert << "  Problem size: n=" << initialPoint.n_rows << ", r="
      << initialPoint.n_cols << std::endl;
  convert << "  Sparse Constraint b_i values: " << sparseB.t();
  convert << "  Dense Constraint b_i values: " << denseB.t();
  return convert.str();
}

namespace mlpack {
namespace optimization {

//! Utility function for calculating part of the objective when AugLagrangian is
//! used with an LRSDPFunction.
template <typename MatrixType>
static inline void
UpdateObjective(double& objective,
                const arma::mat& rrt,
                const std::vector<MatrixType>& ais,
                const arma::vec& bis,
                const arma::vec& lambda,
                const size_t lambdaOffset,
                const double sigma)
{
  for (size_t i = 0; i < ais.size(); ++i)
  {
    // Take the trace subtracted by the b_i.
    const double constraint = trace(ais[i] * rrt) - bis[i];
    objective -= (lambda[lambdaOffset + i] * constraint);
    objective += (sigma / 2.) * constraint * constraint;
  }
}

//! Utility function for calculating part of the gradient when AugLagrangian is
//! used with an LRSDPFunction.
template <typename MatrixType>
static inline void
UpdateGradient(arma::mat& s,
               const arma::mat& rrt,
               const std::vector<MatrixType>& ais,
               const arma::vec& bis,
               const arma::vec& lambda,
               const size_t lambdaOffset,
               const double sigma)
{
  for (size_t i = 0; i < ais.size(); ++i)
  {
    const double constraint = trace(ais[i] * rrt) - bis[i];
    const double y = lambda[lambdaOffset + i] - sigma * constraint;
    s -= y * ais[i];
  }
}

// Template specializations for function and gradient evaluation.
template<>
double AugLagrangianFunction<LRSDPFunction>::Evaluate(
    const arma::mat& coordinates) const
{
  // We can calculate the entire objective in a smart way.
  // L(R, y, s) = Tr(C * (R R^T)) -
  //     sum_{i = 1}^{m} (y_i (Tr(A_i * (R R^T)) - b_i)) +
  //     (sigma / 2) * sum_{i = 1}^{m} (Tr(A_i * (R R^T)) - b_i)^2

  // Let's start with the objective: Tr(C * (R R^T)).
  // Simple, possibly slow solution-- see below for optimization opportunity
  //
  // TODO: Note that Tr(C^T * (R R^T)) = Tr( (CR)^T * R ), so
  // multiplying C*R first, and then taking the trace dot should be more memory
  // efficient
  //
  // Similarly for the constraints, taking A*R first should be more efficient
  const arma::mat rrt = coordinates * trans(coordinates);
  double objective = 0.;
  if (function.hasSparseObjective())
    objective += trace(function.SparseC() * rrt);
  if (function.hasDenseObjective())
    objective += trace(function.DenseC() * rrt);

  // Now each constraint.
  UpdateObjective(objective, rrt, function.SparseA(), function.SparseB(),
      lambda, 0, sigma);
  UpdateObjective(objective, rrt, function.DenseA(), function.DenseB(), lambda,
      function.NumSparseConstraints(), sigma);

  return objective;
}

template<>
void AugLagrangianFunction<LRSDPFunction>::Gradient(
    const arma::mat& coordinates,
    arma::mat& gradient) const
{
  // We can calculate the gradient in a smart way.
  // L'(R, y, s) = 2 * S' * R
  //   with
  // S' = C - sum_{i = 1}^{m} y'_i A_i
  // y'_i = y_i - sigma * (Trace(A_i * (R R^T)) - b_i)
  const arma::mat rrt = coordinates * trans(coordinates);
  arma::mat s(function.n(), function.n());
  s.zeros();

  if (function.hasSparseObjective())
    s += function.SparseC();
  if (function.hasDenseObjective())
    s += function.DenseC();

  UpdateGradient(
      s, rrt, function.SparseA(), function.SparseB(),
      lambda, 0, sigma);
  UpdateGradient(
      s, rrt, function.DenseA(), function.DenseB(),
      lambda, function.NumSparseConstraints(), sigma);

  gradient = 2 * s * coordinates;
}

}; // namespace optimization
}; // namespace mlpack
<commit_msg>don't hardcore Evaluate for the lovasz theta objective function<commit_after>/**
 * @file lrsdp_function.cpp
 * @author Ryan Curtin
 * @author Abhishek Laddha
 *
 * Implementation of the LRSDPFunction class, and also template specializations
 * for faster execution with the AugLagrangian optimizer.
 */
#include "lrsdp_function.hpp"

using namespace mlpack;
using namespace mlpack::optimization;
using namespace std;

LRSDPFunction::LRSDPFunction(const size_t numSparseConstraints,
                             const size_t numDenseConstraints,
                             const arma::mat& initialPoint):
    sparseC(initialPoint.n_rows, initialPoint.n_rows),
    denseC(initialPoint.n_rows, initialPoint.n_rows),
    hasModifiedSparseObjective(false),
    hasModifiedDenseObjective(false),
    sparseA(numSparseConstraints),
    sparseB(numSparseConstraints),
    denseA(numDenseConstraints),
    denseB(numDenseConstraints),
    initialPoint(initialPoint)
{
  denseC.zeros();
  if (initialPoint.n_rows < initialPoint.n_cols)
    Log::Warn << "LRSDPFunction::LRSDPFunction(): solution matrix will have "
        << "more columns than rows.  It may be more efficient to find the "
        << "transposed solution." << endl;
}

double LRSDPFunction::Evaluate(const arma::mat& coordinates) const
{
  const arma::mat rrt = coordinates * trans(coordinates);
  double objective = 0.;
  if (hasSparseObjective())
    objective += trace(SparseC() * rrt);
  if (hasDenseObjective())
    objective += trace(DenseC() * rrt);
  return objective;
}

void LRSDPFunction::Gradient(const arma::mat& /* coordinates */,
                     arma::mat& /* gradient */) const
{
  Log::Fatal << "LRSDP::Gradient() not implemented for arbitrary optimizers!"
      << std::endl;
}

double LRSDPFunction::EvaluateConstraint(const size_t index,
                                 const arma::mat& coordinates) const
{
  const arma::mat rrt = coordinates * trans(coordinates);
  if (index < NumSparseConstraints())
    return trace(sparseA[index] * rrt) - sparseB[index];
  const size_t index1 = index - NumSparseConstraints();
  return trace(denseA[index1] * rrt) - denseB[index1];
}

void LRSDPFunction::GradientConstraint(const size_t /* index */,
                               const arma::mat& /* coordinates */,
                               arma::mat& /* gradient */) const
{
  Log::Fatal << "LRSDP::GradientConstraint() not implemented for arbitrary "
      << "optimizers!" << std::endl;
}

// Return a string representation of the object.
std::string LRSDPFunction::ToString() const
{
  std::ostringstream convert;
  convert << "LRSDPFunction [" << this << "]" << std::endl;
  convert << "  Number of constraints: " << NumConstraints() << std::endl;
  convert << "  Problem size: n=" << initialPoint.n_rows << ", r="
      << initialPoint.n_cols << std::endl;
  convert << "  Sparse Constraint b_i values: " << sparseB.t();
  convert << "  Dense Constraint b_i values: " << denseB.t();
  return convert.str();
}

namespace mlpack {
namespace optimization {

//! Utility function for calculating part of the objective when AugLagrangian is
//! used with an LRSDPFunction.
template <typename MatrixType>
static inline void
UpdateObjective(double& objective,
                const arma::mat& rrt,
                const std::vector<MatrixType>& ais,
                const arma::vec& bis,
                const arma::vec& lambda,
                const size_t lambdaOffset,
                const double sigma)
{
  for (size_t i = 0; i < ais.size(); ++i)
  {
    // Take the trace subtracted by the b_i.
    const double constraint = trace(ais[i] * rrt) - bis[i];
    objective -= (lambda[lambdaOffset + i] * constraint);
    objective += (sigma / 2.) * constraint * constraint;
  }
}

//! Utility function for calculating part of the gradient when AugLagrangian is
//! used with an LRSDPFunction.
template <typename MatrixType>
static inline void
UpdateGradient(arma::mat& s,
               const arma::mat& rrt,
               const std::vector<MatrixType>& ais,
               const arma::vec& bis,
               const arma::vec& lambda,
               const size_t lambdaOffset,
               const double sigma)
{
  for (size_t i = 0; i < ais.size(); ++i)
  {
    const double constraint = trace(ais[i] * rrt) - bis[i];
    const double y = lambda[lambdaOffset + i] - sigma * constraint;
    s -= y * ais[i];
  }
}

// Template specializations for function and gradient evaluation.
template<>
double AugLagrangianFunction<LRSDPFunction>::Evaluate(
    const arma::mat& coordinates) const
{
  // We can calculate the entire objective in a smart way.
  // L(R, y, s) = Tr(C * (R R^T)) -
  //     sum_{i = 1}^{m} (y_i (Tr(A_i * (R R^T)) - b_i)) +
  //     (sigma / 2) * sum_{i = 1}^{m} (Tr(A_i * (R R^T)) - b_i)^2

  // Let's start with the objective: Tr(C * (R R^T)).
  // Simple, possibly slow solution-- see below for optimization opportunity
  //
  // TODO: Note that Tr(C^T * (R R^T)) = Tr( (CR)^T * R ), so
  // multiplying C*R first, and then taking the trace dot should be more memory
  // efficient
  //
  // Similarly for the constraints, taking A*R first should be more efficient
  const arma::mat rrt = coordinates * trans(coordinates);
  double objective = 0.;
  if (function.hasSparseObjective())
    objective += trace(function.SparseC() * rrt);
  if (function.hasDenseObjective())
    objective += trace(function.DenseC() * rrt);

  // Now each constraint.
  UpdateObjective(objective, rrt, function.SparseA(), function.SparseB(),
      lambda, 0, sigma);
  UpdateObjective(objective, rrt, function.DenseA(), function.DenseB(), lambda,
      function.NumSparseConstraints(), sigma);

  return objective;
}

template<>
void AugLagrangianFunction<LRSDPFunction>::Gradient(
    const arma::mat& coordinates,
    arma::mat& gradient) const
{
  // We can calculate the gradient in a smart way.
  // L'(R, y, s) = 2 * S' * R
  //   with
  // S' = C - sum_{i = 1}^{m} y'_i A_i
  // y'_i = y_i - sigma * (Trace(A_i * (R R^T)) - b_i)
  const arma::mat rrt = coordinates * trans(coordinates);
  arma::mat s(function.n(), function.n());
  s.zeros();

  if (function.hasSparseObjective())
    s += function.SparseC();
  if (function.hasDenseObjective())
    s += function.DenseC();

  UpdateGradient(
      s, rrt, function.SparseA(), function.SparseB(),
      lambda, 0, sigma);
  UpdateGradient(
      s, rrt, function.DenseA(), function.DenseB(),
      lambda, function.NumSparseConstraints(), sigma);

  gradient = 2 * s * coordinates;
}

}; // namespace optimization
}; // namespace mlpack
<|endoftext|>


<commit_before>/***************************************************************************
**
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (directui@nokia.com)
**
** This file is part of libmeegotouch.
**
** If you have questions regarding the use of this file, please contact
** Nokia at directui@nokia.com.
**
** This library is free software; you can redistribute it and/or
** modify it under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation
** and appearing in the file LICENSE.LGPL included in the packaging
** of this file.
**
****************************************************************************/

#include <QPainter>
#include <QPropertyAnimation>

#include "mspinnerview.h"
#include "mspinnerview_p.h"

#include "mprogressindicator.h"

#include "mtheme.h"

MSpinnerViewPrivate::MSpinnerViewPrivate()
    :  q_ptr(NULL),
       controller(NULL),
       positionAnimation(NULL),
       currentFrame(0)
{
}

MSpinnerViewPrivate::~MSpinnerViewPrivate()
{
    delete positionAnimation;
    releaseUsedPixmaps();
}

QPropertyAnimation *MSpinnerViewPrivate::createAnimation()
{
    Q_Q(MSpinnerView);

    QPropertyAnimation *animation = new QPropertyAnimation(q, "currentFrame", q);
    animation->setLoopCount(-1);

    return animation;
}

void MSpinnerViewPrivate::refreshStyle()
{
    Q_Q(MSpinnerView);

    positionAnimation->setDuration(q->style()->period());
    positionAnimation->setStartValue(0);
    positionAnimation->setEndValue(q->style()->numberOfFrames());
    reloadFrames();
}

void MSpinnerViewPrivate::refreshModel()
{
    Q_Q(MSpinnerView);

    if (q->model()->unknownDuration()) {
        if (positionAnimation->state() == QPropertyAnimation::Paused)
            positionAnimation->resume();
        else
            positionAnimation->start();
    } else {
        if (positionAnimation->state() == QPropertyAnimation::Running)
            positionAnimation->pause();
    }
}

void MSpinnerViewPrivate::reloadFrames()
{
    Q_Q(MSpinnerView);

    releaseUsedPixmaps();
    // Starts from 1 because that's the agreed convention
    // for the image file names
    for (int i = 1; i <= q->style()->numberOfFrames(); i++) {
        QString frame_name = QString("%1_%2_%3").arg(q->style()->baseImageName())\
                                                .arg(q->style()->baseImageSize())\
                                                .arg(i);
        const QPixmap *p = MTheme::pixmap(frame_name);
        animationPixmaps << p;
    }
}

void MSpinnerViewPrivate::releaseUsedPixmaps()
{
    foreach(const QPixmap *p, animationPixmaps)
        MTheme::releasePixmap(p);
    animationPixmaps.clear();
}

void MSpinnerViewPrivate::_q_resumeAnimation()
{
    Q_Q(MSpinnerView);

    if (q->model()->unknownDuration()) {
        if (positionAnimation->state() == QPropertyAnimation::Paused)
            positionAnimation->resume();
    }
}

void MSpinnerViewPrivate::_q_pauseAnimation()
{
    if (positionAnimation->state() == QPropertyAnimation::Running)
        positionAnimation->pause();
}

void MSpinnerViewPrivate::_q_pauseOrResumeAnimation()
{
    if (controller->isVisible() && controller->isOnDisplay())
        _q_resumeAnimation();
    else
        _q_pauseAnimation();
}

MSpinnerView::MSpinnerView(MProgressIndicator *controller) :
    MWidgetView(controller),
    d_ptr(new MSpinnerViewPrivate)
{
    Q_D(MSpinnerView);
    d->q_ptr = this;
    d->controller = controller;
    d->positionAnimation = d->createAnimation();

    connect(controller, SIGNAL(visibleChanged()), this, SLOT(_q_pauseOrResumeAnimation()));

    connect(controller, SIGNAL(displayEntered()), this, SLOT(_q_pauseOrResumeAnimation()));
    connect(controller, SIGNAL(displayExited()), this, SLOT(_q_pauseOrResumeAnimation()));
}

MSpinnerView::~MSpinnerView()
{
    delete d_ptr;
}

int MSpinnerView::currentFrame() const
{
    Q_D(const MSpinnerView);

    return d->currentFrame;
}

void MSpinnerView::setCurrentFrame(int currentFrame)
{
    Q_D(MSpinnerView);

    if (currentFrame >= d->animationPixmaps.length())
        currentFrame %= d->animationPixmaps.length();

    d->currentFrame = currentFrame;
    update();
}

void MSpinnerView::updateData(const QList<const char *>& modifications)
{
    Q_D(MSpinnerView);
    MWidgetView::updateData(modifications);

    foreach(const char * member, modifications) {
        if (member == MProgressIndicatorModel::UnknownDuration)
            d->refreshModel();
    }
    update();
}

void MSpinnerView::applyStyle()
{
    Q_D(MSpinnerView);
    MWidgetView::applyStyle();

    d->refreshStyle();
}

void MSpinnerView::setupModel()
{
    Q_D(MSpinnerView);
    MWidgetView::setupModel();

    d->refreshModel();
}

void MSpinnerView::drawContents(QPainter *painter, const QStyleOptionGraphicsItem *option) const
{
    Q_UNUSED(option);
    Q_D(const MSpinnerView);

    if (d->animationPixmaps.isEmpty())
        return;

    const QPixmap *p = d->animationPixmaps[d->currentFrame];
    painter->drawPixmap(QRectF(QPointF(0, 0), size()), *p, QRectF(p->rect()));
}

#include "moc_mspinnerview.cpp"

// bind controller widget and view widget together by registration macro
M_REGISTER_VIEW_NEW(MSpinnerView, MProgressIndicator)
<commit_msg>Fixes: NB#206875 - Frequent application crashes @QPixmap::isNull ()/isNull () with SIG11<commit_after>/***************************************************************************
**
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (directui@nokia.com)
**
** This file is part of libmeegotouch.
**
** If you have questions regarding the use of this file, please contact
** Nokia at directui@nokia.com.
**
** This library is free software; you can redistribute it and/or
** modify it under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation
** and appearing in the file LICENSE.LGPL included in the packaging
** of this file.
**
****************************************************************************/

#include <QPainter>
#include <QPropertyAnimation>

#include "mspinnerview.h"
#include "mspinnerview_p.h"

#include "mprogressindicator.h"

#include "mtheme.h"

MSpinnerViewPrivate::MSpinnerViewPrivate()
    :  q_ptr(NULL),
       controller(NULL),
       positionAnimation(NULL),
       currentFrame(0)
{
}

MSpinnerViewPrivate::~MSpinnerViewPrivate()
{
    delete positionAnimation;
    releaseUsedPixmaps();
}

QPropertyAnimation *MSpinnerViewPrivate::createAnimation()
{
    Q_Q(MSpinnerView);

    QPropertyAnimation *animation = new QPropertyAnimation(q, "currentFrame", q);
    animation->setLoopCount(-1);

    return animation;
}

void MSpinnerViewPrivate::refreshStyle()
{
    Q_Q(MSpinnerView);

    positionAnimation->setDuration(q->style()->period());
    positionAnimation->setStartValue(0);
    positionAnimation->setEndValue(q->style()->numberOfFrames());
    reloadFrames();
}

void MSpinnerViewPrivate::refreshModel()
{
    Q_Q(MSpinnerView);

    if (q->model()->unknownDuration()) {
        if (positionAnimation->state() == QPropertyAnimation::Paused)
            positionAnimation->resume();
        else
            positionAnimation->start();
    } else {
        if (positionAnimation->state() == QPropertyAnimation::Running)
            positionAnimation->pause();
    }
}

void MSpinnerViewPrivate::reloadFrames()
{
    Q_Q(MSpinnerView);

    releaseUsedPixmaps();
    // Starts from 1 because that's the agreed convention
    // for the image file names
    for (int i = 1; i <= q->style()->numberOfFrames(); i++) {
        QString frame_name = QString("%1_%2_%3").arg(q->style()->baseImageName())\
                                                .arg(q->style()->baseImageSize())\
                                                .arg(i);
        const QPixmap *p = MTheme::pixmap(frame_name);
        animationPixmaps << p;
    }
}

void MSpinnerViewPrivate::releaseUsedPixmaps()
{
    foreach(const QPixmap *p, animationPixmaps)
        MTheme::releasePixmap(p);
    animationPixmaps.clear();
}

void MSpinnerViewPrivate::_q_resumeAnimation()
{
    Q_Q(MSpinnerView);

    if (q->model()->unknownDuration()) {
        if (positionAnimation->state() == QPropertyAnimation::Paused)
            positionAnimation->resume();
    }
}

void MSpinnerViewPrivate::_q_pauseAnimation()
{
    if (positionAnimation->state() == QPropertyAnimation::Running)
        positionAnimation->pause();
}

void MSpinnerViewPrivate::_q_pauseOrResumeAnimation()
{
    if (controller->isVisible() && controller->isOnDisplay())
        _q_resumeAnimation();
    else
        _q_pauseAnimation();
}

MSpinnerView::MSpinnerView(MProgressIndicator *controller) :
    MWidgetView(controller),
    d_ptr(new MSpinnerViewPrivate)
{
    Q_D(MSpinnerView);
    d->q_ptr = this;
    d->controller = controller;
    d->positionAnimation = d->createAnimation();

    connect(controller, SIGNAL(visibleChanged()), this, SLOT(_q_pauseOrResumeAnimation()));

    connect(controller, SIGNAL(displayEntered()), this, SLOT(_q_pauseOrResumeAnimation()));
    connect(controller, SIGNAL(displayExited()), this, SLOT(_q_pauseOrResumeAnimation()));
}

MSpinnerView::~MSpinnerView()
{
    delete d_ptr;
}

int MSpinnerView::currentFrame() const
{
    Q_D(const MSpinnerView);

    return d->currentFrame;
}

void MSpinnerView::setCurrentFrame(int currentFrame)
{
    Q_D(MSpinnerView);

    if (currentFrame >= d->animationPixmaps.length())
        currentFrame %= d->animationPixmaps.length();

    d->currentFrame = currentFrame;
    update();
}

void MSpinnerView::updateData(const QList<const char *>& modifications)
{
    Q_D(MSpinnerView);
    MWidgetView::updateData(modifications);

    foreach(const char * member, modifications) {
        if (member == MProgressIndicatorModel::UnknownDuration)
            d->refreshModel();
    }
    update();
}

void MSpinnerView::applyStyle()
{
    Q_D(MSpinnerView);
    MWidgetView::applyStyle();

    d->refreshStyle();
}

void MSpinnerView::setupModel()
{
    Q_D(MSpinnerView);
    MWidgetView::setupModel();

    d->refreshModel();
}

void MSpinnerView::drawContents(QPainter *painter, const QStyleOptionGraphicsItem *option) const
{
    Q_UNUSED(option);
    Q_D(const MSpinnerView);

    if (d->animationPixmaps.isEmpty())
        return;

    const QPixmap *p = d->animationPixmaps[d->currentFrame];
    if (p && !p->isNull())
        painter->drawPixmap(QRectF(QPointF(0, 0), size()), *p, QRectF(p->rect()));
}

#include "moc_mspinnerview.cpp"

// bind controller widget and view widget together by registration macro
M_REGISTER_VIEW_NEW(MSpinnerView, MProgressIndicator)
<|endoftext|>


<commit_before>// Copyright (c) 2020 - 2021 by Apex.AI Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// SPDX-License-Identifier: Apache-2.0

#include "topic_data.hpp"

#include "iceoryx_hoofs/posix_wrapper/signal_watcher.hpp"
#include "iceoryx_posh/popo/publisher.hpp"
#include "iceoryx_posh/runtime/posh_runtime.hpp"

#include <iostream>

constexpr char APP_NAME[] = "iox-cpp-publisher-with-options";

int main()
{
    iox::runtime::PoshRuntime::initRuntime(APP_NAME);

    // create publisher with some options set
    iox::popo::PublisherOptions publisherOptions;

    // the publishers stores the last 10 samples for possible late joiners
    //! [history capacity]
    publisherOptions.historyCapacity = 10U;
    //! [history capacity]

    // when the publisher is created, it is not yet visible
    //! [offer on create]
    publisherOptions.offerOnCreate = false;
    //! [offer on create]

    // grouping of publishers and subscribers within a process
    //! [node name]
    publisherOptions.nodeName = "Pub_Node_With_Options";
    //! [node name]

    //  we allow the subscribers to block the publisher if they want to ensure that no samples are lost
    //! [too slow policy]
    publisherOptions.subscriberTooSlowPolicy = iox::popo::ConsumerTooSlowPolicy::WAIT_FOR_CONSUMER;
    //! [too slow policy]

    //! [create publisher with options]
    iox::popo::Publisher<RadarObject> publisher({"Radar", "FrontLeft", "Object"}, publisherOptions);
    //! [create publisher with options]

    // we have to explicitely offer the publisher for making it visible to subscribers
    //! [offer]
    publisher.offer();
    //! [offer]

    double ct = 0.0;

    std::thread publishData([&]() {
        while (!iox::posix::hasTerminationRequested())
        {
            ++ct;

            // Retrieve a sample, construct it with the given arguments and publish it via a lambda.
            publisher.loan(ct, ct, ct).and_then([](auto& sample) { sample.publish(); });

            std::cout << APP_NAME << " sent value: " << ct << std::endl;

            std::this_thread::sleep_for(std::chrono::milliseconds(400));
        }
    });

    while (!iox::posix::hasTerminationRequested())
    {
    }

    // this is optional, but since the iox::popo::ConsumerTooSlowPolicy::WAIT_FOR_CONSUMER option is used,
    // a slow subscriber might block the shutdown and this call unblocks the publisher
    //! [shutdown]
    iox::runtime::PoshRuntime::getInstance().shutdown();
    //! [shutdown]

    publishData.join();

    return 0;
}
<commit_msg>iox-#743 Remove while loop<commit_after>// Copyright (c) 2020 - 2021 by Apex.AI Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// SPDX-License-Identifier: Apache-2.0

#include "topic_data.hpp"

#include "iceoryx_hoofs/posix_wrapper/signal_watcher.hpp"
#include "iceoryx_posh/popo/publisher.hpp"
#include "iceoryx_posh/runtime/posh_runtime.hpp"

#include <iostream>

constexpr char APP_NAME[] = "iox-cpp-publisher-with-options";

int main()
{
    iox::runtime::PoshRuntime::initRuntime(APP_NAME);

    // create publisher with some options set
    iox::popo::PublisherOptions publisherOptions;

    // the publishers stores the last 10 samples for possible late joiners
    //! [history capacity]
    publisherOptions.historyCapacity = 10U;
    //! [history capacity]

    // when the publisher is created, it is not yet visible
    //! [offer on create]
    publisherOptions.offerOnCreate = false;
    //! [offer on create]

    // grouping of publishers and subscribers within a process
    //! [node name]
    publisherOptions.nodeName = "Pub_Node_With_Options";
    //! [node name]

    //  we allow the subscribers to block the publisher if they want to ensure that no samples are lost
    //! [too slow policy]
    publisherOptions.subscriberTooSlowPolicy = iox::popo::ConsumerTooSlowPolicy::WAIT_FOR_CONSUMER;
    //! [too slow policy]

    //! [create publisher with options]
    iox::popo::Publisher<RadarObject> publisher({"Radar", "FrontLeft", "Object"}, publisherOptions);
    //! [create publisher with options]

    // we have to explicitely offer the publisher for making it visible to subscribers
    //! [offer]
    publisher.offer();
    //! [offer]

    double ct = 0.0;

    std::thread publishData([&]() {
        while (!iox::posix::hasTerminationRequested())
        {
            ++ct;

            // Retrieve a sample, construct it with the given arguments and publish it via a lambda.
            publisher.loan(ct, ct, ct).and_then([](auto& sample) { sample.publish(); });

            std::cout << APP_NAME << " sent value: " << ct << std::endl;

            std::this_thread::sleep_for(std::chrono::milliseconds(400));
        }
    });

    iox::posix::waitForTerminationRequest();

    // this is optional, but since the iox::popo::ConsumerTooSlowPolicy::WAIT_FOR_CONSUMER option is used,
    // a slow subscriber might block the shutdown and this call unblocks the publisher
    //! [shutdown]
    iox::runtime::PoshRuntime::getInstance().shutdown();
    //! [shutdown]

    publishData.join();

    return 0;
}
<|endoftext|>


<commit_before>
/// PROJECT
#include <csapex/model/node.h>
#include <csapex/msg/io.h>
#include <csapex/param/parameter_factory.h>
#include <csapex/model/node_modifier.h>
#include <csapex/utility/register_apex_plugin.h>
#include <csapex/msg/generic_value_message.hpp>
#include <csapex_transform/transform_message.h>

using namespace csapex;
using namespace csapex::connection_types;

namespace csapex
{

class TransformAddNoise : public Node
{
public:
    TransformAddNoise():
        noise_(6)
    {
    }

    void setup(csapex::NodeModifier& modifier) override
    {
        in_ = modifier.addInput<TransformMessage>("Input");
        out_ = modifier.addOutput<TransformMessage>("Output");
    }

    void setupParameters(csapex::Parameterizable& params) override
    {
        params.addParameter(param::ParameterFactory::declareRange("std_x",0.0,1.0,0.01,0.01),
                            [this](param::Parameter* p){
            double std = p->as<double>();
            noise_[0] = std::normal_distribution<double>(0, std);
        });

        params.addParameter(param::ParameterFactory::declareRange("std_y",0.0,1.0,0.01,0.01),
                            [this](param::Parameter* p){
            double std = p->as<double>();
            noise_[1] = std::normal_distribution<double>(0, std);
        });
        params.addParameter(param::ParameterFactory::declareRange("std_z",0.0,1.0,0.01,0.01),
                            [this](param::Parameter* p){
            double std = p->as<double>();
            noise_[2] = std::normal_distribution<double>(0, std);
        });
        params.addParameter(param::ParameterFactory::declareRange("std_roll",0.0,1.0,0.01,0.01),
                            [this](param::Parameter* p){
            double std = p->as<double>();
            noise_[3] = std::normal_distribution<double>(0, std);
        });
        params.addParameter(param::ParameterFactory::declareRange("std_pitch",0.0,1.0,0.01,0.01),
                            [this](param::Parameter* p){
            double std = p->as<double>();
            noise_[4] = std::normal_distribution<double>(0, std);
        });
        params.addParameter(param::ParameterFactory::declareRange("std_yaw",0.0,1.0,0.01,0.01),
                            [this](param::Parameter* p){
            double std = p->as<double>();
            noise_[5] = std::normal_distribution<double>(0, std);
        });
    }

    void process() override
    {
        TransformMessage::ConstPtr msg_in = msg::getMessage<TransformMessage>(in_);
        TransformMessage::Ptr msg_out(new TransformMessage);
        msg_out->frame_id = msg_in->frame_id;
        msg_out->child_frame = msg_in->child_frame;
        msg_out->stamp_micro_seconds = msg_in->stamp_micro_seconds;
        tf::Vector3 pos = msg_in->getOrigin();
        double r,p,y;
        msg_in->getBasis().getRPY(r,p,y);

        double dx = noise_[0](generator_);
        double dy = noise_[1](generator_);
        double dz = noise_[2](generator_);
        double droll = noise_[3](generator_);
        double dpitch = noise_[4](generator_);
        double dyaw = noise_[5](generator_);

        pos += tf::Vector3(dx,dy,dz);
        tf::Quaternion q;
        q.setRPY(r+droll,p+dpitch,y+dyaw);
        msg_out->setRotation(q);
        msg_out->setOrigin(pos);
        msg::publish(out_, msg_out);

    }

private:
    Input* in_;
    Output* out_;

    std::vector<std::normal_distribution<double>> noise_;
    std::mt19937 generator_;

};

} // csapex

CSAPEX_REGISTER_CLASS(csapex::TransformAddNoise, csapex::Node)

<commit_msg>Add include random<commit_after>
/// PROJECT
#include <csapex/model/node.h>
#include <csapex/msg/io.h>
#include <csapex/param/parameter_factory.h>
#include <csapex/model/node_modifier.h>
#include <csapex/utility/register_apex_plugin.h>
#include <csapex/msg/generic_value_message.hpp>
#include <csapex_transform/transform_message.h>

/// SYSTEM
#include <random>
using namespace csapex;
using namespace csapex::connection_types;

namespace csapex
{

class TransformAddNoise : public Node
{
public:
    TransformAddNoise():
        noise_(6)
    {
    }

    void setup(csapex::NodeModifier& modifier) override
    {
        in_ = modifier.addInput<TransformMessage>("Input");
        out_ = modifier.addOutput<TransformMessage>("Output");
    }

    void setupParameters(csapex::Parameterizable& params) override
    {
        params.addParameter(param::ParameterFactory::declareRange("std_x",0.0,1.0,0.01,0.01),
                            [this](param::Parameter* p){
            double std = p->as<double>();
            noise_[0] = std::normal_distribution<double>(0, std);
        });

        params.addParameter(param::ParameterFactory::declareRange("std_y",0.0,1.0,0.01,0.01),
                            [this](param::Parameter* p){
            double std = p->as<double>();
            noise_[1] = std::normal_distribution<double>(0, std);
        });
        params.addParameter(param::ParameterFactory::declareRange("std_z",0.0,1.0,0.01,0.01),
                            [this](param::Parameter* p){
            double std = p->as<double>();
            noise_[2] = std::normal_distribution<double>(0, std);
        });
        params.addParameter(param::ParameterFactory::declareRange("std_roll",0.0,1.0,0.01,0.01),
                            [this](param::Parameter* p){
            double std = p->as<double>();
            noise_[3] = std::normal_distribution<double>(0, std);
        });
        params.addParameter(param::ParameterFactory::declareRange("std_pitch",0.0,1.0,0.01,0.01),
                            [this](param::Parameter* p){
            double std = p->as<double>();
            noise_[4] = std::normal_distribution<double>(0, std);
        });
        params.addParameter(param::ParameterFactory::declareRange("std_yaw",0.0,1.0,0.01,0.01),
                            [this](param::Parameter* p){
            double std = p->as<double>();
            noise_[5] = std::normal_distribution<double>(0, std);
        });
    }

    void process() override
    {
        TransformMessage::ConstPtr msg_in = msg::getMessage<TransformMessage>(in_);
        TransformMessage::Ptr msg_out(new TransformMessage);
        msg_out->frame_id = msg_in->frame_id;
        msg_out->child_frame = msg_in->child_frame;
        msg_out->stamp_micro_seconds = msg_in->stamp_micro_seconds;
        tf::Vector3 pos = msg_in->getOrigin();
        double r,p,y;
        msg_in->getBasis().getRPY(r,p,y);

        double dx = noise_[0](generator_);
        double dy = noise_[1](generator_);
        double dz = noise_[2](generator_);
        double droll = noise_[3](generator_);
        double dpitch = noise_[4](generator_);
        double dyaw = noise_[5](generator_);

        pos += tf::Vector3(dx,dy,dz);
        tf::Quaternion q;
        q.setRPY(r+droll,p+dpitch,y+dyaw);
        msg_out->setRotation(q);
        msg_out->setOrigin(pos);
        msg::publish(out_, msg_out);

    }

private:
    Input* in_;
    Output* out_;

    std::vector<std::normal_distribution<double>> noise_;
    std::mt19937 generator_;

};

} // csapex

CSAPEX_REGISTER_CLASS(csapex::TransformAddNoise, csapex::Node)

<|endoftext|>


<commit_before>#ifndef XSIMD_AVX512F_REGISTER_HPP
#define XSIMD_AVX512F_REGISTER_HPP

#include "./xsimd_generic_arch.hpp"

namespace xsimd {

  struct avx512f : generic {
    static constexpr bool supported() { return XSIMD_WITH_AVX512F; }
    static constexpr bool available() { return true; }
    static constexpr unsigned version() { return generic::version(3, 1, 0); }
    static constexpr std::size_t alignment() { return 64; }
  };

#if XSIMD_WITH_AVX512F

namespace types {
template <class T> struct simd_avx512_bool_register {
  using register_type = typename std::conditional<
      (sizeof(T) < 4), std::conditional<(sizeof(T) == 1), __mmask64, __mmask32>,
      std::conditional<(sizeof(T) == 4), __mmask16, __mmask8>>::type::type;
  register_type data;
  operator register_type() const { return data; }
};
template <class T> struct get_bool_simd_register<T, avx512f> {
  using type = simd_avx512_bool_register<T>;
};

    XSIMD_DECLARE_SIMD_REGISTER(bool, avx512f, __m512i);
    XSIMD_DECLARE_SIMD_REGISTER(signed char, avx512f, __m512i);
    XSIMD_DECLARE_SIMD_REGISTER(unsigned char, avx512f, __m512i);
    XSIMD_DECLARE_SIMD_REGISTER(char, avx512f, __m512i);
    XSIMD_DECLARE_SIMD_REGISTER(unsigned short, avx512f, __m512i);
    XSIMD_DECLARE_SIMD_REGISTER(short, avx512f, __m512i);
    XSIMD_DECLARE_SIMD_REGISTER(unsigned int, avx512f, __m512i);
    XSIMD_DECLARE_SIMD_REGISTER(int, avx512f, __m512i);
    XSIMD_DECLARE_SIMD_REGISTER(unsigned long int, avx512f, __m512i);
    XSIMD_DECLARE_SIMD_REGISTER(long int, avx512f, __m512i);
    XSIMD_DECLARE_SIMD_REGISTER(unsigned long long int, avx512f, __m512i);
    XSIMD_DECLARE_SIMD_REGISTER(long long int, avx512f, __m512i);
    XSIMD_DECLARE_SIMD_REGISTER(float, avx512f, __m512);
    XSIMD_DECLARE_SIMD_REGISTER(double, avx512f, __m512d);

  }
#endif
}
#endif

<commit_msg>memory<commit_after>#ifndef XSIMD_AVX512F_REGISTER_HPP
#define XSIMD_AVX512F_REGISTER_HPP

#include "./xsimd_generic_arch.hpp"

namespace xsimd {

  struct avx512f : generic {
    static constexpr bool supported() { return XSIMD_WITH_AVX512F; }
    static constexpr bool available() { return true; }
    static constexpr unsigned version() { return generic::version(3, 1, 0); }
    static constexpr std::size_t alignment() { return 64; }
    static constexpr bool requires_alignment() { return true; }
  };

#if XSIMD_WITH_AVX512F

namespace types {
template <class T> struct simd_avx512_bool_register {
  using register_type = typename std::conditional<
      (sizeof(T) < 4), std::conditional<(sizeof(T) == 1), __mmask64, __mmask32>,
      std::conditional<(sizeof(T) == 4), __mmask16, __mmask8>>::type::type;
  register_type data;
  operator register_type() const { return data; }
};
template <class T> struct get_bool_simd_register<T, avx512f> {
  using type = simd_avx512_bool_register<T>;
};

    XSIMD_DECLARE_SIMD_REGISTER(bool, avx512f, __m512i);
    XSIMD_DECLARE_SIMD_REGISTER(signed char, avx512f, __m512i);
    XSIMD_DECLARE_SIMD_REGISTER(unsigned char, avx512f, __m512i);
    XSIMD_DECLARE_SIMD_REGISTER(char, avx512f, __m512i);
    XSIMD_DECLARE_SIMD_REGISTER(unsigned short, avx512f, __m512i);
    XSIMD_DECLARE_SIMD_REGISTER(short, avx512f, __m512i);
    XSIMD_DECLARE_SIMD_REGISTER(unsigned int, avx512f, __m512i);
    XSIMD_DECLARE_SIMD_REGISTER(int, avx512f, __m512i);
    XSIMD_DECLARE_SIMD_REGISTER(unsigned long int, avx512f, __m512i);
    XSIMD_DECLARE_SIMD_REGISTER(long int, avx512f, __m512i);
    XSIMD_DECLARE_SIMD_REGISTER(unsigned long long int, avx512f, __m512i);
    XSIMD_DECLARE_SIMD_REGISTER(long long int, avx512f, __m512i);
    XSIMD_DECLARE_SIMD_REGISTER(float, avx512f, __m512);
    XSIMD_DECLARE_SIMD_REGISTER(double, avx512f, __m512d);

  }
#endif
}
#endif

<|endoftext|>