how to go from Fabric::EDK::KL::RTVal to FabricCore::RTVal ?

benblobenblo Posts: 29

Given: function bla(RTVal val) = "bla";, kl2edk generates a cpp function with a Fabric::EDK::KL::RTVal argument... but KL::RTVal doesn't define any relevant methods at all, only FabricCore::RTVal does. Casting doesn't work (nice segfault), so how do I get there?

I see the EDK version only has an m_bits pointer, that in turn only seems to have an m_refCount. Somehow that still has to point to an actual RTVal (right??), which in turn is a Ref that points to an actual object, eventually (one can hope :)).
I fail to see the distinction between KL::RTVal and FabricCore::RTVal, isn't that one too many indirection?

Overall, I don't understand the EDK namespace, seems like it redefines empty shells for Core classes (String etc). Also, Object is again redefined in a kl2edk-generated .h.
... what for?

R&D Developer at Dwarf Animation Studio

Tagged:

Best Answer

Answers

  • pzionpzion Moderator, Fabric Employee Posts: 118 Fabric Employee

    There is quite a difference between what an RTVal looks like outside of Fabric, what FabricCore.h is for, and what it looks like inside running KL code, what FabricEDK.h is for. The types in the EDK must be exact C++ replicas of the KL types so that we can call C++ functions without doing any conversions; this is important for performance.

    While it would be technically possible to allow for RTVal interaction from the EDK, it would be quite difficult to do so because we would essentially be converting in the opposite direction. The EDK wasn't designed with complex interactions with KL in mind. Rather, the EDK is used to provide lightweight wrappings for C/C++ libraries that don't know about Fabric or KL.

    One thing you can do from the EDK is call interface (but not non-interface) functions on KL objects.

    Maybe if you give some details about what we need to do we can offer some suggestions about how to best accomplish it.

    Peter Zion
    Fabric Engine

  • benblobenblo Posts: 29

    Yeah, I'm slowly wrapping my head around how things interconnect. I finally managed to hook up a debugger and saw that the value passed to EDK is actually a Fabric::RTVal, not a FabricCore::RTVal, which we don't have the headers for.

    What I'm looking for, basically, is reflection, from KL.
    There are quite a lot of things you can do from C++ or from Python, but not from KL; I find that... paradoxical.

    Right now, I want to walk through some data, iterate through all members of the types I encounter (to do custom serialization etc). Since the data I'm considering is POD (structs only, no objects), which doesn't have a base type, I figured I'd pass it to my walker as RTVal.
    But RTVal in KL is seriously crippled, eg it doesn't have any of those is/get/set: http://docs.fabric-engine.com/FabricEngine/2.3.1/HTML/RTValProgrammingGuide/capi.html#api-reference
    So I figured ok, let's just do it in C++... nope.

    I'd also like to be able to construct a KL object/struct/RTVal from json (actually from any format but json seems the most reachable right now).
    FEC_RTValGet/SetJSON is tantalizing... but it requires a ContextRef, which I don't know how to get from an extension.
    I tried hooking up IMPLEMENT_FABRIC_EDK_ENTRIES_WITH_SETUP_CONTEXT_CALLBACKS: setupCallback gets fired, contextCallback doesn't.
    I tried s_callbacks.m_getContextPtr(), but then using that with FEC_RTWhateverThatRequiresAContext() gives me a segfault... ;(

    There are other things I'd like to do, but this should be a good start :) !

    R&D Developer at Dwarf Animation Studio

  • benblobenblo Posts: 29

    OK... so I figured out how to get almost everything by creating my own client (FEC_ClientGetSingleton), and then using the CAPI to get the info I need. Only thing I'm missing is the ability to call methods, but that can wait.
    Problem is... the client returned by FEC_ClientGetSingleton is empty, I have to loadExtension to get any RT info. That's slow.

    So basically, all I need to know is: how do I get a usable FEC_ContextRef from s_callbacks.m_getContextPtr()?

    I finally figured out that s_callbacks.m_getContextPtr() returns a Fabric::DG::Context.
    FEC_ClientGetSingleton returns a Fabric::CAPIClientRef, and the associated fecContextRef is a Fabric::CAPIWeakRef...

    R&D Developer at Dwarf Animation Studio

  • pzionpzion Moderator, Fabric Employee Posts: 118 Fabric Employee

    First, obtaining the singleton client from within executing KL code is not something we test at all, so I'm not sure it will work. That said, I don't immediately see that there would be a problem, as long as you're not calling it from different threads (in which case a deadlock could occur).

    There is the very first client that is created to start using Fabric. If that client is not also created via FabricCore::Client::GetSingleton then I think you will get a null client if you call GetSingleton later. So this is where I would look. I'm not sure what your code is that "starts up Fabric", hopefully it's something where it's easy to change a call from FabricCore::Client::Create to FabricCore::Client::GetSingleton.

    Peter Zion
    Fabric Engine

  • benblobenblo Posts: 29

    Thanks Peter.

    @pzion said:
    First, obtaining the singleton client from within executing KL code is not something we test at all, so I'm not sure it will work. That said, I don't immediately see that there would be a problem, as long as you're not calling it from different threads (in which case a deadlock could occur).

    Well I've tested it, and I can tell you it works for me :), from the main thread.

    There is the very first client that is created to start using Fabric.

    Yes! that! how do I get that one?

    If that client is not also created via FabricCore::Client::GetSingleton then I think you will get a null client if you call GetSingleton later.

    No, I don't get a null client, I get a different client (a new one the first time I call, then the same one afterwards).
    This is consistent with what the docs say.

    So this is where I would look. I'm not sure what your code is that "starts up Fabric", hopefully it's something where it's easy to change a call from FabricCore::Client::Create to FabricCore::Client::GetSingleton.

    Well right now I'm using canvas.py, but long term I also need it to work from Maya, so no I can't really change the code, I need the initial client.

    Or rather, I need the client that's executing the KL code that's calling the C++ lib. You haven't answered my previous question: what's the s_callbacks.m_getContextPtr() for? Any way I could use that? The RT function of the CAPI take a context anyway (not a client), so that seems to be it, doesn't it?

    I've noticed that when I create the singleton client, the C++ lib is loaded again (or at least its SETUP_CALLBACK is called again), so it would seem like 1 client = 1 "lib context", so I don't see why I couldn't have access to it...

    R&D Developer at Dwarf Animation Studio

Sign In or Register to comment.