wren
wren copied to clipboard
Override language primitives
If I wanted to embed wren into a game engine that has its own primitives (such as String) that have their own API, is that possible? This engine also uses reference counting instead of GC for memory management; how would these 2 systems be able to work together? Do I just hold on to the wren handle until the RC cleanup?
For the string case there is no easy way, either your API also support char* or std::string_view, or you have to convert back and forth. For refcounted objects, I think it is better to make wren objects that holds a refcounted reference (or any entity reference). It add an extra indirection, but I don't think there are no other practical solution. The "real" solution would be to drop your memory management to use make a wrapper around wren solutions. But I would not do that directly, unless wren shows to be the bottle neck, you don't want other scripting solutions, and are willing to revisit your entire API.
It does look like the string class has a char* of some sort. But I suppose I would have to expose it as its own class for using the API this string class has?
I suppose it would help me not to be vague here. I was playing around with adding Wren language support to Godot game engine. Godot does indeed have a RefCounted class that works with its RC system. All of its primitive types lie beneath a Variant class as well, which may help. The structure looks like this:
Variant
> bool
> int
> float
> String
> etc.
> Object (Used mainly for singletons by itself)
> RefCounted
> Almost everything else in the engine inherits from RefCounted.
I don't know if it would be possible to properly expose these Variant types to Wren. Sorry if this didn't make sense, I am tired.
Technically you can provide your own String class. The thing is that you'll need to guess the place where you need to convert from your string to wren string (thought a lot can already be done using the toString/fromString methods)
It is not really complicated, just tedious. You need to invoke something like in a constructor:
Variant* v = wrenSetSlotNewForeign(vm, 0, 0, sizeof(Variant));
// initialize v
And in methods and destructor uses
Variant* v = wrenSetSlotNewForeign(vm, 0);
// use v
The biggest pitfall is that you have to validate arguments outside of the binding (in wren directly before the binding), since only this (slot 0) is "guaranteed" to have the expected type.
I see. Alright, if I have any more questions, I will return.