Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Custom user types (STL/math primitives) #107

Closed
rokups opened this issue Jul 8, 2020 · 5 comments
Closed

Custom user types (STL/math primitives) #107

rokups opened this issue Jul 8, 2020 · 5 comments
Labels
enhancement New feature or request
Milestone

Comments

@rokups
Copy link
Contributor

rokups commented Jul 8, 2020

The Problem

I am experimenting with integrating RmlUI into my project. Since it uses EASTL instead of standard library i am in a position where types of both libraries are interchangeable and yet a conversion has to be made each time i would like to pass a eastl::string to RmlUi. Similarly RmlUi vector types are incompatible with whatever math primitive types user's application is using, which creates an inconvenient requirement of manually converting these types in some cases where it does not make sense to only use RmlUi math types.

What can we do

std types

Actually RmlUi is some way there already. RMLUI_NO_THIRDPARTY_CONTAINERS and type aliases exist to facilitate use of different container types in some places. We could expand use of these aliases and provide means for user to inject their own aliases and includes to Types.h. Not only this would allow using alternate container types, it would also bring in a little more code style consistency into RmlUi.

Math primitive types

I do not have a full answer for this one yet. One thing we could do is provide some preprocessor defines that user could set in config header, implementing conversion between RmlUi math primitive types and user-defined types. This is what Dear ImGui does. It gets us half-way as this change would allow user to pass their own math primitives and compiler would do a conversion for us. I do not have an answer for output parameters (non-const references) however.


Do you think this is something that RmlUi should have? I have a working proof of concept conversion done already. RmlUi builds with EASTL. Aside from replacing std::T with custom aliases, only few minor modifications were needed to make RmlUi compatible with EASTL. If you find these ideas acceptable i can submit a PR.

@mikke89
Copy link
Owner

mikke89 commented Jul 8, 2020

I like the idea. Of course, the library types would have to be compatible with their std counterparts, at least to a large extent. The feature should be clearly labeled with a "no-guarantees" given warning. I think it's great even if you just want to replace std::string with std::u8string, or use custom allocators in the containers.

For vector and color types we could do the same as the example in Dear ImGui you link to. Output parameters should work the same, right? It should automatically handle the implicit conversion when assigning from the user type. On a related note, we should really pass these types by value instead of reference through the API (for input parameters).

Matrices are a bit heavier though, I'm not sure if users really want implicit conversions? I guess it would be up to the user to decide anyway.

I also wonder a bit regards to how it should work with the CMake integration?

If this change can be done with minimal changes to the source code, ie. mostly header file changes, then I'd like to see this implemented :) A PR would be nice.

@mikke89 mikke89 added the enhancement New feature or request label Jul 8, 2020
@rokups
Copy link
Contributor Author

rokups commented Jul 8, 2020

Output parameters should work the same, right? It should automatically handle the implicit conversion when assigning from the user type.

I dont think we can do

Rml::SomeApi(Rml::Vector3& out);
MyVector3 out;
Rml::SomeApi(out);

I would be very surprised if that worked with implicit typecast operators 👀

I also wonder a bit regards to how it should work with the CMake integration?

Depends.. We might not need anything at all on CMake's side. If we have something like RmlUserConfig.h then user could define all preprocessor defines in there, put into some known location and call it a day. Maybe we could use a CMake option for providing a custom path to RmlUserConfig.h. Any includes should be relative, that would avoid RmlUi lib having to link to whatever stdlib target. Thats it.

If this change can be done with minimal changes to the source code, ie. mostly header file changes, then I'd like to see this implemented :)

I threw my WIP changes into a git repo. Its still early so some things are missing. I did not add new aliases for stdlib, also i did not touch any of lua support as i am not using it myself. Main meat and bones is in Types.h. I had to introduce wrapper functions MakeShared(), MakeUnique() and MakeMoveIterator(). Also had to remove final from Releaser class as it somehow did not work with EASTL. I did not touch std::pair<> because for some reason it broke a lot of things, fixing which turned into cascade of weird changes, including making wrappers for sorting functions. Just for the sake of completeness I should still add an alias to std::pair<> even if i wont be using it myself.

