Proxy class for polymorphic type, using templates - c++

This is for a "game engine" as a bit of programming practice. All of my GameObjects are component based, where each component adds a functionality to its parent GameObject and all of these components descend from a base Component class which has virtual methods making it polymorphic.
When I read in these gameobject definitions from an XML file some components need to know about others for example a physics component needs to be aware of the transform component for the physics calculations. However if these components aren't present in the XML file then occasionally it throws up nasty null-pointers and endless rabbit hole call stack chasing to find the XML typo I fudged while half asleep.
My solution was to have a node in the XML file as an assertion that a component of this type should exist and possibly throw an exception or another appropriate action if it doesnt.
Eg.
<ComponentRequirement type="ComponentTransform">myTransformComponent</ComponentRequirement>
So I need a way of representing this in C++. The first idea, template classes to change according to what type of component it's the proxy of since this class needs to act like their unproxied component. I've solved that with some operator overloading so long as the class is a template class.
template <class T>
class ComponentRequirement {
public:
T* operator->() { (I chose the arrow operator because the CompReq class will never be referenced as a pointer)
return this->component;
}
//Other unrelated functions . . .
private:
T* component;
};
And this is all fine and dandy at compile time because I can just say
ComponentRequirement<ComponentTransform> req = ComponentRequirement("myComponentTransform");
But I need to be able to specify what that template type in place of the will be from a string when I read the XML in. I thought a hashmap could do it but I dont think the type name even "is" anything other than a human readable compiler hint so I couldn't use it as a hashmap value.
Can this be done and how could I go about implementing it? Inserting some string literal into a "black-box of magic" and get something that can be used as a template argument. And if it helps, everything that will be the value of "T" is polymorphic.
Or is there a better solution to my problem. It needs to be able to act as any Component I put into it and it needs to be discernable at runtime.
EDIT 1:
In my components I have a read and write function. If I read the component requirement in there I can make sure the template has the right value because each component is seperate.
I can then evaluate the requirements with a virtual function and a few functions in the gameobject class to check it's a valid configuration. This could solve the problem.

At a first glance I would use the factory pattern for your problem. That way you can create classes to create your objects given a different string without specifying the exact class you need at compile time unlike with normal typed constructors. The analogy I see people use are Virtual Constructors.
http://www.oodesign.com/factory-pattern.html
In essence you would have a map of factories (creator objects).
Define some top level interface for your components, such as IComponent.
Define a factory class for every component you want to generate that has a Create Instance method. I recommend the Create Instance method should be part of an interface like IFactory.
During setup of your program create your map and assign factories to particular keys. ActorCreator["MyComponent"] = new MyComponentFactory();
When you want to create an object read from an XML node you can just call the create instance method on the returned factory for the key. auto myComponent = ActorCreator[readXML]->CreateInstance();
You now have an actor/components whose concrete type has been decided at runtime instead of compile time.

Related

Variable types from inherited classes

If I have a class that inherits from a base class, can I use that base class as a variable type in c++?
class Component {
// Code here
};
class TransformComponent : public Component {
// Code here
};
class Entity {
// Code here
Component *getComponent(Component *searchComponent) {
// Code Here
}
};
as you can see here, I am using the base class "Component" as a return type and a variable type. The problem is that the user may input a "TransformComponent". The only reason I am asking this is because the "TransformComponent" class inherits from the "Component" class and there might be a way to do this?
<Entity>.getComponent(Component &TransformComponent());
The answer I'm looking for is one that works both for the return type, and the variable type.
Absolutely! It's one of the beauties of OOP. Your instanced class of type TransformComponent is both an instance of Component as well as TransformComponent.
If you had some function that returned a type of Component, this could return any class derived from Component as a Component! If you later wanted to refer to it as its sub-class, you might have to check its type and then cast to it, but what you want is absolutely possible, and you're going the right way about it.
In fact, in the example you describe, were you are using Component and the user might pass a TransformComponent, all of the base methods and properties that the Component possesses will be possessed by TransformComponent too. It will look and feel as if it was a Component, with all the benefits of being one.
The only time a problem will arise is if you specifically want to access the features of a TransformComponent, and the user passed a Component. The parent class doesn't know about the sub-class stuff, because it isn't an instance of one, it will throw up errors for you. Sub-classes build upon the base class, so they have all the base-class stuff, plus more. Basically its only an issue when your example is reversed.
Your Entity.getComponent() method suggests that it only cares that the provided argument is a Component ... not any specialization, such as TransformComponent, of that original class.
So, if you find yourself writing logic that actually cares that "this Component might actually be a TransformComponent," then "warning bells should be going off." Create method definitions within the class that are as specific as possible.

