Advertisement

Template containers angelscript addon library release!

Started by October 14, 2014 09:46 AM
48 comments, last by Wracky 8 years, 1 month ago


The operand is implicitly converted to handle in order to compare them at row: X col: Y

I've not been able to reproduce this with the current WIP version. I believe this problem has been fixed in a previous release. Version 2.29.1 is 1.5 years old after all. :)

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

So I've just updated my Angelscript again, and noticed my version of AATC didn't use TypeInfo yet.
So I decided to update AATC as well, but I have troubles getting it to compile.

I don't know if this is a fault in my project, or not, but I'm getting a lot of errors like this:



1>  aatc_container_shared.cpp
1>..aatc\aatc_container_shared.hpp(358): error C2988: unrecognizable template declaration/definition (..\..\src\Scripting\AngelScript\aatc\aatc.cpp)
1>..aatc\aatc_container_shared.hpp(358): error C2988: unrecognizable template declaration/definition (..\..\src\Scripting\AngelScript\aatc\aatc_container_set.cpp)
1>..aatc\aatc_container_shared.hpp(358): error C2059: syntax error : '<L_TEMPLATEDECL>' (..\..\src\Scripting\AngelScript\aatc\aatc.cpp)
1>..aatc\aatc_container_shared.hpp(358): error C2059: syntax error : '<L_TEMPLATEDECL>' (..\..\src\Scripting\AngelScript\aatc\aatc_container_set.cpp)
1>..aatc\aatc_container_shared.hpp(359): error C2059: syntax error : '}' (..\..\src\Scripting\AngelScript\aatc\aatc.cpp)
1>..aatc\aatc_container_shared.hpp(358): error C2988: unrecognizable template declaration/definition (..\..\src\Scripting\AngelScript\aatc\aatc_container_list.cpp)
1>..aatc\aatc_container_shared.hpp(359): error C2059: syntax error : '}' (..\..\src\Scripting\AngelScript\aatc\aatc_container_set.cpp)
1>..aatc\aatc_container_shared.hpp(341): error C2888: 'void register_all_tempspec_basics_for_container(asIScriptEngine *)' : symbol cannot be defined within namespace 'autoregister' (..\..\src\Scripting\AngelScript\aatc\aatc.cpp)
1>..aatc\aatc_container_shared.hpp(358): error C2059: syntax error : '<L_TEMPLATEDECL>' (..\..\src\Scripting\AngelScript\aatc\aatc_container_list.cpp)
1>..aatc\aatc_container_shared.hpp(341): error C2888: 'void register_all_tempspec_basics_for_container(asIScriptEngine *)' : symbol cannot be defined within namespace 'autoregister' (..\..\src\Scripting\AngelScript\aatc\aatc_container_set.cpp)
1>..aatc\aatc_container_shared.hpp(359): error C2059: syntax error : '}' (..\..\src\Scripting\AngelScript\aatc\aatc_container_list.cpp)
1>..aatc\aatc_container_shared.hpp(341): error C2888: 'void register_all_tempspec_basics_for_container(asIScriptEngine *)' : symbol cannot be defined within namespace 'autoregister' (..\..\src\Scripting\AngelScript\aatc\aatc_container_list.cpp)
1>..aatc\aatc_container_shared.hpp(358): error C2988: unrecognizable template declaration/definition (..\..\src\Scripting\AngelScript\aatc\aatc_common.cpp)
1>..aatc\aatc_container_shared.hpp(358): error C2059: syntax error : '<L_TEMPLATEDECL>' (..\..\src\Scripting\AngelScript\aatc\aatc_common.cpp)
1>..aatc\aatc_container_shared.hpp(359): error C2059: syntax error : '}' (..\..\src\Scripting\AngelScript\aatc\aatc_common.cpp)
1>..aatc\aatc_container_shared.hpp(341): error C2888: 'void register_all_tempspec_basics_for_container(asIScriptEngine *)' : symbol cannot be defined within namespace 'autoregister' (..\..\src\Scripting\AngelScript\aatc\aatc_common.cpp)
1>  aatc_container_unordered_map.cpp

