• Content count

  • Joined

  • Last visited

Community Reputation

150 Neutral


  • Rank
  1. Yays! Glad I was able to help a little this time, and not only point my finger to a problem [img][/img]
  2. Great. Thanks for the tip. I'll be sure to check it out later today
  3. Hello again! I've been checking the source code and I think I have a few hints on what's going on. First of all: the problem only occurs when the function who's pointer we want to retrive is inside a namespace AND it receives parámeters. If the function has no parameters, it's pointer is retrieved correctly. The reason for that is that in as_module.cpp, around line 640, we have the following code: [code] if( globalFunctions[n]->objectType == 0 && == globalFunctions[n]->name && func.returnType == globalFunctions[n]->returnType && func.parameterTypes.GetLength() == globalFunctions[n]->parameterTypes.GetLength() && ns == globalFunctions[n]->nameSpace ) { //this means that the function we are looking for has been found!! [/code] Take a close look at this line: [code]func.parameterTypes.GetLength() == globalFunctions[n]->parameterTypes.GetLength() &&[/code] Turns out, when we search for a function inside a namespace, func.parameterTypes.GetLength() always returns 0. And that's because in as_builder.cpp, around line 956, we have this code: [code] n = node->firstChild->next->next->next->firstChild; while( n ) { //Do some parameter counting stuff here... [/code] The problem is: when the function we are searching for is inside a namespace, "node->firstChild->next->next->next->firstChild;" returns null. Why, you ask? Damn I wish I knew... [img][/img] I'd really love to know what that line of code actually does [img][/img] Could you help me out here, Andreas? Why do you get the node's first child of the third sibling? I really hope this is at least closing the distance to solve this weird issue
  4. Hello. I asked the very same question to Andreas not long ago. And he told me of a work-around for this, (as well as why it doesn't work [img][/img] ). Here is his reply: [quote] Unfortunately, it is not possible to inherit directly from application registered objects as they are not instances of asCScriptObject. It is possible to implement a script proxy class that gives a light wrapper on top of the application registered object, and then have the script classes inherit from the proxy instead. For example: shared class FSMProxy { FSMProxy() { @inner = FSM(); } bool ChangeState(string v) { return inner.ChangeState(v); } string CurrState { get const { return inner.CurrState; } set { inner.CurrState = value; } private FSM @inner; } The script code for the proxy class can be generated by the application and added as a secondary script section to the script modules that will use the FSM class. Regards, Andreas [/quote] In this case "FSM" is my SuperClass and FSMProxy is the derived class
  5. EDIT: Fixed a stupid mistake of mine in the function implementation, now it almost works perfectly!! (look by the end) Hello. If it helps... as in... at all... I've done the following changes: Function registering (now it returns value instead of reference): [CODE]r = engine->RegisterGlobalFunction ("ref getFuncPtr (const string &in)", asFUNCTION (getFuncPtr), asCALL_CDECL); assert (r >= 0);[/CODE] Function implementation (ID is now get with module->GetTypeIdByDecl to a fixed funcdef): [CODE] CScriptHandle getFuncPtr (const string &Name) { CScriptHandle Handle; asIScriptFunction *Func = engine->GetModule(0)->GetFunctionByDecl (Name.c_str ()); cout << Name << endl; cout << Func << endl; cout << engine->GetObjectTypeById (engine->GetModule(0)->GetTypeIdByDecl ("FSMFunc")) << endl; Handle.Set (Func, engine->GetObjectTypeById (engine->GetModule(0)->GetTypeIdByDecl ("FSMFunc"))); return Handle; }[/CODE] and the script code goes like this (Notice that the function is called by the end): [CODE] funcdef void FSMFunc(TestClass @); class TestClass { string getMessage () { return "this is a message"; } } void PrintMessage (TestClass @Class) { print ("We got a message: " + Class.getMessage ()); } void main () { TestClass Test; FSMFunc @Func = cast <FSMFunc @> (getFuncPtr ("void PrintMessage (TestClass @)")); Func (Test); }[/CODE] Aaaand, the grand result iiiis~ [CODE] void PrintMessage (TestClass @) 0056BAA0 0054AB34 We got a message: this is a messageCall [/CODE] So, that part is now working perfectly. BUT! If in the script we try to get a pointer to a function inside a namespace, the result is a null pointer. Example code: [code] funcdef void FSMFunc(TestClass @); class TestClass { string getMessage () { return "this is a message"; } } namespace test { void PrintMessage (TestClass @Class) { ::print ("We got a message: " + Class.getMessage ()); } } void main () { TestClass Test; FSMFunc @Func = cast <FSMFunc @> (getFuncPtr ("void test::PrintMessage (TestClass @)")); Func (Test); } [/code] That script code gives us the following output: [code] void test::PrintMessage (TestClass @) 00000000 0016AB34 [/code] So, it seems like GetFunctionByDecl is not taking namespaces into account... maybe?
  6. Hey Andreas, I've tried with version 2.24.0a (Which by the way is not linked in the main page [img][/img] ), and I can tell you that, at least under a simple example, the bug is fixed. BUT! I'm affraid I found another similar bug [img][/img] If you try to inherit from a class that's inside a namespace from OUTSIDE of that namespace, you get a compiler error. Example code: [code] namespace Test { class FSM { } } class AdvancedFSM: Test::FSM { } void main () { AdvancedFSM Adv; } [/code] We get the following output: [code] main.fss (9, 24) : ERR : Expected '{' main.fss (0, 0) : ERR : Script failed to build [/code]
  7. Greetings. I'm doing lots of mad scientist experiments here [img][/img] 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": [code] r = engine->RegisterGlobalFunction ("void getFuncPtr (const string &in)", asFUNCTION (getFuncPtr), asCALL_CDECL); assert (r >= 0); [/code] 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: [code] void getFuncPtr (const string &Name) { asIScriptFunction *Func = engine->GetModule(0)->GetFunctionByDecl (Name.c_str ()); cout << Name << endl; cout << Func << endl; cout << Func->GetObjectType () << endl; } [/code] And, in an angelscript we have the following code: [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)"); } [/code] and that code prints the following: [code] main.fss (0, 0) : INFO : Script successfully built void DoNothing (int) 005BA9D0 00000000 void Freedom::DoNothing () 005BAB28 00000000 void Freedom::DoNothingElse (int) 00000000 [/code] 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: [code] //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; } [/code] and the script is pretty the same code as the previous. If I'm lucky, the output goes something like this: [code] main.fss (0, 0) : INFO : Script successfully built System function (1, 1) : ERR : Expected data type 00000000 [/code] notice that for "Name" is not printing anything, so, the function is not actually getting the correct reference. Of course, the application crashes [img][/img] (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 [img][/img] .
  8. 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: [CODE] namespace TestNamespace { class MyHappyClass { MyHappyClass () { } void DoSomething () { //Actually should be called: DoNothing () } } } void main () { TestNamespace::MyHappyClass ClassInstance; ClassInstance.DoSomething (); }[/CODE] We get the following error: [CODE] (17, 1) : INFO : Compiling void main() (19, 17) : ERR : Identifier 'MyHappyClass' is not a data type (0, 0) : ERR : Script failed to build [/CODE] Even if I remove the "TestNamespace::" from the ClassInstance declaration, the compiling error persists [img][/img]
  9. AngelScript 2.24.0 is here (+ bug fix in 2.24.0a)

    Awesome work, indeed.
  10. [quote name='Andreas Jonsson' timestamp='1340575198' post='4952452'] Try it again with version 2.24.0 please, and let me know if still doesn't work. [img][/img] [/quote] Tested... and it works! \o/ Thank you so much [img][/img] script used for testing, compiles and runs smoothly: [CODE] float calc(float a, float b) { // Print the value that we received print("Received: " + a + ", " + b + "\n"); // Print the current system time //print("System has been running for " + pow (2,16) + " seconds\n"); // Do the calculation and return the value to the application return a * b; } namespace A { dictionary Dic; void main () { float Out; Dic.set ("Value", ::calc (1.1,2.0)); Dic.get ("Value", Out); ::print ("Value: " + Out + "\n"); } } [/CODE] Of course, it has Dictionary, String, Array and Math functions registered.
  11. By the way, I guess a simple, yet not very nice, way to solve this problem is adding everything to another namespace called "global" and always make reference to it. In the application: [CODE] engine->SetDefaultNamespace ("Global"); engine->RegisterGlobalFunction("void print (string &in)", asFUNCTION(print), asCALL_CDECL);[/CODE] In the script: [CODE] void MyFunction () { Global::print ("OMG!! it works!!111"); }[/CODE] Of course, this doesn't look nice at all. But it's a temporary solution [img][/img]
  12. Hello. I've just tried this with version 2.23.1 of angelscript and it doesn't work for function calls Even if I add "::function", it won't resolve to Global scope. As for the way of resolving scope, I would like to say that I'm OK with either of the alternatives (automatic recursive resolution or manually specifying "::"), as long as the documentation states it clearly ;) Thanks for the great lib, by the way
  13. Clonable modules?

    Quote:Original post by WitchLord Cloning of modules is indeed on my to-do list, and is something that I hope to be able to implement soon (in a couple of more releases). Though if you want speed while creating objects, then I really suggest you use script classes instead of cloning modules. Mmmmmm... That could work too... though... it wouldn't be as user-friendly :) Sounds interesting enought to think about it
  14. Clonable modules?

    mmm... true... true... Maybe cheat a little more by keeping the byte code in RAM :O
  15. Very basic question

    Mmmm... as far as i understand, AngelScript doesn't include any functionality for input handling, but you can register it. Anyways, you'll have to deal with windows' API so that you can bind those functions into AngelScript.