Design pattern to use when the application wants to know which concrete class it got

I have a class structure like the on below.
class Technology;
class BasicTechnology : public Technology;
class BasicChildTechnology : public BasicTechnology;
class ConcreteChildTechnology1 : public BasicChildTechnology;//concretechildtech1
class ConcreteChildTechnology2 : public BasicChildTechnology;//concretechildtech2
class ConcreteChildTechnology3 : public BasicChildTechnology;//concretechildtech3
...
class ConcreteChildTechnologyN : public BasicChildTechnology;//concretechildtechN
The ConcreteChildTechnologyN/3/2/1 has an isValid(String selector) method, which is as shown below,
public isValid(String selector){
return "concretechildtech1".Equals(selector);
}
Now in the client code is,
Technology tech = getTechnologyObject("concretechildtech1"); //tech becomes an instance of ConcreteChildTechnology1
How should I implement getTechnologyObject() in this case?.
Thought of using the abstract factory pattern, but doubtful of that. or even create a Facade and create the concrete child based on the input argument?
The problem is, only the ConcreteChildTechnology1 knows whether the input string (concretechildtech1) belongs to him or not; via isValid() method.
Again if I start to create N objects every time to check the validity, that will cause and overhead, because 1)the system is running in a very low memory environment like mobile and tablets, 2)the number of instance creation is high, 10-100 per minute.
May be make the isValid() a static inline method and create object based on the reply from child objects?
My understanding is that getTechnologyObject("string") is returning a smart reference/pointer like std::shared_ptr<BasicChildTechnology> based on a string. Inside that function there is a list of these tech objects and only that tech object knows if it is associated with that string.
The first problem is that string. Is it possible to convert it to an enumeration or some more precise data type earlier than now? That alone will make your system more reliable, and faster.
The second problem is the ownership of the match criteria. I imagine when the system was being designed that this felt natural. I would point out that this object does not have a single responsibility. It is both required to do whatever the Tech is, and required to match itself from some serialisation format. It may still make sense to leave the string inside that object (it might be a name) but the matching needs to be elevated out of the object, and into the search function getTechnologyObject("string").
Now regardless of if you have a string/numeric, the tech objects need a function virtual label_t label() (name it as you feel fit) that returns this identifier.
Thirdly your creating a new object each time. That is the factory pattern, but there are two choice on how to implement that. One is giving the power of cloning to each implementation and treat each instance as a prototype. The other is to create a related hierarchy of factories that build those tech objects.
If you go the prototype path also define a virtual std::shared_ptr<BasicChildTechnology> clone() const =0; in the Tech classes. Otherwise create a related TechnologyFactory class tree, or a Factory<T> template. The factory will need something like a label_t label() and a std::shared_ptr<BasicChildTechnology> build().
I'm going to pick prototype here.
Construct the lookup like:
std::map<label_t, std::shared_ptr<BasicChildTechnology>> lookup;
lookup.add(tech1->label(), tech1);
lookup.add(tech2->label(), tech2);
lookup.add(tech3->label(), tech3);
Then:
std::shared_ptr<BasicChildTechnology> getTechnologyObject(const label_t& label)
{
return lookup[label]->clone();
}
And a Factory template here.
Construct the lookup like:
std::map<label_t, Factory<std::shared_ptr<BasicChildTechnology>>> lookup;
lookup.add(factory1->label(), factory1);
lookup.add(factory2->label(), factory2);
lookup.add(factory3->label(), factory3);
Then:
std::shared_ptr<BasicChildTechnology> getTechnologyObject(const label_t& label)
{
return lookup[label]->build();
}
The lookup will execute in log(N) time, for both cases.
What you are trying to do has different solutions based on your exact implementation and what the child types actually do.
If the isValid() method never relies on non-static member variables, isValid() could be made static. Your getTechnologyObject() function could be written as:
Technology* getTechnologyObject(const std::string& _string)
{
if(ConcreteChildTechnology1::isValid(_string)){
return new ConcreteChildTechnology1(/* arguments go here */);
}
/* follow with the rest */
}
As per user4581301's comment you can return a pointer to prevent object slicing.
It seems that your type hierarchy is blowing out in size. To reduce complexity and perhaps make the creation of objects easier, you could explore some form of composition instead of inheritance. This way a factory pattern would make more sense. Perhaps you could create a Technology object based off what is it supposed to do using a decorator pattern.