I'm using Visual Studio 2013, and have used the current master branch for AATC.

Am I doing something wrong? :)

Thanks!

http://www.piko3d.net
Advertisement

I'm not sure, but this has the looks of being a problem with the compiler not understanding the template syntax used in AATC. Perhaps you need to upgrade to MSVC 2015.

Regards,

Andreas

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

Hi Andreas,

Thanks for the reply.

Yeah I'm afraid so. Too bad though. It's nice that Angelscript is still available on so many different compilers/versions, and a bit of a bummer when such a nice add-on as this one requires a specific compiler.

We will eventually update to Visual Studio 2015, but I'm currently not in the mood of recompiling all our other dependencies ;-)

For now I've decided to revert AATC to an older version from my own repository. I don't know which version it is, but I just changed all the references to asIObjectTypeInfo and related functions to asITypeInfo, and now it works fine.

Shame though.. of course I'd like to keep AATC up to date as well.

Anyway, I have a solution for now.

Thanks for keeping Angelscript alive. It's an amazing product :-)

http://www.piko3d.net
Hey.
Apparently msvc2013 is very scared of templated template parameters declared with the syntax

template<template<int> typename functor_operate>
, but fine with

template<template<int> class functor_operate>
I made a patch for you which seems to compile fine with msvc2013 and msvc2015, its in a separate branch for now at patch-2016-09-msvc2013.
Will merge to master once I get my linux builder VM running and can confirm that GCC won't cry about it either.

Thanks!!
Ok that's just silly :D I've updated my version to the patch, and it seems to work.

I did notice something else though.

We do Strings a bit differently in our engine. They are ref objects, and all our classes are registered with a name starting with a Capital. So I always spend some time converting some of the types, before I can start using AATC. While doing that, I came across the script_Funcpointer class, which needs a String to specify the script function to call.

I've solved a lot of callback situations with funcdefs, which work great when the type is known.
Everything you need is basically in the asIScriptFunction class, but the trick is to get Angelscript to pass one to you :D
A funcdef for less<T>( const T& a, T& b) would be awesome, but I don't think that is currently possible, is it?

Anyway, thanks again. loving aatc as well ;)

http://www.piko3d.net
Advertisement

AATC does allow using proper funcdefs where possible, for example when sorting a tempspec'd vector or list. See vector's script interface manual page.

Quote from aatc_funcpointer's manual page:

aatc_funcpointer was created in ancient times to make sorting by angelscript functions possible. Nowadays angelscript has anonymous functions and everyone likes to use those for sorting instead of global functions. Anonymous function support for sorting is available, but only for tempspec'd containers for now, templated containers would probably require angelscript language support for templated funcdefs.

Ah right. Makes sense!

In other news, I think I've found a curious bug in AATC:

Let's say I want to replicate the following C++ code in Angelscript AATC:


std::map<int, int> myMap;
myMap[0] = 1;

std::cout << "myMap has: " << myMap.size() << " elements" << std::endl;
	
for (auto& iter = myMap.begin(); iter != myMap.end(); ++iter)
{
	std::cout << "Key: " << iter->first << " Value: " << iter->second << std::endl;
}
return 0;

//This will output the following (stating the obvious)
myMap has: 1 elements
Key: 0 Value: 1

We've translated this to: ("echo" is a simple function we've bound that does console output)


map<int, int> myMap;
myMap[0] =  1;

echo("myMap has " + String(myMap.size()) + " elements");

for (auto iter = myMap.begin(); iter != myMap.end(); ++iter)
{
	echo ("Key: "+ String(iter.key) + " Value: " + String(iter.value));
}

//This will output the following:
myMap has 1 elements
Key: 0 Value: 1
Key: 0 Value: 1

While the C++ program will output exactly one item, the angelscript version will output 2 values! Even though myMap.size() returns 1.

