It sounds like what you want is named delegates. If I understand it correctly, your actions are just a call to a function in an existing component. Then all you need is to store a member function pointer and a pointer to the component, instead of a custom class.
You can do this directly with member function pointers, or wrap it in a delegate class. It would look something like this:
class Actor
{
// ... same as before
typedef delegate<bool(int,int)> Action;
void addAction(const string& actionName, Action action);
bool executeAction(const string& actionName, int arg1, int arg2);
private:
map<string, Action> m_Actions;
};
Actor* player = new Actor();
player->addAction("move", Actor::Action(moveComponent, &MoveComponent::move));
The trick is to build a templatized delegate class that will handle any component and, as long as your signature stays the same (return a bool, take two ints) then you can abstract all the actions easily.
If you need to take multiple components, then you'll have to fall back to your original method, especially if you want to bind the components in advance. If not, then you can have the action perform the lookup, if it's quick enough, and implement actions as free functions:
class Actor
{
// ... same as before
typedef delegate<bool(Actor,int,int)> Action;
};
bool MoveAction(Actor* actor, int dX, int dY)
{
MoveComponent* moveComponent = actor.getComponent("move");
if (moveComponent) return moveComponent->move(dX, dY);
return false;
}
Actor* player = new Actor();
player->addAction("move", Actor::Action(MoveAction));
There are many resources for how to implement a delegate class like that. This is a great starting point, maybe simpler than this implementation which works well and is broadly used. There may be better ways to do this in C++11better ways to do this in C++11.
Roughly speaking, you use templates to bind the member function or free function pointer to an automatically generated function that knows how to call it.