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

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.

Related

C++ how to implement settings of different types that are serializable/deserializable

I am trying to implement a system where I have a template class which implements a Serializable interface.
Right now, the interface contains serialize/deserialize methods while the template Setting class has get/set, and private members settingName, settingValue and a template function T adaptType() to adapt string to correct type using the >> operator (https://gist.github.com/mark-d-holmberg/862733). The file also contains a custom struct with << and >> operators overloaded for everything to work.
Settings are serialized in form of settingName:settingValue or settingName:val1;val2;val3 in case of the struct.
There are two problems I'm facing with this design:
I want to hold all these setting objects in a map<string, ISerializable*(?)> to access them but then I can't call other functions get/set on these objects because the interface doesn't define the methods (they must be in Setting class because their type depends on the template type), if I switch the second type in map to template class, I must define a concrete type
When deserializing there's no way to know which type it is and ISerializable can't be instantiated since it's an abstract class, again I need to know which type I'm deserializing and instantiate the Setting class with appropriate type
Is there a better way to design this or something I'm missing, note that I am not very proficient with c++
Bit of a background for the problem:
I'm working on an embedded device where settings need to be loaded/saved to flash memory but there's also another framework running on the device which holds these settings in RAM and serves them on a webserver to be edited, I cannot change this part. My goal is to manually save these settings to my custom class that manages settings and save/load to flash so it is persistent between reboots and synced with the web framework.
Any help or advice is welcome
As far as I understand your problem it is similar to what the Oops library is doing. It creates a Type Descriptor class for all types having similar functionality: giving some description of the type and provide text and binary serialization for them. It is also designed to handle configuration, so it even may help to solve your problem.
It worth to have a look at least for getting some ideas: https://bitbucket.org/barczpe/oops

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.

Creating a unique ID for class types C++

My goal here is to create a unique ID (starting a 0) for each child of a specific class. I'm not sure if it is possible in the way i want, but i figured i'd ask here as a last resort.
Some context:
I'm creating my own 2D game engine and i want it to have an ECS as it's back bone (Before anyone says anything, i'm doing this as a learning experience, i know i could just use an already existing game engine). My idea is that each class that implements the 'EntityComponent' class should have a unique ID applied to it. This needs to be per child, not per object. I want to use this ID as the index for an array to find the component of an entity. The actual ID that each Component gets is unimportant and each component does not need to be assigned the ID every run time.
My hope is there is some way to create something similar to a static variable per class (That implements the Entity Component class). It needs to be quick to get this value so doing an unordered_map lookup is slower than i would like. One thing i do not want to do is setting the ID for every component myself. This could cause problems once many components are made and could cause problems if i forget to set it or set two components to the same ID.
One idea i had was to make a variable in EntityComponent called ID (And a getter to get it). When the entity is constructed it looks up an unordered map (which was made at run time, assigning an ID to each class) for what ID it should have. The price of looking up once at construction is fine. The only problem i see with this is there is a lot of redundant data (Though overall it seems it would account to a pretty small amount). With this, every single transform component would have to store that it its ID is x. This means potentially thousands upon thousands of transform components are storing this ID value, when only 1 really needs to.
Basically i am after an extremely quick way to find an ID for a class TYPE. This can be through a lookup, but it needs to be a quick lookup. I would like something faster than unordered_map if possible. If this can be done through compile time tricks (Maybe enums?) or maybe even templates i would love to hear your ideas. I know premature optimisation is the bad, but being able to get a component fast is a pretty big thing.
What i'm asking might very well be impossible. Just thought i'd ask here to make sure first. I should also note i'm trying to avoid implementation of this in the children classes. I'd like to not have to set up the same code for each child class to create an id.
Thank you.
In order to get something corresponding to the actual type of an object, it either needs to be in the object itself or accessed via a virtual function. Otherwise the type will be determined by the type of the variable it is associated with.
A common option when speed and size are both important is to have an integer identifier associated with each type (when the full type list is known at compile time) and use that integer value in a specific way when you want to do something based on the type.
The integer mechanism usually uses an enum for generating the corresponding value for each type and has that field in every object.
The virtual method variety, I've used boost::uuid and a static data member in each class and a virtual method get'er for it.
Declare a virtual function newId() in EntityComponent.
Implement this function to get and increment a static variable in each class, which children you want to have a unique Id.
Assign Id in the constructor:
mId = newId();
don't know this if this is what you meant and i know this is an old post however this is how im currently dealing with a similar issue, maybe it will help someone else.
(Im also doing this as a learning experience for uni :) )
in the controlling class or its own utility class:
enum class EntityType{ TYPE_ONE = 0, TYPE_TWO =1};
in class header:
#include "EntityType.h"
class Whatever{
public:
inline void getType(){return _type;}
OR
inline void getType(){return EntityType::TYPE_ONE;}
private:
EntityType _type = EntityType::TYPE_ONE;
};
Hope this is helpful to anyone :)