@rokups
Copy link
Contributor Author

rokups commented Jul 8, 2020

Hey @mikke89 i see there is using Matrix4f = ColumnMajorMatrix4f;. Can we simply switch to row-major matrices by modifying that? If so, seems like it would make sense to include that into config header as well.

@uniquejack
Copy link

That's a very good suggestion, I also use custom containers in my engine, it would be cool to overwrite Vector and String containers, don't care that much about the other math types, I can simply convert them.

@mikke89
Copy link
Owner

mikke89 commented Jul 8, 2020

Looks like a good start @rokups !

I would be very surprised if that worked with implicit typecast operators 👀

I see what you mean now, yes, this wouldn't work. I guess the user will either have to live with it, or we could go crazy and start replacing all the member functions with non-member functions that the user can customize. I'm not really a fan unless somebody has better suggestions.

Depends.. We might not need anything at all on CMake's side. If we have something like RmlUserConfig.h then user could define all preprocessor defines in there, put into some known location and call it a day. Maybe we could use a CMake option for providing a custom path to RmlUserConfig.h. Any includes should be relative, that would avoid RmlUi lib having to link to whatever stdlib target. Thats it.

I like the config file suggestion. Proposed CMake changes:

Add a new configuration option CUSTOM_CONFIG_FILE which the user can point to a file of their choice, and which sets a macro to replace the default configuration. Maybe a bool option to enable this first?

We could replace the NO_THIRDPARTY_CONTAINERS option with a selection between eg. "mixed std and internal containers" (current default), "std only", and "custom containers".

The latter option should require a custom config file, and enable a new option, eg:

  • CUSTOM_CONTAINERS_INCLUDE_DIRS. Adds the provided include directory to all targets.
  • Maybe also an option to include libraries, then again I guess most of these libraries are headers only?

Of course this is just some initial thoughts. Names and configurations are open for suggestions.

Maybe I'm overthinking this, but it would be nice to select between std only, current default (included containers), and custom. Maybe just add the std vs internal containers as two different configuration files that the user can point to, or select their own path?

I threw my WIP changes into a git repo. Its still early so some things are missing. I did not add new aliases for stdlib, also i did not touch any of lua support as i am not using it myself. Main meat and bones is in Types.h. I had to introduce wrapper functions MakeShared(), MakeUnique() and MakeMoveIterator(). Also had to remove final from Releaser class as it somehow did not work with EASTL. I did not touch std::pair<> because for some reason it broke a lot of things, fixing which turned into cascade of weird changes, including making wrappers for sorting functions. Just for the sake of completeness I should still add an alias to std::pair<> even if i wont be using it myself.

This is a great start. I don't see any big issues with these changes. Although we would need to change all the samples and Lua bindings as well.

Hey @mikke89 i see there is using Matrix4f = ColumnMajorMatrix4f;. Can we simply switch to row-major matrices by modifying that? If so, seems like it would make sense to include that into config header as well.

Yup, this would be great to add to the configuration file :)

@mikke89 mikke89 added this to the 4.0 milestone Jul 12, 2020
Unicornum added a commit to Unicornum/Externals.RmlUi that referenced this issue Aug 1, 2020
* Create data binding sample

* add virtual dcon to Rml::Core::Releasable

* Fix CMake 3.17 STRING warning

CMake Warning (dev) at CMakeLists.txt:29 (set):
  implicitly converting 'string' to 'STRING' type.
This warning is for project developers.  Use -Wno-dev to suppress it.

* Update number parser procedure. Fixes mikke89#102. Improves performance.

* X11 Shell: Consider additional paths for the assets directory. More robust, and makes remote compilation/debugging on WSL from Visual Studio work with default configuration.

* Use the F8 key to toggle the debugger on all platforms.

* Fix warnings on GCC and Clang with -Wall -pedantic

* Fix warning on MSVC

* Travis: Add warning and pedantic compilation flags

