Thank you for you quick reply. The issue was indeed the namespace which wasn't the default one (I'm trying to organize all the API I'm exposing).
I'm still dubious regarding some design aspects: to avoid using static references to the engine or context: I have a native method which registers a builder able to instantiate an AngelScript class and forward some native calls to the AS instance. This is done by the script itself to register some scripted classes as target of game logic.
I do this by class name, eg:
static bool registerObjectRenderer(const std::string& object, const std::string& className)
{
const ObjectSpec* spec = Data::d().object(object);
class ScriptedObjectNodeFactory : public ::gfx::ObjectNodeFactory
{
private:
asIScriptFunction* factoryMethod;
asIScriptFunction* generateMethod;
asIScriptFunction* updateMethod;
asIScriptFunction* setSelfMethod;
public:
ScriptedObjectNodeFactory(const std::string& className, asITypeInfo* type)
{
generateMethod = type->GetMethodByDecl("void generate()");
updateMethod = type->GetMethodByDecl("void update(float dt)");
setSelfMethod = type->GetMethodByDecl("void setSelf(gfx::objects::SuperObjectGfxNode@ self)");
factoryMethod = type->GetFactoryByDecl(fmt::format("{} @{}()", className, className).c_str());
}
::gfx::ObjectNode* build(const Object* object) const override
{
auto* objectNode = new modding::as::classes::ObjectNode(object, ASE::context, generateMethod, updateMethod);
ASE::context->Prepare(factoryMethod);
ASE::context->Execute();
asIScriptObject* scriptObject = *reinterpret_cast<asIScriptObject**>(ASE::context->GetAddressOfReturnValue());
objectNode->setScriptObject(scriptObject);
int r = ASE::context->Prepare(setSelfMethod); assert(r >= 0);
r = ASE::context->SetObject(scriptObject); assert(r >= 0);
r = ASE::context->SetArgObject(0, objectNode); assert(r >= 0);
r = ASE::context->Execute(); assert(r >= 0);
return objectNode;
}
};
asITypeInfo* type = ASE::module->GetTypeInfoByDecl(className.c_str());
assert(type);
::gfx::Gfx::data.registerObjectRenderer(spec, new ScriptedObjectNodeFactory(className, type));
return true;
}
Now, this works but require a static reference to the context and to the module containing the definition (in the code stored in ASE::context
and ASE::module
).
So I wonder which is the best practice here to avoid these references, the method is registered in the engine through
registerFunction("bool registerObjectRenderer(const string& in object, const string& in className)", CALL_FUNCTION(gfx::registerObjectRenderer), "register a class as renderer of a specific object, class must inherit ObjectGfxNode interface");