billyquith / ponder

C++ reflection library with Lua binding, and JSON and XML serialisation.
http://billyquith.github.io/ponder/
Other
640 stars 93 forks source link

What are people using Ponder for? #53

Open billyquith opened 7 years ago

billyquith commented 7 years ago

I'm asking as the feedback might change future features and direction. This won't necessarily change things instantly. I like to mull things over a bit.

I'm current working on V2 of the API. It is largely the same but some renaming and an effort to support "modular extensions", which are uses of the registered type data. This is type data is only around for the C++ compiler at compile-time, so this gives "uses" a chance to process the type data. E.g. I've refactored the "runtime" (i.e. function calling with args) into a use. A Lua binding is another use, but currently this uses the reflection data.

I don't really want to change direction with V2 now as I've invested too much time in it already. And open source mantra says release early, release often. So it may be a little alpha, but I'm using as well.

billyquith commented 7 years ago

I'm using Ponder to try and expose useful attributes and functions in video game code. I'm hoping to use this for Lua binding, serialisation, and editing. Perhaps this could yield docs as well.

I've also been trying to expose Gwork, a GUI library I refactored. I figure if I can do this, then you can pretty much do anything, it is a suitably complex problem and as already resulted in lots of work having to be done.

If anyone would like to collaborate on a remote value editor etc...

Weeena commented 7 years ago

We plan to use ponder for the following tasks:

iwbnwif commented 7 years ago

We are using Ponder as a kind of data mapper.

It sits between the database layer and the application layer. This allows us to have abstract / generic data management functions that use the Ponder introspection to be able persist and restore data objects.

We also have some low level data view and manipulation functions that display the Ponder objects in tables and editable dialogs, although mostly the data objects are mapped to and from the application layer classes using normal C++.

The idea is to be able to leverage the full power of the database functions and maintain more control over the data schema than we previously experienced with full blown ORM such as Hibernate.

Of course, I would be interested to know if you think this is a good use of the library.

The only request would be for an error handling policy that optionally implemented asserts instead of exceptions. This would allow Ponder objects to be used more deeply in our application (maybe a good or bad thing!) without wrapping every object access in a try { ... } catch.

billyquith commented 7 years ago

@iwbnwif I don't know about the scope of your project etc. Sometimes choosing a different language can solve the problem, perhaps one with these features already. On small projects an ORM might be overkill. Difficult to comment, but I can see the attraction of wanting to automate object exposure for this purpose.

I've written serialisation and language binding code before and it often feels that you're writing the same thing again in different way. Ponder is an attempt to add a generic element, and perhaps abstract out the common features between these aspects, but then use them in different ways.

A note about going forward: In CAMP/Ponder V1 declaration of the objects and usage are conflated. E.g. calling is done on a function. In V2 we're starting to move towards object declarations creating immutable type data (introspection) and the callable part being a "use" of this, i.e. decoupled. This is more future-proof if someone wants to add a different way of calling, perhaps RPC or scripting, that don't want to use the same calling mechanism.

I've also added return policies for function callers, so we can now return internal references (e.g. singletons/owners). Generally I think this is a more flexible approach and the same technique could be applied to error handling and reporting. Identifier strings are also now trait-based so a use can replace (in theory!) with their own string type.

iwbnwif commented 7 years ago

Thank you for your comments.

One of the requirements for my project is that it basically offers various views on current and future data tables. The database itself is also able to be accessed in other ways.

In my [very limited] experience of ORM, it seems the database is tuned to reflect / serve the objects it is persisting. With the Ponder based data mapper this is reversed and the (intermediate C++) objects reflect the structure of the data. I was previously doing the same thing with a set of macros, but the Ponder way is much more elegant and easier to debug.

The mapping to higher level objects (for example for graphical visualisation) can comfortably be achieved with C++. I like and use wxWidgets so could possibly have used Python instead. However, as I am sure you know there is a huge set of readily available C++ libraries (not least of which is Boost) that helps moving things along.

In V2 we're starting to move towards object declarations creating immutable type data (introspection) and the callable part being a "use" of this, i.e. decoupled.

I am not sure I understand this (still learning lots), but are you saying the properties are set during definition, but methods can be added afterwards?

Identifier strings are also now trait-based so a use can replace (in theory!) with their own string type.

You mean it isn't necessary to use std::string? If that is the case, it would be very nice for me and save several conversions to and from wxString :)

At one point I was going to ask if it would be possible for the variant backend to be 'plugable' so it doesn't need to be mapbox. The main reason was to be able to directly access properties using the native variant type rather than via Ponder's Value type. However, I suspect that this would be very complex and end up hurting performance more than any gains through direct access. So I am happy to do the conversion using a ValueVisitor.

billyquith commented 7 years ago

@iwbnwif

I am not sure I understand this (still learning lots), but are you saying the properties are set during definition, but methods can be added afterwards?

If you mean "the properties of the function are baked" then yes. Sorry there is a bit of overloading of terminology. Ponder also has "properties", which are an abstraction layer around data members. You'll notice in V2 I've renamed a lot of things to try and avoid this confusing overloading (type vs kind, etc). You might have to rename a few things in your code, but hopefully you'll agree the result is easier to read.

To clarify, in V1 a function declaration declares a Function object, which belongs to a (meta) Class object. This Function object contains state, i.e. whether the object is callable. You and I might never use this functionality, and it thus is either baggage, or an unnecessary complication, depending on your mileage. So instead, V2 Function contains data about the function (object introspection re: reflection) only, which is immutable, i.e. no state information. Things wanting to use this information reference the same data, and don't clash with each other by perhaps conflicting use of the state information. CAMP is a reflection library, but it also has a purpose/intent in its API. In Ponder V2 we try to separate the two so that multiple things can use the data without conflict.

You mean it isn't necessary to use std::string? If that is the case, it would be very nice for me and save several conversions to and from wxString :)

In theory! 🎲 If you look at IdTraits this should contain the types to be used and the interface for conversion. I've only done this for std::string and string_view at the moment (and there should be a lot less string copying going on now). If different string type is added then this may require extensive changes throughout Ponder where strings are converted to/from other types, but it should be possible.

At one point I was going to ask if it would be possible for the variant backend to be 'plugable' so it doesn't need to be map box.

This might be possible, but as you say, at this point a rather unnecessary complication. From what I've read the Mapbox variant implementation is very efficient, even compared to Boost, so converting to/from that, if not done too often, may be more efficient. And possibly still more efficient than using a language like Python (not that I don't like Python).

A lot of this work is still in transition. V2 has taken way longer than anticipated so I need to get on with my own project. I'll probably push it out but changes will still take place. I don't really want to get into a backwards compatibility trap. There will be a bit of work patching things up due to the changes but hopefully you'll agree the result is worth it.

BlamKiwi commented 7 years ago

Initially just making plugins simpler for a wide array of scripting languages.