Proxy class for polymorphic type, using templates

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.

Flexible application configuration in C++

I am developing a C++ application used to simulate a real world scenario. Based on this simulation our team is going to develop, test and evaluate different algorithms working within such a real world scenrio.
We need the possibility to define several scenarios (they might differ in a few parameters, but a future scenario might also require creating objects of new classes) and the possibility to maintain a set of algorithms (which is, again, a set of parameters but also the definition which classes are to be created). Parameters are passed to the classes in the constructor.
I am wondering which is the best way to manage all the scenario and algorithm configurations. It should be easily possible to have one developer work on one scenario with "his" algorithm and another developer working on another scenario with "his" different algorithm. Still, the parameter sets might be huge and should be "sharable" (if I defined a set of parameters for a certain algorithm in Scenario A, it should be possible to use the algorithm in Scenario B without copy&paste).
It seems like there are two main ways to accomplish my task:
Define a configuration file format that can handle my requirements. This format might be XML based or custom. As there is no C#-like reflection in C++, it seems like I have to update the config-file parser each time a new algorithm class is added to project (in order to convert a string like "MyClass" into a new instance of MyClass). I could create a name for every setup and pass this name as command line argument.
The pros are: no compilation required to change a parameter and re-run, I can easily store the whole config file with the simulation results
contra: seems like a lot of effort, especially hard because I am using a lot of template classes that have to be instantiated with given template arguments. No IDE support for writing the file (at least without creating a whole XSD which I would have to update everytime a parameter/class is added)
Wire everything up in C++ code. I am not completely sure how I would do this to separate all the different creation logic but still be able to reuse parameters across scenarios. I think I'd also try to give every setup a (string) name and use this name to select the setup via command line arg.
pro: type safety, IDE support, no parser needed
con: how can I easily store the setup with the results (maybe some serialization?)?, needs compilation after every parameter change
Now here are my questions:
- What is your opinion? Did I miss
important pros/cons?
- did I miss a third option?
- Is there a simple way to implement the config file approach that gives
me enough flexibility?
- How would you organize all the factory code in the seconde approach? Are there any good C++ examples for something like this out there?
Thanks a lot!
There is a way to do this without templates or reflection.
First, you make sure that all the classes you want to create from the configuration file have a common base class. Let's call this MyBaseClass and assume that MyClass1, MyClass2 and MyClass3 all inherit from it.
Second, you implement a factory function for each of MyClass1, MyClass2 and MyClass3. The signatures of all these factory functions must be identical. An example factory function is as follows.
MyBaseClass * create_MyClass1(Configuration & cfg)
{
// Retrieve config variables and pass as parameters
// to the constructor
int age = cfg->lookupInt("age");
std::string address = cfg->lookupString("address");
return new MyClass1(age, address);
}
Third, you register all the factory functions in a map.
typedef MyBaseClass* (*FactoryFunc)(Configuration *);
std::map<std::string, FactoryFunc> nameToFactoryFunc;
nameToFactoryFunc["MyClass1"] = &create_MyClass1;
nameToFactoryFunc["MyClass2"] = &create_MyClass2;
nameToFactoryFunc["MyClass3"] = &create_MyClass3;
Finally, you parse the configuration file and iterate over it to find all the entries that specify the name of a class. When you find such an entry, you look up its factory function in the nameToFactoryFunc table and invoke the function to create the corresponding object.
If you don't use XML, it's possible that boost::spirit could short-circuit at least some of the problems you are facing. Here's a simple example of how config data could be parsed directly into a class instance.
I found this website with a nice template supporting factory which I think will be used in my code.