Data Driven Design in native C++ - c++

So I am writing a game engine that utilizes data driven design to instantiate various actors from xml files. I recently finished coding the event management system and everything fires off the events and the handlers catch them correctly. No easy task considering I used member function pointers and templates. The issue I am having now is that I would like to be able to do something like this in the xml file:
<InputComponent>
<Event EventName="GainedFocus" OnEvent="Initialize"/>
</InputComponent>
The problem should be pretty obvious. C++ has no form of reflection and therefore cannot, as far as I know, get the address for the Initialize function from the string "Initialize". This means that for slightly different input components I have derive from the class and register the events specific to that instance and add the functions. Also, it should be known that this is different than the way I am handling typical input:
<InputComponent>
<Mapping Type="MousePress" Button=1 Command="RotateCamera"/>
</InputComponent>
In this instance mapping is an element specific to input components and commands are themselves objects that are created with a factory. I cannot really do this with generic events though. Commands are specific items that perform the exact same operations on different objects whereas objects or components themselves often need to handle individual events differently. Has anyone done anything like this before? Genuinely curious as to how someone could go about doing something like this so that events that need to be registered to an object dont have to be hard coded into the class itself.
EDIT: Let me word it this way. Different INSTANCES of the same type of components need to react differently to events. This will be application specific and as such should be separate from the engine code (I shouldn't have to modify the components). The user should be able to supply functions that can then be called upon reaction to an event. Both the function and event should be able to be bound in XML. I am starting to think this might just be impossible in unmanaged C++ because there is no form of metadata to look up the functions supplied by the user based on a string of the same name.

You could use a map that associates strings with function pointers.
Or if the function signatures differ you can use a Factory pattern with an if-else-if ladder.
Edit 1: Example
// Typedef for event functions
typedef void (*Event_Function_Pointer)(const Event& e);
typedef std::map<std::string, Event_Function_Pointer> Event_Function_Container;
//...
Event_Function_Container events;
events["Gained Focus"] = Initialize;
There's also an option of having lookup table since the text and the function pointers are constant data:
struct Event_Function_Entry
{
char * const * event_name;
Event_Function_Pointer event_function;
};
Event_Function_Entry events[] =
{
{"Gained Focus", Initialize},
};

Your components could all inherit from a same base, that provindes the interface for basic operations that your commands will invoque:
class Component {
public:
virtual void initialize();
virtual void rotate(int x, int y);
...
};
class Monster : public Component {
virtual void initialize(); // concrete implementation for a Monster
virtual void rotate(int x, int y);
};
You may then consider the "command" design pattern. The general idea would be:
class Command { // generic interface for commands
Component *receiver;
public:
Command(Component *receiver);
virtual ~Command();
virtual void execute();
};
class InitializeCommand : Command { // a specific command
public:
InitializeCommand (Component *receiver /* + additional command specific parameters */); // specific constructor with all needed parameters
void execute() {
// use the parameters and do the common operations
receiver->initialize(); // polymorphically call the object operations
// ...
}
};
The rest depends of your global design.
You could for example design a factory that would create the commands based on the events that are processed and execute these:
if (event==...) {
// todo: find object pointed to by the object
Command c = myfactory_for_event (object, parameters);
c.execute();
}
Of if your xml file is meant to configure an object, then you read the file, create specific commands, and store them in an event map that associates an event name to a concrete command:
map<string,Command*> commands;
In this case, the event processing would be something like:
myobject["initialize"]->execute();

So no one knows if there is any way to do this? Obviously there are hack ways. Multiple integration, multiple factories etc. I could ONLY have responses to events done as Command objects but that seems like a weird solution...because there is no runtime information available I have to encapsulate each INDIVIDUAL function in its own class..waste of memory if you ask me...Just realized how weird that sounds. Basically what I meant is for each funtion I wanted to map to an event I would have to create an entire new class (same as the command pattern I am already using to map keys). Would be much easier if I could just provide a function address instead of allocating and deallocating memory for ever individual action but no one seems to have an answer.

Related

Architecture of a director / executive / master / top-level application layer

I have a collection of classes and functions which can interact with one another in rich and complex manners. Now I am devising an architecture for the top-level layer coordinating the interaction of these objects; if this were a word processor (it is not), I am now working on the Document class.
How do you implement the top-level layer of your system?
These are some important requirements:
Stand-alone: this is the one thing that can stand on its own
Serializable: it can be stored into a file and restored from a file
Extensible: I anticipate adding new functionality to the system
These are the options I have considered:
The GOF Mediator Pattern used to define an object that encapsulates how a set of objects interact [...] promotes loose coupling by by keeping objects from referring to each other explicitly, and it lets you vary their interaction independently.
The problem I see with mediator is that I would need to subclass every object from a base class capable of communicating with the Mediator. For example:
class Mediator;
class Colleague {
public:
Colleague(Mediator*);
virtual ~Colleague() = default;
virtual void Changed() {
m_mediator->ColleagueChanged(this);
}
private:
Mediator* m_mediator;
};
This alone makes me walk away from Mediator.
The brute force blob class where I simply define an object and all methods which I need on those objects.
class ApplicationBlob {
public:
ApplicationBlob() { }
SaveTo(const char*);
static ApplicationBlob ReadFrom(const char*);
void DoFoo();
void DoBar();
// other application methods
private:
ClassOne m_cone;
ClassTwo m_ctwo;
ClassThree m_cthree;
std::vector<ClassFour> m_cfours;
std::map<ClassFive, ClassSix> m_cfive_to_csix_map;
// other application variables
};
I am afraid of the Blob class because it seems that every time I need to add behaviour I will need to tag along more and more crap into it. But it may be good enough! I may be over-thinking this.
The complete separation of data and methods, where I isolate the state in a struc-like object (mostly public data) and add new functions taking a reference to such struct-like object. For example:
struct ApplicationBlob {
ClassOne cone;
ClassTwo ctwo;
ClassThree cthree;
std::vector<ClassFour> cfours;
std::map<ClassFive, ClassSix> cfive_to_csix_map;
};
ApplicationBlob Read(const char*);
void Save(const ApplicationBlob&);
void Foo(const ApplicationBlob&);
void Bar(ApplicationBlob&);
While this approach looks exactly like the blob-class defined above, it allows me to physically separate responsibilities without having to recompile the entire thing everytime I add something. It is along the lines (not exactly, but in the same vein) of what Herb Sutter suggests with regards to preferring non-member non-friends functions (of course, everyone is a friend of a struct!).
I am stumped --- I don't want a monolith class, but I feel that at some point or another I need to bring everything together (the whole state of a complex system) and I cannot think of the best way to do it.
Please advise from your own experience (i.e., please tell me how do you do it in your application), literature references, or open source projects from where I can take some inspiration.

Pattern for choosing behaviour based on the types present in a collection derived objects

I have an collection of objects which represents a model of a system. Each of these objects derives from a base class which represents the abstract "component". I would like to be able to look at the system and choose certain behaviours based on what components are present and in what order.
For the sake of argument, let's call the base class Component and the actual components InputFilter, OutputFilter and Processor. Systems that we can deal with are ones with a Processor and one or both filters. The actual system has more types and more complex interaction between them, but I think this will do for now.
I can see two "simple" ways to handle this situation with a marshalComponentSettings() function which takes one of the collections and works out how to most efficiently set up each node. This may require modifying inputs in certain ways or splitting them up differently, so it's not quite as simple as just implementing a virtual handleSettings() function per component.
The first is to report a enumerated type from each class using a pure virtual function and use those to work out what to do, dynamic_cast'ing where needed to access component specific options.
enum CompType {
INPUT_FILTER,
OUTPUT_FILTER,
PROCESSOR
}
void marshal(Settings& stg)
{
if (comps[0].type() == INPUT_FILTER)
setUpInputFilter(stg); //maybe modified the stg, or provides other feedback of what was done
// something similar for outputs
setUpProcessor(stg);
}
The second is to dynamic_cast to anything that might be an option in this function and use the success of that or not (as well as maybe the cast object if needed) to determine what to do.
void marshal(Settings& stg)
{
if (InputFilter* filter = dynamic_cast<InputFilter*>(comp[0]))
setUpInputFilter(stg); //maybe modified the stg, or provides other feedback of what was done
// something similar for outputs
setUpProcessor(stg);
}
It seems that the first is the most efficient way (don't need to speculatively test each object to find out what it is), but even that doesn't quite seem right (maybe due to the annoying details of how those devices affect each other leaking into the general marshaling code).
Is there a more elegant way to handle this situation than a nest of conditionals determining behaviour? Or even a name for the situation or pattern?
Your scenario seems an ideal candidate for the visitor design pattern, with the following roles (see UML schema in the link):
objectStructure: your model, aka collection of Component
element: your Component base class
concreteElementX: your actual components (InputFilter, OutputFilter, Processor, ...)
visitor: the abstract family of algorithms that has to manage your model as a consistent set of elements.
concreteVisitorA: your configuration process.
Main advantages:
Your configuration/set-up corresponds to the design pattern's intent: an operation to be performed on the elements of an object structure. Conversely, this pattern allows you to take into consideration the order and kind of elements encountered during the traversal, as visitors can be stateful.
One positive side effect is that the visitor pattern will give your desing the flexibility to easily add new processes/algortihms with similar traversals but different purpose (for example: pricing of the system, material planning, etc...)
class Visitor;
class Component {
public:
virtual void accept(class Visitor &v) = 0;
};
class InputFilter: public Component {
public:
void accept(Visitor &v) override; // calls the right visitor function
};
...
class Visitor
{
public:
virtual void visit(InputFilters *c) = 0; // one virtual funct for each derived component.
virtual void visit(Processor *c) = 0;
...
};
void InputFilter::accept(Visitor &v)
{ v.visit(this); }
...
class SetUp : public Visitor {
private:
bool hasProcessor;
int impedenceFilter;
int circuitResistance;
public:
void visit(InputFilters *c) override;
void visit(Processor *c) override;
...
};
Challenge:
The main challenge you'll have for the visitor, but with other alternatives as well, is that the setup can change the configuration itself (replacing component ? change of order), so that you have to take care of keeping a consitent iterator on the container while making sure not to process items several time.
The best approach depends on the type of the container, and on the kind of changes that your setup is doing. But you'll certainly need some flags to see which element was already processed, or a temporary container (either elements processed or elements remaining to be processed).
In any case, as the visitor is a class, it can also encapsulate any such state data in private members.

What is the best C++ design to contain a class's objects?

I have a class with many objects that I would like to group in some type of container and also access them with some type of identifier.
class Menu {
Object title;
Object play;
Object instructions;
Object pause;
...
};
Having each object listed in the class, shown above, is nice because I can access them like, menu.title, but then I have to retype every name to add it to a container, vector.push_back(title).
Shown below is how I've always solved the problem. I use an enum's integer value to access the corresponding index. objects[TITLE] or objects[PLAY]
class Menu {
std::vector<Object> objects;
};
enum ObjectTypes {
TITLE, PLAY, INSTRUCTIONS, PAUSE, ...
};
I generally dislike this approach because it seems indirect, and when using nested classes and enums, the identifiers can become long and cumbersome. I'm coming from C and somewhat new to C++. Does anybody have a more practical and/or elegant way to solve this problem? C++11 and above welcomed!
The approach you are using is fine. If you want to avoid cumbersome identifiers, you can make a temporary reference to keep things more succinct. For example, instead of calling:
menu.objects[PAUSE].foo();
menu.objects[PAUSE].bar();
menu.objects[PAUSE].baz();
... you could do this when necessary:
Object & pause = menu.objects[PAUSE];
pause.foo();
pause.bar();
pause.baz();
and it would work the same, but without all of the redundant characters.
I think your approach is fine. Using a std::map<ObjectType, Object> instead of a std::vector might be a little more type-safe.
Either way, if you want to save yourself a little typing you could overload the operator[] on Menu:
Object& operator[](index_type i){ return objects[i]; }
const Object& operator[](index_type i) const { return objects[i]; }
Then you can write menu[TITLE].
Other than that, I don't see how it can be any less cumbersome, there is no redundant information there and, as Jeremy pointed out, if you need an object multiple times you can always create a local reference auto& title = menu[TITLE];.
Depending on what other responsibilities Menu has maybe you don't need a Menu class at all and you can just use a map or vector directly?
The best solution to your question depends mostly on your use cases.
I see two main use cases:
You want to represent "functions"of a "device" so you can achieve readable code when manipulating that "device" from your code. Such as a MediaPlayer device having play, stop, pause operations. But you dismissed the option to simply add member functions to your "device" object, such as Play(), because you want to re-use your play code also for another device, such as a tuner device. Also, you want to apply operations to all or a sub set of those "functions", for example Enable()/Disable()/ToString()/Trigger(),Configure()..., which is why the member function approach is not favorable.
You want to create a Document Object model, which is more data focused. Such as an Xml Document.
From what you wrote in your question, I assume you have use case 1 in mind. Your Object type has all the common operations you need.
Yet, then there are the differences between all those "functions".
In order to stick to your simple approach, you would need to manually set up/configure your Object instances, which might in the long run turn out to be annoying, but hardly avoidable:
// Example of "annoying": If you have more than 1 "device",
// you have to write such a function for each of them.
// Also, there is that fishy bit with Object.Id - the association between
// your configuration data and your object you want to configure.
void ConfigureMenu( std::vector& menuItems, MenuConfigurationData& configData )
{
for( auto& menuItem : menuItems )
{
menuItem.Configure( configData[menuItem.Id] ); // spoiler!
}
}
Also, I am inclined to think that even now you have some code not shown in your question, which configures your objects.
With that in mind, you might want to get rid of the idea to write 1 class type per "device" by hand. The next device/menu will need to be treated the same, yet with dedicated more coding.
So, my advice to you is to get rid of your class Menu for good, to abstract your problem and to model your problem rather like: Object is your "function" and a device is simply a set of functions/Objects. Then, your class Menu simply becomes an instance, named Menu.
typedef uint32_t FunctionId; // for example uint32_t...
typedef std::map<FunctionId,Object> Device; // aka. Menu.
Then, in the configuration function you most likely have anyway, you pass in an instance of that Device map and your configuration function fills it with Object, properly configured.
// those enums are still specific to your concrete device (here Menu) but
// you can consider the time it takes writing them an investment which will
// pay off later when you write your code, using your functions.
// You assign the function id which is used in your meta-data.
enum class MenuFunctions : FunctionId { play = ..., title = ..., instructions, ... };
// "generic" configuration function.
// Does not only configure your Object, but also puts it inside the device.
void ConfigureDevice( Device& device, ConfigData& configData )
{ // ...
}
And later in your code, you can access the functions like this:
menu[MenuFunctions::play].Trigger();
There are alternative approaches and variations to this, of course. For example, assuming you have your meta data (config data, device descriptions), you could stop coding all that by hand and instead write some code generator which does the job for you.
Your first version of such a generator could create your configuration functions and the enums for you.
With all that in place, the use case of "nested classes" becomes just a matter of creating collections of Device instances. Now, as all your devices are of the same type, you can compose and sub-group them at your leisure.
A few different approaches below. I'm not saying which is "best". There are pros/cons to them all.
A) Rather than using a vector (e.g. class Menu { std::vector<Object> objects; };), use an array class Menu {std::array<Object,NObjectTypes> objects;}; when your element count is constant.
B) Just use a class, but provide an api to return a std::array<> of references to your objects:
class Menu {
Object title;
Object play;
Object instructions;
Object pause;
...
std::array<Object*,NObjects> allObjects();
};
C) std::tuple can be useful when your types are not all the same.
For menus, I'll often go with "A".

