Author Topic: AngelScript questions (not related to FOnline API)  (Read 9973 times)

JovankaB

  • Guest
AngelScript questions (not related to FOnline API)
« on: June 21, 2012, 09:58:40 am »
It's a single topic to ask all general questions about AngelScript scripting, or some weird stuff like DLLs,
not related to FOnline API directly (for example questions about arrays, objects, pointers etc).
« Last Edit: June 21, 2012, 10:01:37 am by JovankaB »

Offline wladimiiir

  • Rotator
  • Independent FOnline developer
Re: AngelScript questions (not related to FOnline API)
« Reply #1 on: May 21, 2013, 09:13:03 am »
How do I share an interface between C++ and AngelScript code? What I want is to define an interface in C++ code (.cpp) and then implement it somewhere in AngelScript code.

I am aware that I need to use:
Code: [Select]
ASEngine->RegisterInterface("IAction");and then probably
Code: [Select]
ASEngine->RegisterInterfaceMethod("IAction", "int test()");to register its methods.

But how do I bind it in my AS code so I can really use it?

Offline Wipe

  • Rotator
  • Random is god
Re: AngelScript questions (not related to FOnline API)
« Reply #2 on: May 21, 2013, 09:40:27 am »
Does it really have to be interface? With classess it's much easier ;)
Games are meant to be created, not played...

Offline wladimiiir

  • Rotator
  • Independent FOnline developer
Re: AngelScript questions (not related to FOnline API)
« Reply #3 on: May 21, 2013, 09:46:19 am »
OK, so actually the solution I wrote is sufficient, so if you want to use some shared interface, the only thing is that you have to register it in C++ code.
My problem was that I have created a new .cpp file where I wanted to declare my interface and do stuff with it. Registering interface in such a new file does not really register it and I had to move my declaration to fonline_test.cpp and register it there.

So my question is:
How do I make my new .cpp file get used by the engine. Is this even possible or I have to use fonline_tla.cpp and/or fonline_test.cpp files?

Offline wladimiiir

  • Rotator
  • Independent FOnline developer
Re: AngelScript questions (not related to FOnline API)
« Reply #4 on: May 21, 2013, 09:47:51 am »
Does it really have to be interface? With classess it's much easier ;)
Is it? In which way? What I need is to be able to create new implementations of the interface, although, I think I might end up with some (abstract) classes.

Offline Bartosz

  • Rotator
  • There'd better be a killer reason...
Re: AngelScript questions (not related to FOnline API)
« Reply #5 on: June 06, 2013, 11:12:56 am »
How do I make my new .cpp file get used by the engine. Is this even possible or I have to use fonline_tla.cpp and/or fonline_test.cpp files?