It seems like there's a problem with the iterators somehow. They don't behave like their C++ counterparts.

While testing, I noticed something else with the following


Map<int, String@> myMap;
@myMap[0] = "Foo";

In this case, my String's = operator get's called, which in my opinion shouldn't happen ? It crashes, as the handle being assigned to is a nullptr. I was expecting it to just reassign handles. Is that possible? I loved the DEFAULT_HANDLEMODE_DIRECTCOMP option in the config, I hoped this would work in a similar fashion.

Thanks for reading,

Let me know what you think!

Regards,
Wracky

http://www.piko3d.net

The iterator problem is caused by AATC's iterators being quite nonstandard indeed. The manual page for iterators and the first page of this topic explain the iteration syntax. Maybe I should implement a more standard iteration syntax for easier c++ -> AS conversion and keep the current syntax available under a different operator or function name. The iterator syntax was originally created to reduce AS function calls and to improve performance.

The string problem is probably caused by AATC expecting strings to be AS value types and your AS reftype string causing terrible confusions.

I did some testing with removing AATC's specialized string handling entirely, and treating strings as plain old objects or ref objects. Seemed to work pretty good with scriptstdstring, maybe it could help your reftype String as well.

If you want to try that route, make these changes to your AATC installation (and remove any other changes to strings):

In aatc_common.cpp, line 326


DATAHANDLINGTYPE Determine_Datahandlingtype(...){
  ...
  return DATAHANDLINGTYPE::STRING
  ...
}

delete the part about "return DATAHANDLINGTYPE::STRING".

In aatc_container_shared.hpp, line 357


template<...> void autoregister::register_all_tempspec_basics_for_container(...){
  ...
  tempspec_container_template<config::t::string>::Register(rs, "string");
}
delete the line regarding registering "string".
With these changes AATC will properly treat your reftype String as a reftype and you won't have to go changing "string" to "String" deep in the bowels of AATC after every update.
AATC will also no longer be able to use it's native hash function for strings automatically, because AATC is treating String as an AS type. You will have to register a hash function manually for your String class, if you need to use it with the hashing containers.
If this thing works out for you, I'll make it an option in aatc_config.hpp.

Ah! Thanks! I see what you mean.

Even when looking for it, it took me a little while to see that the opPreInc and opPostInc functions returned a bool. Our scripters missed it too ;)
In C++, the convention for these operators is usually to return a reference to the object itself, or a copy (for postInc).
This is convenient in some cases, for instance when pasing them as arguments.

I really like that you thought about minimizing AS function calls in the for loop though, so I would definitely appreciate a method for this, so that the current behaviour can still be used. Good thinking!

I've tested out the solution you proposed for our String handling, and it works great. Thank you.
During testing, I did come accross another small bug, regarding opCmp. The angelscript manual states the following:

"The comparison operators are rewritten as a.opCmp(b) op 0 and 0 op b.opCmp(a) and then the best match is used. The opCmp method must be implemented to return a int in order to be considered by the compiler. If the method argument is to be considered larger than the object then the method should return a negative value. If they are supposed to be equal the return value should be 0."

So for the less operator, the function returns a negative value. Not necessarily -1. I found AATC just checks for -1.

For performance reasons, (and to follow the example of strcmp, our String is implemented to return the numerical difference between the first mismatching characters which will often be smaller than -1.

I managed to fix it by changing line 232 in aatc_container_shared.cpp as follows:


result = (cc->GetReturnDWord() == -1);
//Should be..
result = ((int)cc->GetReturnDWord() < 0);

opCmp is expected to return an int, so this sould be fine.
With that said, it seems like everything is in order now. I can use Strings directly, or use String@, so the scripter can decide for them selfs if they want to copy string or not ;-)

As for the Hash function, sure, I would gladly specify one manually.
Thanks again for your reply, and keep up the good work!

http://www.piko3d.net

This topic is closed to new replies.

Advertisement