Retrieving values of collection from multiple classes, what's the correct way?

Before anything, thanks for reading!
I'm developing an application in C++ and I want an advice about a design issue. Let me explain:
The main class of my application has some collections, but other classes eventually need to get a value from one of those collections. Something like this:
class MainClass {
private:
// Collections are internally implemented as QHash
Collection<Type1> col1;
Collection<Type2> col2;
};
class RosterUnit {
public:
RosterUnit() {
/* This method needs to get a specific value from col1 and
initialize this class with that data */
}
};
class ObjectAction {
public:
virtual void doAction() = 0;
};
class Action1 : public ObjectAction {
public:
void doAction() {
// This needs a specific value from col2
}
};
class Action2 : public ObjectAction {
public:
void doAction() {
// This needs a specific value from col1
}
};
My first approach was passing the whole collection as parameter when needed, but it is not so good for ObjectAction subclasses, because I would have to pass the two collections and if I later create another subclass of ObjectAction and it needs to get an element from other collection (suppose col3), I would have to modify the doAction() signature of every ObjectAction subclass, and I think that is not too flexible. Also, suppose I have a Dialog and want to create a RosterUnit from there. I would have to pass the collection to the dialog just to create the RosterUnit.
Next I decided to use static variables in RosterUnit and ObjectAction that pointed to the collections, but I'm not very happy with that solution. I think it is not flexible enough.
I have been reading about design patterns and I first thought a Singleton with get functions could be a good choice, but after some more investigation I think it isn't a proper design for my case. It would be easier and more or less the same if I use global variables, which don't seem to be the right way.
So, could you give some advices, please?
Thank you very much!
As mentioned previously, Iterators are good for abstracting away the details of the Collection. But going this route implies that the objects that use the Iterators will need to know about what's inside the Collection. Meaning they will need to know how to decide which object in the Collection they need, thus increasing the coupling. (more details below in the Factory paragraph) This is something you need to consider.
Another approach would be to create accessor methods on the MainClass that take some sort of key and return an object from the Collection (findObject(key)). Internally the MainClass methods would search through the container(s) and return the appropriate object. To use this approach, you will however need access to the MainClass, either by dependancy injection as mentioned before, or possibly making it a Singleton (not recomended in this scenario, though).
With the info provided so far, it may even be better for your ObjectAction Factory to have a reference to the MainClass, and as a part of the ObjectAction creation logic, call the appropriate MainClass accessor and pass the result into the ObjectAction, thus decoupling the ObjectAction Objects from the MainClass.
You probably want to use iterators, they exist exactly for the purpose of abstracting away sequences from specific containers.
If your issue is how to pass the iterators to the code that needs them in the first place, do not give in to the temptation to use globals. It may look more convoluted if you have to pass parameters in, but your code is that much more decoupled for it. "Dependency Injection" is a good keyword if you want to read more about this topic.
I would also advise you to check out std::function or boost::function instead of inheriting from ObjectAction. Functional style is getting more common in modern C++, as opposed to how it's usually done in languages like Java.
There's not enough information here of what you are trying to do. You make it sound like 'at some point in the future, this statically created action needs this data that was left behind.' How does that make any sense? I would say either construct the actions with the data, as you would for instance with a Future or Callable), or have the command ask for the next piece of data, in which case you are just implementing a Work queue.
Sounds like you are trying to do something like a thread pool. If these actions are in any way related, then you should have then in some composing object, implementing something like the Template Method pattern, e.g. execute() is abstract and calls a few other methods in a fixed sequence and that cannot be overridden, the other methods must be (protocol enforcement).

