Jump to content

  • Log In with Google      Sign In   
  • Create Account

alraz

Member Since 04 Sep 2005
Offline Last Active Jul 31 2012 06:50 PM

Topics I've Started

2.24.0 GetFunctionByDecl returns NULL for functions inside a namespace

07 July 2012 - 01:45 PM

Greetings. I'm doing lots of mad scientist experiments here Posted Image  and I think I found 2 bugs for the price of one.

I'm trying to allow scripts to get function pointers by passing a string with the CDECL, and found out that, when we use GetFunctionByDecl to try to get the pointer of a function inside a namespace, if that function receives parameters, GetFunctionByDecl returns NULL.

Lemme explain with code:
So, here is the code to register "Get function pointer":
r = engine->RegisterGlobalFunction ("void getFuncPtr (const string &in)", asFUNCTION (getFuncPtr), asCALL_CDECL); assert (r >= 0);

Please notice that currently, the getFuncPtr function is not actually returning anything (as it's return type is void); I'll get into that in the second issue, but for now, let me first explain the problem with namespaces.

the code for getFuncPtr goes like this:

void getFuncPtr (const string &Name)
{
   asIScriptFunction *Func = engine->GetModule(0)->GetFunctionByDecl (Name.c_str ());
   cout << Name << endl;
   cout << Func << endl;
   cout << Func->GetObjectType () << endl;
}


And, in an angelscript we have the following code:

void DoNothing (int NotUsed)
{
}

namespace Freedom
{
   void DoNothing ()
   {
   }
   void DoNothingElse (int NotUsed)
   {
   }
}

void main ()
{
   getFuncPtr ("void DoNothing (int)");
   getFuncPtr ("void Freedom::DoNothing ()");
   getFuncPtr ("void Freedom::DoNothingElse (int)");
}



and that code prints the following:

main.fss (0, 0) : INFO : Script successfully built
void DoNothing (int)
005BA9D0
00000000
void Freedom::DoNothing ()
005BAB28
00000000
void Freedom::DoNothingElse (int)
00000000

Notice that, for the first 2 calls to getFuncPtr, we get a pointer, but for the third, the one that tries to get the address of the function that receives parameters and is inside a namespace, we get NULL. Of course, the application crashes in the third call to getFuncPointer, since we got a NULL pointer.

Another thing that worries me is that "Func->GetObjectType ()" is always returning NULL.

So, that's for the first issue: getting functions with parameters inside namespaces.



======================================================


Of course, the main idea behind all of this weirdness is to allow script objects to get pointers to functions (I know, it's weird...), so, after lots of not-less-weird attempts, I tried with the ref object:

//Register the function to return a ref:
r = engine->RegisterGlobalFunction ("ref @getFuncPtr (const string &in)", asFUNCTION (getFuncPtr), asCALL_CDECL); assert (r >= 0);

//some happy lines of code later...
CScriptHandle *getFuncPtr (const string &Name)
{
   CScriptHandle *Handle = new CScriptHandle;
   asIScriptFunction *Func = engine->GetModule(0)->GetFunctionByDecl (Name.c_str ());
   cout << Name << endl;
   cout << Func << endl;
   cout << Func->GetObjectType () << endl;
   Handle->Set (Func, Func->GetObjectType ());

   return Handle;
}

and the script is pretty the same code as the previous. If I'm lucky, the output goes something like this:
main.fss (0, 0) : INFO : Script successfully built
System function (1, 1) : ERR  : Expected data type

00000000

notice that for "Name" is not printing anything, so, the function is not actually getting the correct reference. Of course, the application crashes Posted Image
(On an unlucky run, I would get a matrix screen saver in my console output)

I'ts most likely just me doing something stupid; I gotta admit I don't understand this "reference object" very much Posted Image .

2.24.0 Cannot instantiate a class outside of it's namespace

25 June 2012 - 03:37 PM

Hello, I've been testing the 2.24.0 release with namespaces and I think i found a bug.

Say we have the following script code:

namespace TestNamespace
{
	class MyHappyClass
	{
		MyHappyClass ()
		{
		}

		void DoSomething ()
		{
			//Actually should be called: DoNothing ()
		}
	}
}

void main ()
{
	TestNamespace::MyHappyClass ClassInstance;

	ClassInstance.DoSomething ();
}


We get the following error:
test.as (17, 1) : INFO : Compiling void main()
test.as (19, 17) : ERR  : Identifier 'MyHappyClass' is not a data type
test.as (0, 0) : ERR  : Script failed to build


Even if I remove the "TestNamespace::" from the ClassInstance declaration, the compiling error persists Posted Image

Clonable modules?

23 August 2008 - 02:14 PM

Hello. I come here with something i think it's an interesting question (hope it actually is ^_^) I was trying to make some script which are actually "entities" or "processes"; i like to call them Objects. Whatever the name, those scripts are intended to control one particular Sprite in the screen. For example a "projectile" Object would contain all the code to move a shot across the screen, a "character" Object would control a the player's character in the screen, a "monster" object would do the same for enemies... and so on... I've already created some C++ clases and functions which take care of animations, sprite loading, sounds, input handling, etc. and they are passed to the AngelScript Engine. There is a sort of "Yield" function, based on the examples of AngelScript's SDK, so that every Object can tell the main .exe when it has finished doing it's job for this frame. Now, the main intention of all this, is that scripts can create other Objects. For example, a Character Object would create a Projectile Object every time the player shoots. There could also be a Monster Spawner Object which takes care of creating some random enemies. Hope you are getting the idea. I was hoping that users of all this messy program could make their own Object, which means, they could declare some global variables to hold Sprite, Sound, Animation and other data, hoping that every Object that is created will have it's own copy of those variables, functions and, in general, it's own independent code. With this, we can create one type of Object and make it appaer tons of times on screen. The best example is the Enemy Object: We can place tons of enemies around the stage, by just changing their position and current animation; those could be recieved as parameters in the main function; those parameters change the global variables; later, every single enemy could have it's own current state, position, animation, etc. by just changing the Global Variables declared in the script for that Object, something the script itself can do. Now, my problem is the following: This cannot be achieved with contexts, since they share variables for the current module (Suposing every module contains the code for one Object). It can be done by using one module for every Object create, but this would mean that i'd have to recompile the code for that module every time a new object is created, which I suppose is not fast enought to do it on real time. I propose a "ClonModule" method for the Script Engine class, which creates a copy of one module, to a new module with just a different name; hoping, of course, that it would be fast enought to do it real time. Hope i was clear enought.

Virtual class registration problems?

09 March 2008 - 01:08 PM

Hello I'm using the co-routines example to do a little testing with AngelScript. I'm Using Code::Blocks + MinGW to compile. I'll try to explain my problem as clear as possible... Basically, the script returns with code 3 (asEXECUTION_EXCEPTION) as soon as i try to run any mothod of an instantiated object. Here is what i have: First of all, there is a small virtual class which is supposed to handle input:
class ygi_input
{
public:
    virtual ~ygi_input () {};

    virtual void clear () = 0;
    virtual bool load (const string FileName, const string Player, const string Name, const string Default = "") = 0;
    virtual bool save (const string FileName) = 0;


    /*
    some other methods... 
    */

    virtual bool waspressed  (const sint32 FramesBack) = 0;
    virtual bool wasreleased (const sint32 FramesBack) = 0;
    virtual sint32 value () = 0;
};
there is an inherited class which implements all the virtual functions from this base class, but the application only uses the main class via pointers... somthing like:
ygi_input MyInput = CreateInputClass ();


ygi_input *CreateInputClass ()
{
//DerivedClass is something like DerivedClass : public ygi_input
DerivedClass *Cls = new DerivedClass;

   return (ygi_input *) Cls;
}
So, what i did is use the Coroutines example which comes with AngilScript and alther it a little bit to include handling of this input class. First, i created some basic functions for behaviour and some others for testing...
map <ygi_input *, int> RefCounter;


ygi_input *InputFactory ()
{
    ygi_input *Ret = ygi_createinput ();

    if (Ret != NULL)
        RefCounter [Ret] = 1;

    return Ret;
}

void InputAddRef (ygi_input *Obj)
{
    RefCounter [Obj] ++;
}

void InputRemRef (ygi_input *Obj)
{
    RefCounter [Obj] --;
    if (RefCounter [Obj] == 0)
    {
        ygi_releaseinput (Obj);
    }
}

bool InputLoad (ygi_input *Obj, string A, string B, string C, string D)
{
    return Obj->load (A, B, C, D);
}

bool InputPressed (ygi_input *Obj, sint32 Frms)
{
    return Obj->waspressed (Frms);
}

void InputClear (ygi_input *Obj)
{
    Obj->clear ();
}
And altered the ConfigureEngine function a little bit to add the object to the script:
   // [...]

   RegisterScriptAny(engine);

	r = engine->RegisterObjectType("ygi_input", sizeof(ygi_input), asOBJ_REF); assert( r >= 0 );

	r = engine->RegisterObjectBehaviour("ygi_input", asBEHAVE_FACTORY, "ygi_input @f()", asFUNCTION(InputFactory), asCALL_GENERIC); assert( r >= 0 );
	r = engine->RegisterObjectBehaviour("ygi_input", asBEHAVE_ADDREF,  "void f()",       asFUNCTION(InputAddRef),  asCALL_GENERIC); assert( r >= 0 );
	r = engine->RegisterObjectBehaviour("ygi_input", asBEHAVE_RELEASE, "void f()",       asFUNCTION(InputRemRef),  asCALL_GENERIC); assert( r >= 0 );

    r = engine->RegisterObjectMethod("ygi_input", "bool load (string &in, string &in, string &in, string &in)", asFUNCTION(InputLoad), asCALL_CDECL_OBJFIRST); assert( r >= 0 );
    r = engine->RegisterObjectMethod("ygi_input", "bool waspressed  (const int)", asMETHODPR(ygi_input, waspressed, (const sint32), bool), asCALL_THISCALL); assert( r >= 0 );*/
    r = engine->RegisterObjectMethod("ygi_input", "void clear ()", asFUNCTION(InputClear), asCALL_GENERIC); assert( r >= 0 );

   // [...]
I can create object of type "ygi_input" in the scripts, but, as soon as y try to call any of the methods clear, load or waspressed, the (*currentCtx)->Execute() function returns with code 3, which the .h file says is asEXECUTION_EXCEPTION. I tried with many different ways to register the method but all of them took me to the same problem :( Any ideas or help...?

Warnings compiling AngelScript 2.6.0

16 April 2006 - 09:29 AM

when I compile AngelScript with Dev-Cpp, it gives me the following warnings: G:\sdk\angelscript\source\as_context.cpp In member function `virtual void* asCContext::GetReturnObject()': 478 G:\sdk\angelscript\source\as_context.cpp [Warning] cast to pointer from integer of different size G:\sdk\angelscript\source\as_context.cpp In member function `void asCContext::ExecuteNext()': 1085 G:\sdk\angelscript\source\as_context.cpp [Warning] cast to pointer from integer of different size Im using the following options: -General: -Project type: DLL file -Compiler: -Optimization: Perform a number of minor optimizations = Yes -Further Optimization: Optimize More -Parameters: -C++ Compiler = -DANGELSCRIPT_EXPORT and that's all...

PARTNERS