Are there pros to inheriting a class template?

I'm new to c++ and I have more of a "design" question than actual code:
I'd like to write a program that works with many different types of graphs, however I want to support any type of vertex or weight (i.e the vertices are strings or char and the weight can be int,double or char or even a class).
For this cause I wrote a class template of graphs, which contains things like a set of vertices and a map with the edges and their weights and get/set functions - Then I have other classes such as finite-state machine graph, a regular weighted graph etc. which inherit from the class template "Graphs". (in each graph I know exactly what types the vertices and weights will be)
I did this as it seemed natural to expand upon a base class and inherit from it. It works so far, but then I thought whats the point? I could simple create in each class one of these generic graphs and use it as I would use an ADT from the STL.
The point being, is there any benefit to inheriting from a class template instead of just creating a new object of the template in the class (which itself isn't generic)?
According to the explanation you gave above it would be incorrect to inherit the generic graph. Inheritance is a tool to help expand an existing class of the same type to one with additional attributes, methods and functionality.
So, if all you're going to do is take the generic graph and make it a specific one by specifying the type of edges and weights without adding anything else to the structure or functionality of the original class then inheritance is unnecessary.
That being said, there are many cases for which one might need to inherit a template class and either keep it a generic one or a specific one depending on the task at hand. For example, if you were given the task of creating a class that represents a list of integers with the regular operations on lists and in addition to implement a function that return (let's say the average of these numbers or any other operation that is not supported by the original generic class List). In this case you inherit Class List and add your method.
Similarly, you could've kept the List as a template class and added the required functionality if that's what the task requires.
Your question is very broad and highly depends on your particular situation. Regardless, assuming that your question can be simplified to: "why should I use inheritance when I can just put the object inside the class?", here are two objective reasons:
Empty base optimization: if your base class X is empty (i.e. sizeof(X) == 0), then storing it as one of your derived class's fields will waste some memory as the standard forces every field to have its own address. Using inheritance will prevent that. More information here.
Exposing public methods/fields to the user of the derived class: if you want to "propagate" all your base class's public methods/fields to the derived one, inheritance will do that automatically for you. If you use composition, you have to expose them manually.

Whats a good design pattern for class that wraps shader parameter values

I am trying to design a class that would wrap shader parameter in such way that it would enable the user to easily set and get its value without a need to write a tonne of validation code outside of this class implementation.
The problem is that obviously the shader parameter values can be of different types, and whether I use templates or method overloading it results in a lot of messy code that if one was to use this class it would probably not be a very pleasant experience.
Is there some clever design pattern that once implemented would render the usage of said class to be more straightforward? I wouldn't mind if the mechanism was more complex as long as its implementation is not exposed to the user of this class.
Also just to be more clear, this shader parameter class is somewhat abstract in that its purpose is only to store the parameter for easier editing and handling across my code base. It does not interact or have any knowledge about the actual shader.
Edit 1:
Here's how I attempted to solve the issue before with templates and why I failed:
My template values were derived from a non template base class that I used to store them in a STL containers, but I have run into issues when retrieving the values and being unable to up cast them back into their template values, another issue was the amount of code needed to set and get the values when using this class implementation
Edit 2:
The ideal usage would be :
ShaderParameter* param = ShaderParameterCollection.GetParameter("color_param");
ShaderParameterCollection->GetParameter("property_name")->Set(vec3());
ShaderParameterCollection->GetParameter("property_name")->Get(&out);
ShaderParameterCollection->AddParameter("property_name", FLOAT_VEC3, vec3());
ShaderParamterCollection is just a storage class that internally uses STL container, does mapping and validation, I already have that one sorted.
What about a templated value class ? It's not a particular design pattern but could suit your needs pretty well by encapsulating :
1) your private shader data of different types and their public accessors
2) the validation code to be executed when the data are changing (coded in setters for example)
I would start by replacing the string property names that you currently have with typed keys, for example:
ShaderParameterKey<color> color_key("color_param");
ShaderParameterKey<vec3> property_key("property_name");
Then your collection methods could take a ShaderParameterKey<T> as input and return a ShaderParameter<T>. Your usage would look like:
ShaderParameter<color>* param = ShaderParameterCollection.GetParameter(color_key);
ShaderParameterCollection->GetParameter(property_key)->Set(vec3());
ShaderParameterCollection->GetParameter(property_key)->Get(&out);
ShaderParameterCollection->AddParameter(property_key, vec3());
You no longer need to pass the type (FLOAT_VEC3) to AddParameter because that is encoded in the key.
I'm not sure what issues you ran into in your previous attempt with the template base class but this solution calls for something similar.