Overriding / modifying C++ classes using DLLs

I have a project with a large codebase (>200,000 lines of code) I maintain ("The core").
Currently, this core has a scripting engine that consists of hooks and a script manager class that calls all hooked functions (that registered via DLL) as they occur. To be quite honest I don't know how exactly it works, since the core is mostly undocumented and spans several years and a magnitude of developers (who are, of course, absent). An example of the current scripting engine is:
void OnMapLoad(uint32 MapID)
{
if (MapID == 1234)
{
printf("Map 1234 has been loaded");
}
}
void SetupOnMapLoad(ScriptMgr *mgr)
{
mgr->register_hook(HOOK_ON_MAP_LOAD, (void*)&OnMapLoad);
}
A supplemental file named setup.cpp calls SetupOnMapLoad with the core's ScriptMgr.
This method is not what I'm looking for. To me, the perfect scripting engine would be one that will allow me to override core class methods. I want to be able to create classes that inherit from core classes and extend on them, like so:
// In the core:
class Map
{
uint32 m_mapid;
void Load();
//...
}
// In the script:
class ExtendedMap : Map
{
void Load()
{
if (m_mapid == 1234)
printf("Map 1234 has been loaded");
Map::Load();
}
}
And then I want every instance of Map in both the core and scripts to actually be an instance of ExtendedMap.
Is that possible? How?
The inheritance is possible. I don't see a solution for replacing the instances of Map with instances of ExtendedMap.
Normally, you could do that if you had a factory class or function, that is always used to create a Map object, but this is a matter of existing (or inexistent) design.
The only solution I see is to search in the code for instantiations and try to replace them by hand. This is a risky one, because you might miss some of them, and it might be that some of the instantiations are not in the source code available to you (e.g. in that old DLL).
Later edit
This method overriding also has a side effect in case of using it in a polymorphic way.
Example:
Map* pMyMap = new ExtendedMap;
pMyMap->Load(); // This will call Map::Load, and not ExtendedMap::Load.
This sounds like a textbook case for the "Decorator" design pattern.
Although it's possible, it's quite dangerous: the system should be open for extension (i.e. hooks), but closed for change (i.e. overriding/redefining). When inheriting like that, you can't anticipate the behaviour your client code is going to show. As you see in your example, client code must remember to call the superclass' method, which it won't :)
An option would be to create a non-virtual interface: an abstract base class that has some template methods that call pure virtual functions. These must be defined by subclasses.
If you want no core Map's to be created, the script should give the core a factory to create Map descendants.
If my experience with similar systems is applicable to your situation, there are several hooks registered. So basing a solution on the pattern abstract factory will not really work. Your system is near of the pattern observer, and that's what I'd use. You create one base class with all the possible hooks as virtual members (or several one with related hooks if the hooks are numerous). Instead of registering hooks one by one, you register one object, of a type descendant of the class with the needed override. The object can have state, and replace advantageously the void* user data fields that such callbacks system have commonly.