So I was using my code when I ran into a problem using this synchronously. This code works best asynchronous (meaning it executes whenever it executes, which is when any event occurs), but what if I wanted to do synchronous actions? You can't use this to, say, draw stuff on the screen because the action would execute before or after the beginScene function. While it is possible to get the index of the action you want to execute, that involves, yet again, some more messy code. So I implemented a tag system to the Action class as well as the ability to search and/or execute any desired action so long it has that tag.
EDIT: The interaction as a means to call an object in the code, avoiding the including of it on the parameter list. However, you can't use it to assign classes a variable in the constructor. For example, you can't have a variable that is assigned in the constructor; the class needs to add the interaction to another class first in order to have a pointer to the instance of that class to assign to the variable in the first place. I would stick to passing it through the parameter list if you want to assign the pointer in the constructor.
Example Usage:
Code: Select all
/*****************main.cpp*********************/
#include "include/IEventUpdater.h"
using namespace blah blah blah // <-- Error? You actually copied and compiled this?
int main()
{
IrrlichtDevice *device = createDevice(EDT_SOFTWARE, dimension2d<u32>(640, 480), 16, false, false, false, &Updater); // The Updater is used like any other event class
IVideoDriver* driver = device->getVideoDriver();
Sprite *sprite = new Sprite(driver, dimension2d<u32>(32, 32), position2d<int>(200, 200));
Updater.addAction(sprite, "sprite"); // NOTICE that there is no need for the update function. As long as it extends the Action class, it can be put into the updater. Also it has a tag: "Sprite".
while(device->run())
{
driver->beginScene(true, true, SColor(0,0,0,0));
event.runAction("sprite"); // Search by tag and execute
driver->endScene();
}
delete sprite;
}
/*****************Sprite.h*********************/
class Sprite: public Action
{
Sprite(IVideoDriver* _driver, dimension2d<u32> _dim, position2d<int> _pos);
void update(const SEvent& event); // The update function must be void(const SEvent& event);
ITexture* sprite;
dimension2d<u32> dim;
position2d<int> pos;
IVideoDriver* driver;
}
/*****************Sprite.cpp*********************/
// Let's skip the init code; It should be obvious what it contains
void Sprite::update(const SEvent& event)
{
driver->draw2DImage(sprite, pos);
}
IEventUpdater.h:
Code: Select all
#ifndef IEVENTUPDATER_H
#define IEVENTUPDATER_H
#include <irrlicht.h>
#include <vector>
#include <string>
#include "Action.h"
using namespace irr;
using namespace core;
using namespace scene;
using namespace video;
using namespace std;
class IEventUpdater: public IEventReceiver
{
public:
IEventUpdater();
virtual ~IEventUpdater();
virtual bool OnEvent(const SEvent& _event);
void addAction(Action* _Action, std::string _name = "n/a");
Action* findAction(std::string _name);
void runAction(std::string _name);
protected:
private:
vector<Action*> actions;
} extern Updater;
#endif // IEVENTUPDATER_H
IEventUpdater.cpp:
Code: Select all
#include "../include/IEventUpdater.h"
IEventUpdater::IEventUpdater()
{
actions.resize(0);
}
IEventUpdater::~IEventUpdater()
{
actions.resize(0);
}
void IEventUpdater::addAction(Action* _action, std::string _name)
{
_action->setName(_name);
actions.push_back(_action);
}
bool IEventUpdater::OnEvent(const SEvent& _event)
{
for(int action=0; action<actions.size(); action++)
actions.at(action)->update(_event);
return true;
}
Action* IEventUpdater::findAction(std::string _name)
{
for(int action=0; action<actions.size(); action++)
if(actions.at(action)->getName() == _name) return actions.at(action);
}
void IEventUpdater::runAction(std::string _name)
{
findAction(_name)->update();
}
IEventUpdater Updater;
Action.h:
Code: Select all
#ifndef ACTION_H
#define ACTION_H
#include <irrlicht.h>
#include <string>
using namespace irr;
using namespace std;
class Action
{
public:
Action();
virtual ~Action();
virtual void update(const SEvent& event) = 0;
void update();
void setName(string _name);
string getName() const;
protected:
private:
string name;
};
#endif // ACTION_H
Action.cpp:
Code: Select all
#include "../include/Action.h"
Action::Action(){}
Action::~Action(){}
void Action::update()
{
update(SEvent()); // Just create a(n) SEvent to bypass the required argument... idk how safe this is, but it works
}
void Action::setName(string _name)
{
name = _name;
}
string Action::getName() const
{
return name;
}