fallahn / tmxlite

lightweight C++14 parser for Tiled tmx files

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

New properties constructor + property map

Eren121 opened this issue · comments

Two more proposals related to properties ^^

  1. In the map.tmx, properties are in a std::vector but a real use case is a std::map<std::string, tmx::Property> (access by name). Is it possible to de something like that ? Should eventually manage the duplicate, but that's the only edge case I see.

  2. Property do not has a constructor from C++ type. For my personal use for example, I store a map for property with default values but I must use workaround with a std::variant because Property can only be constructed from xml, I just replicate Property but with modiable content. Is it possible to support construction from float, int, std::string, etc ?

Thanks!

In the first case you are probably correct - it would make more sense to access properties by name, however this would break the API to change it. For now I would have to remain committed to std::vector. On a related note std::unordered_map would probably perform better for string keys 🙂 When loading your map you can of course copy the properties into your own map anyway - as this is what the map loader would be doing for you then there's going to be little to no noticeable difference in performance.

The second instance would, presumably, require a constructor which would look something like explicit Property(std::int32_t value) and explicit Property(bool value) so you can initialise a property object in a certain type? In this case you would need to overload the constructor for each type, which ought to be OK, as long as you don't get stung by implicit conversion (for instance between float and int). The thing with properties is that they're meant to be read-only, due to their ability to hold multiple types. Anyone who has ever written javascript will tell you the pain of having an object's underlying type mutated elsewhere in a program, leading to unexpected results 😉 Assertion helps with this of course, but I'd stop short of suggesting that we should add setters to the Property class.

Again, just my two cents as a user of this library(feel free to ignore it :) ):
I am using this small loop for retrieving the (Float)-Properties be assured, on modern processors this should be not measurable for a single digit number of properties:
for (auto& p: tileObject->properties){ if (propertyName==p.getName()){ retVal = p.getFloatValue(); } }
I made the experience that the data, if you really need it in a more flexible fashion, you should copy it to your own data structures. I see the tmxlite as a reader of tmx files. It is not my object model to work on for my game. In this way I feel that the std::vector is the correct data-type: There is a list of properties in this tmx file(may be some people store their properties in a specific sequence and need support for this, maybe somewhen it is supported to use two properties with same name..).

This is, indeed, the original intent of the library - a C++ representation of the data structures held in the xml file. It is another reason why the properties (and other classes) are all read-only. Of course, if a proposed feature makes sense and holds no unreasonable overhead, then I am also willing to consider it 😊

My current thinking is:

  • extra constructors would be fine (as long as they don't run into implicit conversion problems)
  • setters for Property values would be a bad idea
  • changing the vector for (un)ordered_map is not going to happen for API reasons, as well as this design philosophy

I've understood that the goal is retty much a "as-is" reader of the tmx files, that's why it was just propositions and I know it could go away from the initial intent. std::vector is the valid representation of a list of nodes in xml. Point 1 was just an idea. It isn't a problem of perfomance either, just a quality of life change. About unordered_map I've seen many performance patches speaking about that, but yeah it was just an idea, and not that much important, I see the problem that it could break existing code. So std::vector is probably enough, and we can use use a map in our game code.

However, Point 2 is a a bit different because there is no possibilities to access private values, so there is no way to do it. What I do actually is copy entirely the class tmx::Property but with writable state (but it's not necessary to have that much flexibility, read-only property but creatable would works perfectly). It also should not break existing code. Basically, yes only explicit Constructor(int), etc, is sufficient for it and what I request. (however, I don't know if you considerate the case Property p(true); p = Property(1.0f); as an indirect setter). The precise point is using with default properties ^^

OK, that seems reasonable enough. Having indirect setters seems like a fair trade-off. If you want to prepare a PR which does what you need with the constructors, we can take it from there 😎