* Fix some additional warnings in GCC

* Property 'white-space: nowrap' should not disable scrollbars on overflow. See mikke89#94.

* Dirty font effects when the 'font-effect' property is changed. Fixes mikke89#98.

* Fix structural pseudo-selectors only being applied if written with parenthesis. See mikke89#30.

* Remove the StringCache. See mikke89#96.

* Windows shell: Add another candidate path for the samples folder search.

* Selection box: Prevent scrolling the parent window when hovering over the drop down list.

* Select element: Close select box if parent document is scrolled.

* Reduce memory allocations while parsing the 'style' attribute.

* Do not require a final semi-colon while parsing the 'style' attribute.

* Fix possible wrong layout in widget slider

* Make project C++20 compatible

* CMake: Enable the C++14 standard project-wide.

* Element 'select': Automatically position and size the selection box to the available space within the context's window dimensions. See mikke89#91.

* ShellX11: Load and activate mouse cursors.

* Update changelog.

* Fix geometry not setting its host element or context on construction

* Several warnings fixed with '-Wall -Wextra' and on MSVC with '/W4'.

* Enhanced Tracy profiler CMake configuration. Add separate build configuration.

* Element 'select': Respect 'height' property on selectbox set by user in style sheet.

* Add missing include

* Fix SFML and SDL samples on Windows.

* Add sdl2_image include to CMakeLists.txt

* Fix tiled decorator alignment not working.

* Release RmlUi 3.3

* Start working on RmlUi 4.0

* Update gitignore

* Debugger: Display contents of text elements

* Debugger: Use pre-wrap in event log. Display beacon if messages are logged during application start-up.

* Try fixing problems from the None macro in X11 (ugh)

* Add forward to flat_map and flat_set emplace

* XMLNodeHandlerTabSet: 'tabs' and 'panels' should return null

* Basic implementation of data binding (WIP)

* Make DataViewText take a text element, replacing its text contents with the data binding.

* Set values on data view constructions. Add attribute view.

* Remove handling of data binding in xml parser

* Add data controller for attributes

* Make slider widget update attribute on value change

* Update utf8 string iterator

* Add DataViewIf

* Make Variant constructors explicit

* Variant: Add bool, double, int64 types, remove word.

* Add type converters for double, int64_t

* Implement data types

* Refactor data bindings

* Add data view for style

* Start implementing data view 'for' (highly WIP)

* Experimenting with approach for nested variables in structs and arrays.

* Data variables address parsing and get/set values

* Make data arrays safer, no need for Update

* Refactor, move the new data variable types into the library. Now working 'for' loops for structs.

* Custom iterator name in data-for

* Better parsing in data-for: Nested for loops now work.

* Safely add and remove data views during iteration, and clean up data views on element removal.

* Only update dirty data variables

* Some cleanup

* Getters and setters for data struct members

* Add arbitrary get/set functions as data binding

* Clean up data binding API

* Update data controller

* Data types now associated with the Context. Clean up data model.

* Move creation of data views and controllers to ElementUtilities. Clean up.

* Data views: recursively update

* Start creating a parser for data views

* Trim trailing zeros in float converted to String. Remove PrettyFormatNumbers from debugger.

* Add data expression transform functions (callbacks).

* Add data-class and data-rml

* XML Parser: Ignore <tags> in {{ double brackets }}

* Read in whole document in xml parser before parsing.

* Handle raw inner xml contents of data-for elements more robustly.

* Some refactoring of DataViews. Move the default DataViews to separate files.

* - Implemented 'data-event' controller. Can use assignment in its expression, and also 'ev.' variable name to fetch parameters from the event.
- Move default controllers to separate file.
- The 'data-value' controller now uses the 'change' event to listen for value changes.
- Get size on data array variables by .size member.

* Make initialization of data views and controllers safer

* Update comments. Generalize XMLParser. Data model and variables refactoring.

* Add additional operator precedence in data parser. Add more tests. Add format() and round() transform functions to data parser.

* Robustify text elements from illegal syntax.