Check the Makefile which is used to build the dll, you need to configure it to build your additional cpps as well (it's in scripts directory).

Offline wladimiiir

  • Rotator
  • Independent FOnline developer
Re: AngelScript questions (not related to FOnline API)
« Reply #6 on: June 06, 2013, 11:30:55 am »
Check the Makefile which is used to build the dll, you need to configure it to build your additional cpps as well (it's in scripts directory).
I already have dll compiled. My question is, how does the server load these dlls? Is it hardcoded in the server, what dlls should be used? This is not really clear to me.

Offline Bartosz

  • Rotator
  • There'd better be a killer reason...
Re: AngelScript questions (not related to FOnline API)
« Reply #7 on: June 06, 2013, 11:32:30 am »
pragma bindfunc with dll as module causes the library to be loaded:

Code: [Select]
// Test function
# ifdef __SERVER
#  pragma bindfunc "void TestFunc(string&) -> fonline_test.dll TestFunc"
# endif
# ifdef __CLIENT
#  pragma bindfunc "void TestFunc(string&) -> fonline_test_client.dll TestFunc"
# endif

Offline wladimiiir

  • Rotator
  • Independent FOnline developer
Re: AngelScript questions (not related to FOnline API)
« Reply #8 on: June 06, 2013, 12:46:33 pm »
Cool, thanks. :)

Offline wladimiiir

  • Rotator
  • Independent FOnline developer
Re: AngelScript questions (not related to FOnline API)
« Reply #9 on: June 10, 2013, 02:42:48 pm »
I have an interface defined in C++:
Code: [Select]
class IFoo
{
    public:
        virtual void FooMethod();
};

I have registered the interface in AngelScript engine:
Code: [Select]
ASEngine->RegisterInterface("IFoo");
ASEngine->RegisterInterfaceMethod("IFoo", "void FooMethod()");

I have a script (foo.fos) with implementation of this interface:
Code: [Select]
class FooImpl : IFoo
{
   void FooMethod() {/*doing something totally useful*/}
}

I have also registered Global function which I am calling from my script with new instance of my FooImpl class as parameter:
Code: [Select]
ASEngine->RegisterGlobalFunction("void RetrieveFoo(IFoo& foo)", asFUNCTION(RetrieveFoo), asCALL_CDECL);
And I have my RetrieveFoo function in C++ code:
Code: [Select]
void RetrieveFoo(asIScriptObject* obj)
{
    if(obj == NULL)
   {
        Log("No object has been passed");
        return;
   }

   //I want to do something with passed FooImpl
}

My question is:
Is it possible to cast asIScriptObject* obj to IFoo interface and directly call FooMethod() or I have to do it the "ugly" way, which makes the interface useless (creating context, getting function to call, setting parameters, and executing it)?

Offline Bartosz

  • Rotator
  • There'd better be a killer reason...
Re: AngelScript questions (not related to FOnline API)
« Reply #10 on: June 10, 2013, 03:51:27 pm »
Nope, you still need to do call using provided API.

Offline wladimiiir

  • Rotator
  • Independent FOnline developer
Re: AngelScript questions (not related to FOnline API)
« Reply #11 on: June 10, 2013, 04:26:37 pm »
Yeah, I found out that my assumption was incorrect. I actually have no inheritance relationship between my C++ interface and AS implementation class. And it is not possible to create one, I guess.
But the best solution I can do is to create an implementation class of my C++ IFoo interface in C++, that would wrap asIScriptObject and it would call the functions using the API. Something like this:
Code: [Select]
class Foo : IFoo
{
    protected:
        asIScriptObject* asFoo;

    public:
        FooScript(asIScriptObject* obj)
       {
            asFoo = obj;
            obj->AddRef();
       }
        ~FooScript() { asFoo->Release(); }

       void FooMethod()
       {
            asIObjectType* type = asFoo->GetObjectType();
            int id = type->GetMethodIdByDecl("void FooMethod()");
            asIScriptContext* ctx = ASEngine->CreateContext();
            ctx->Prepare(id);
            ctx->SetObject(asFoo);
            ctx->Execute();
            ctx->Release();
       }
}

Then I would just wrap retrieved ScriptObject and use the IFoo's interface methods. ;)
Code: [Select]
void RetrieveFoo(asIScriptObject* obj)
{
    if(obj == NULL)
   {
        Log("No object has been passed");
        return;
   }

   IFoo* foo = new Foo(obj);
   foo->FooMethod();
}

Offline Bartosz

  • Rotator
  • There'd better be a killer reason...
Re: AngelScript questions (not related to FOnline API)
« Reply #12 on: June 10, 2013, 04:39:23 pm »
Yeah, this is similar to how mono' DLR handles AngelScript calls.

I am wondering however, if the whole approach needs such heavy interfacing - maybe tackling it in different manner would help .

Offline wladimiiir

  • Rotator
  • Independent FOnline developer
Re: AngelScript questions (not related to FOnline API)
« Reply #13 on: June 12, 2013, 12:15:51 pm »
I am wondering however, if the whole approach needs such heavy interfacing - maybe tackling it in different manner would help .
I personally prefer interfaces, to be able to easily extend or change implementation of some feature. Imagine in my case I will have FooScript implementation which will call ScriptObject functions via provided API. But everywhere except my new FooScript constructor I will use interface instead. One day, Andreas Jonsson (author of AS) will implement possibility to register relation between C++ classes and AS classes, so it will allow me to solve my issue like I indented at the beginning. What needs to be done then is to create an instance of other implementation in one line of code. ;)

Offline wladimiiir

  • Rotator
  • Independent FOnline developer
Re: AngelScript questions (not related to FOnline API)
« Reply #14 on: June 12, 2013, 01:05:13 pm »
How to set an argument of executed script function from C++, while type of the argument is Critter (or some other class)?

I have this script function:
Code: [Select]
void Start(Critter@ critter);
And I would like to call it from C++, while I have pointer to Critter (Critter*) I would like to pass as the argument and what I am trying to do is this:
Code: [Select]
asIScriptContext* ctx = ASEngine->CreateContext();
asIScriptFunction* func = GetObjectType()->GetMethodByDecl("void Start(Critter@)");

ctx->Prepare(func);
ctx->SetArgObject(0, critter);
ctx->Execute();

But I am getting exception state of the context, with message "Null pointer access". Does anyone know see what I am missing?
(When I call argument-less function, it works flawlessly.)

EDIT:
Additional information from server dump file:
Code: [Select]
Exception
Signo   Segmentation fault (11)
Code    Invalid permissions for mapped object, SEGV_ACCERR (1)
Errno   Success (0)

EDIT (SOLVED):
Me stupid monki. I forgot to set object which the function should be executed on:
Code: [Select]
asIScriptContext* ctx = ASEngine->CreateContext();
asIScriptFunction* func = GetObjectType()->GetMethodByDecl("void Start(Critter@)");

ctx->Prepare(func);
ctx->SetObject(GetObject());
ctx->SetArgObject(0, critter);
ctx->Execute();
« Last Edit: June 12, 2013, 02:06:34 pm by Mike Wall »