Generic map objects - c++

I am trying to create an Asset Manager (Much like the one that is provided in the Libgdx library) for SFML in C++. But I am running into the age old problem of templates being one of the worst parts of C++.
I am trying to have a map object hold generic types, the key would be a simple string and the data would be any type I want it to be. Note, I don't want to template the map object to simply hold one generic type throughout the entire map (IE, the map being <string, int>). I want to have different types in the same map so I can load many different assets.
Is there any way I can do something like this?
Thank you for your help and consideration, any little tip goes a long way.

I reiterate my comment about a redesign using a map of manager instead.
Then you could have e.g.
class basic_asset_manager { ... };
class image_asset_manager : public basic_asset_manager { ... };
...
std::unordered_map<std::string, basic_asset_manager*> asset_managers;
asset_managers["image"] = new image_asset_manager;
...
// Load an image from a file
asset_managers["image"]->load("some alias for image", "/some/file/name");
...
// Get image
image = asset_manager["image"]->get("some alias for image");
Maybe not exactly like this, but you hopefully get the point.

You could define a struct or in some cases possibly use a union to pass as the second parameter of the map. Might not be the most elegant solution, but can get the job done.

Related

Is there any way to define methods for data model when using FMPP?

I want to add methods to my datamodel so I need a way to specify them inside my tdd data file(s).
For example having a tdd data file containing two scalars :
a: 1
b: 1
I would like to add a method area which multiplies them.
Is this even possible and if so how do I achieve this?
So let's say you have MyUtils that has a foo() and a bar() methods, and you want to access those in the templates.
You can add an arbitrary Java objects to the model using the eval data loader in data, like myUtils: eval('new com.example.MyUtils()'). Then you can issue myUtils.foo() in the templates. But, you wanted to add the methods at top level. That's also possible. Both in eval and in a custom DataLoader (whichever you want to use) you have access to engine, the fmpp.Engine object. And then you can pull this trick:
// Note: In case you are using eval, use Java 1.2 syntax (no generics).
TemplateHashModel myUtilsModel = (TemplateHashModel) engine.wrap(new MyUtils());
Map<String, TemplateModel> myUtilsMethodModels = new HashMap<>();
myUtilsMethodModels.put("foo", myUtilsModel.get("foo"));
myUtilsMethodModels.put("bar", myUtilsModel.get("bar"));
return myUtilsMethodModels;
Then you add that Map to data without a name. (If you add a Map to data without a name, its keys become top-level variables.)
Certainly it can be polished to be nicer, like find methods you want automatically, etc. Plus I did not try this above (so typos are possible). But this is the basic idea. (I guess it would be practical if FMPP had a data loader that loads the static methods of a class... But, right now it doesn't have that.)

Create a custom property map

I'm trying to use the write_graphml function from the Boost Graph Library. The relevant things to know are that this function takes in a dynamic property map composed of property maps for each vertex and edge property, and assumes that all properties on the vertices and edges can be resolved to character types for writing to the file. This makes sense and works for most of my properties. However, I have 1 edge property that is an enum, and so it refuses to compile.
I think what I need is to create a custom PropertyMap that basically acts as a wrapper around the one for that edge property, intercepts the accesses, and returns a character representation in place of the enum values.
Is this the right way to solve this, and if so where can I look for how to define my own custom PropertyMap? I've been digging through the docs and code and so far I'm lost.
Got some help from someone else looking closer at the error messages, and it turns out defining << for std::ostream and >> for std::istream for my custom type enabled boost to write everything properly.

Setting Custom Coders & Handling Parameterized types

I have two questions related to coder issues I am facing with my Dataflow pipeline.
How do I go about setting a coder for my custom data types? The class consists of just three items - two doubles and another parameterized property. I tried annotating the type with SerializableCoder but I still end up with the error "com.google.cloud.dataflow.sdk.coders.CannotProvideCoderException: Cannot provide coder based on value with class interface java.util.Set: No CoderFactory has been registered for the class." The Set actually contains the parameterized custom data-type - so I am assuming that the custom datatype is the problem. I could not find enough documentation/examples on the right way to do this. Please point me to the right place if its available.
Even without the custom datatype, whenever I try switching to a parameterized version of Transform functions, it results in coder errors. Specifically, inside a complex transform which is parameterized, a ParDo works with parameterized types but when I apply a Combine.PerKey on the resulting PCollection after the ParDo, it results in the CoderNotFoundException.
Any help regarding these two items would be helpful as I am kind of stuck on this for sometime now.
It looks like you have been bitten by two issues. Thanks for bringing them to our attention! Fortunately, there are easy workarounds for both while we improve things.
The first issue is that the default coder registry does not have an entry for mapping Set.class to SetCoder. We have filed GitHub issue #56 to track its resolution. In the meantime, you can use the following code to perform the needed registration:
pipeline.getCoderRegistry().registerCoder(Set.class, SetCoder.class);
The second issue is that parameterized types currently require advanced treatment in the coder registry, so the #DefaultCoder will not be honored. We have filed Github issue #57 to track this. The best way to ensure that SerializableCoder is used everywhere for CustomType is to register a CoderFactory for your type that will return a SerializableCoder. Supposing your type is something like this:
public class CustomType<T extends Serializable> implements Serializable {
T field;
}
Then the following code registers a CoderFactory that produces appropriate SerializableCoder instances:
pipeline.getCoderRegistry().registerCoder(CustomType.class, new CoderFactory() {
#Override
public Coder<?> create(List<? extends Coder<?>>) {
// No matter what the T is, return SerializableCoder
return SerializableCoder.of(CustomType.class);
}
#Override
public List<Object> getInstanceComponents(Object value) {
// Return the T inside your CustomType<T> to enable coder inference for Create
return Collections.singletonList(((CustomType<Object>) value).field);
}
});
Now, whenever you use CustomType in your pipeline, the coder registry will produce a SerializableCoder.
Note that SerializableCoder is not deterministic (the bytes of encoded objects are not necessarily equal for objects that are equals()) so values encoded using this coder cannot be used as keys in a GroupByKey operation.

How can I associate data - a string, integer or enum member - with a Gtk::ComboBoxText item?

I am using gktmm 3.0 on an Ubuntu 12.04 box with the default GCC toolchain.
In the C# world, the ComboBox class has a ComboxBox.item[n].value property, which allows you to associate each item in the comboBox with data.
I am looking for something similar in the Gtk::ComboBoxTextclass. How can I associate data - a string, integer or enum member for example - with a particular Gtk::ComboBoxTextitem?
I know that many frameworks provide a genericdata pointer on widgets for such use, as this is quite a common need.
Is there something in Gtk::ComboBoxText class or one of its parent classes that might allow me accomplish this, or do I need to set up such an association myself, using a map or other associative collection?
The Gtk::ComboBoxText append, insert() and prepend() methods allows you to specify an ID string as well as the human-visible text. For instance:
https://developer.gnome.org/gtkmm/stable/classGtk_1_1ComboBoxText.html#a19e80f4e451e23d2c00d3fb11023f9f2
But it would be clearer and more type-safe to use Gtk::ComboBox and define an actual underlying model that contains the associated data. This example uses an int, but you could use other types or use more columns:
https://developer.gnome.org/gtkmm-tutorial/stable/combobox-example-full.html.en

How to see if all data structures dependencies are solved?

Lets imagine demo situation that we have such simple structure
struct service
{
std::string name
std::set<std::string> depends_on_service_name;
};
We have some raw data (text file, io stream or what ewer) coming into our parser that turns it into service struct instances and puts them into std::map<service> services we need a way to chack if all map items have all there depends_on_service_name resolved (meaning there shall be services[item].name in map for each service[other_item].depends_on_service_name). Is there any standart way to check for such things in boost of manual for_each is the way to go each time parser appends new item(s) into map?
The "way to go" here is to solve this problem during input verification and abstraction. You are representing a directed (probably acyclic) graph with the service map, and you should represent it as such (e.g. using Boost.Graph) instead of rolling your own graph structure with sets and maps. While you are building this explicit graph structure, missing services will naturally be discovered.