* Better warnings.

* Start data binding example with invaders

* Implement it_index in data view for. Rename some functions.

* Add data view: visible

* Clean up data binding sample, add a basic example.

* Fix headers

* In Element: Set parent just after inserting child element.

* Add missing headers

* Add ability to retrieve an existing data model from Context.

* DataModel make views and controllers internal.

* Rename DataParser file to DataExpression. Some cleanup.

* Fix removal of event listener in data-event.

* Enable removal of data model from context.

* Unify parsing of curly brackets in RML.

* The big restructuring for RmlUi 4.0. This involves breaking changes but should benefit everyone using the library in the future.

- The old `Controls` plugin is now gone. But fear not! It has been merged into the `Core` project .
- The old `Rml::Core` and `Rml::Controls` namespaces are now located directly in the `Rml` namespace.
- The old `Controls` public header files have been moved to `<RmlUi/Core/Elements/...>`.
- The old `Controls` source files and private header files have been moved to `Source/Core/Elements/...`.
- The `Debugger` plugin remains as before at the same location and same namespace `Rml::Debugger`.

The Lua plugins have been changed to reflect the above changes.

- The old Lua plugins `RmlCoreLua` and `RmlControlsLua` have been merged into a single library `RmlLua`.
- The public header files are now located at `<RmlUi/Lua/...>`.
- The Lua plugin is now initialized by calling `Rml::Lua::Initialise()` located in `<RmlUi/Lua/Lua.h>`.
- Separated the Lua interpreter functions from initialization and the Lua plugin.
- Renamed macros in the Lua plugin, they now start with `RMLUI_`.

Related changes.

- Refactored slider widgets to avoid duplicate names in Core and Controls.
- Renamed header guard macros.

* Update changelog

* Add some missing files to RmlUi/Core.h

* Refactor some of the Transform functionality. Move functions that should only be called internally to an internal TransformUtilities. Rename Transforms::Primitive to TransformPrimitive.

* Initialize OpenGL viewport directly before rendering the gui

* Add view to sfml2 example

* Remove Resize method

* Update readme

* Fix compilation and warnings in shared libraries.

* Update changelog

* Fix mingw build

* Move target_link_libraries to shell, and rename WIN32 to RMLUI_PLATFORM_WIN32

* Fix win32 shell compilation issue in some environments.

* Add a note for the lifetime requirement of 'LoadFontFace' from memory.

* Add FamilyId to std::hash.

* Add MinGW build to AppVeyor configuration. Small tweak to Travis.

* Fix warning in SFML sample.

* Initial document_base_tag branch

* code cleanup

* Implement `Element::QuerySelector` and `Element::QuerySelectorAll`.

* Fix build with EASTL when it is configured to use size_type different from size_t.

* Add ability for user to override container types.

Resolves mikke89#107.

* Extend example of custom type conversion operators.

* Update Include/RmlUi/UserConfig.h

Co-authored-by: Michael R. P. Ragazzon <mikke89@users.noreply.github.com>
Update Include/RmlUi/Core/Types.h

Co-authored-by: Michael R. P. Ragazzon <mikke89@users.noreply.github.com>

* Move config file into a subdir and include it in Traits.h and Types.h

* Some cleanup and warning fixes.

* Update CMake for custom configuration.

Co-authored-by: Michael Ragazzon <michael.ragazzon@gmail.com>
Co-authored-by: SpaceCat~Chan <49094338+SpaceCat-Chan@users.noreply.github.com>
Co-authored-by: Michael R. P. Ragazzon <mikke89@users.noreply.github.com>
Co-authored-by: Jan Niklas Hasse <jhasse@bixense.com>
Co-authored-by: Karsten Hachmeister <karsten@hachmeister.org>
Co-authored-by: Cloud Wu <cloudwu@gmail.com>
Co-authored-by: aquawicket <aquawicket@hotmail.com>
Co-authored-by: Rokas Kupstys <rokups@zoho.com>
Co-authored-by: Rokas Kupstys <19151258+rokups@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

3 participants