C++ design issue. New to templates

I'm fairly new to c++ templates.
I have a class whose constructor takes two arguments. It's a class that keeps a list of data -- it's actually a list of moves in a chess program.
I need to keep my original class as it's used in other places, but I now need to pass extra arguments to the class, and in doing so have a few extra private data members and specialize only one of the private methods -- everything else will stay the same. I don't think a derived class helps me here, as they aren't going to be similar objects, and also the private methods are called by the constructor and it will call the virtual method of the base class -- not the derived method.
So I guess templates are going to be my answer. Just looking for any hints about how might proceed.
Thanks in advance
Your guess is wrong. Templates are no more the answer for your problem than inheritance is.
As jtbandes said in comment below your question, use composition.
Create another class that contains an instance of your existing class as a member. Forward or delegate operations to that contained object as needed (i.e. a member function in your new class calls member functions of the contained object). Add other members as needed, and operations to work with them.
Write your new code to interact with the new class. When your new code needs to interact with your old code, pass the contained object (or a reference or a pointer to it) as needed.
You might choose to implement the container as a template, but that is an implementation choice, and depends on how you wish to reuse your container.
Templates are used when you want to pass at compile time parameter like values,typenames, or classes. Templates are used when you want to use exactly the same class with the same methods, but applying it to different parameters. The case you described is not this I think.
If they aren't goign to be similar objects you may want to create a specialized class (or collections of function) to use from the various other classes.
Moreover you can think of creating a base class and extending it as needed. Using a virtual private method should allow you to select the method implementation of the object at runtime instead of the method of the base class.
We may help you more if you specify what does they need to share, what does your classes have in common?
The bare bones of my present code looks like this:
class move_list{
public:
move_list(const position& pos, unsigned char ply):pos_(pos),ply_(ply){
//Calculates moves and calls add_moves(ply,target_bitboard,flags) for each move
}
//Some access functions etc...
private:
//private variables
void add_moves(char,Bitboard,movflags);
};
Add_moves places the moves on a vector in no particular order as they are generated. My new class however, is exactly the same except it requires extra data:
move_list(const position& pos, unsigned char ply,trans_table& TT,killers& kill,history& hist):pos_(pos),ply_(ply),TT_(TT),kill_(kill),hist_(hist) {
and the function add_moves needs to be changed to use the extra data to place the moves in order as it receives them. Everything else is the same. I guess I could just write an extra method to sort the list after they have all been generated, but from previous experience, sorting the list as it receives it has been quicker.