Advertisement

2.23.1: Unable to access functions in global scope from within namespace (plus a bit on the scope resolution operator with namespaces)

Started by May 27, 2012 05:45 PM
8 comments, last by WitchLord 12 years, 2 months ago
Pretty clear with code:

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void GlobalFunction() {
Engine::LOG(Engine::LOG_PRIORITY::INFO, "Called.");
}

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
namespace MyNamespace {
void NamespacedFunction() {
Engine::LOG(Engine::LOG_PRIORITY::INFO, "Called.");
GlobalFunction(); // No matching signatures to 'GlobalFunction()'
::GlobalFunction(); // No matching signatures to '::GlobalFunction()'
}
}

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void main() {
GlobalFunction();
MyNamespace::NamespacedFunction();
}


I first noted this problem when attempting to use sqrt (from the scriptmath addon) from within a namespaced function. I worked around it by registering scriptmath inside a "Math" namespace, but that's hardly ideal. To me all functions in a parent namespace, unless masked by another function in a closer relation, such as the same namespace, should be accessible in all children namespaces. If a function is masked, it should be accessible with the right use of scope resolution.

Which leads me to: the global scope operator doesn't play with namespaces. This could make situations like the below rather interesting...

void MyFunction() {
Engine::LOG(Engine::LOG_PRIORITY::INFO, "Called.");
}

namespace MyNamespace {
void MyFunction() {
Engine::LOG(Engine::LOG_PRIORITY::INFO, "Called.");
}

void NamespacedFunction() {
MyFunction(); // Which function is this referencing? I assume it's the one in the current namespace!
::MyFunction(); // Which implies that this should be the syntax to access the one in the global namespace...
}
}


I understand the global scope operator is currently designed to access global variables, as in:

// From http://www.angelcode.com/angelscript/sdk/docs/manual/doc_expressions.html
int value;
void function()
{
int value; // local variable overloads the global variable
::value = value; // use scope resolution operator to refer to the global variable
}

However, as it is also the namespace resolution operator I was expecting it to work for accessing the global namespace as well...
Just saw "Accessing entitites in global scope from a function in a namespace didn't work (Thanks _Vicious_)" d'oh...
Advertisement
:)

Did the fix provided for problem reported by _Vicious_ solve your issue too?


Observe that the namespace feature is still quite new in AngelScript, and doesn't have quite all capabilities that is available in for example C++. For one thing, AngelScript currently does not recursively search parent namespaces for matching symbol names. Only the current namespace is search, or if another explicit namespace is given, then that one is used instead.

I intend to implement the recursive search of parent namespaces, but I'm not sure when I'll get to it.

AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game

I'm not sure about _Vicious_'s fix, but I expect so. It sounds the same.

I know it's fresh. :D The inclusion of namespaces is why I upgraded AS in our engine - it was of more worth to me than most of the bug fixes.

Understandable about the searching - so long as that is documented. http://www.angelcode.com/angelscript/sdk/docs/manual/doc_global.html#doc_global_namespace doesn't currently mention this situation, leading to the expectation of C++-esque functionality. I'd recommend, and I know I'm not in a place to say anything about your project's direction, that in the current situation blocking access to the objects in the global scope (2.23.1's current functionality) by default, but then allowing access through the explicit use of the global scope resolution operation "::MyFunction()" would make the system self-consistent. The global scope operator is documented here for our convenience: http://www.angelcode.com/angelscript/sdk/docs/manual/doc_expressions.html#scope

Thank you very much for an amazing tool.
The documentation can definitely be improved. I'll add this for the next release.

Everyone gets a say in the project's direction. :) AngelScript has far exceeded my own needs for a scripting library many years ago. Nowadays I'm working on this library more for the community than for my own use. I listen to the users feedback and decide what seems to benefit the most of you. When opinions diverge but there is a possibility to make an option configurable without negatively impacting everyone I'll try that as well.

For example, whether or not to do a recursive search in parent namespaces might be something I'll make configurable with an engine property.

AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game

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
format c: /q
Advertisement
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:

engine->SetDefaultNamespace ("Global");
engine->RegisterGlobalFunction("void print (string &in)", asFUNCTION(print), asCALL_CDECL);


In the script:

void MyFunction ()
{
Global::print ("OMG!! it works!!111");
}


Of course, this doesn't look nice at all. But it's a temporary solution wink.png
format c: /q
Try it again with version 2.24.0 please, and let me know if still doesn't work. :)

AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game


Try it again with version 2.24.0 please, and let me know if still doesn't work. smile.png


Tested... and it works! \o/

Thank you so much smile.png

script used for testing, compiles and runs smoothly:


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");
}
}


Of course, it has Dictionary, String, Array and Math functions registered.
format c: /q
Thanks for the confirmation :)

AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game

This topic is closed to new replies.

Advertisement