How is the vec3_t declared? You've registered it with asOBJ_APP_CLASS, with which you're telling AngelScript that this type doesn't have any default constructor nor any copy constructor. Is that really the case? If you don't register the value type with the correct asOBJ_APP_xxx flags AngelScript will not know how the type should be passed by value to native functions. If you're using a C++11 capable compiler you can use the GetTypeTraits<T>() function from scripthelpers add-on to automatically get the correct asOBJ_APP_xxx flags.
How is the playerState_t declared? The asOFFSET(playerState_t, persistant[PERS_ACCURACY_SHOTS]) macro expands to the following:
What you're doing is not completely wrong (though it is quite inefficient, in that you do a lot of string processing with each call). The problem is probably some small detail, e.g. a missing dereference of the pointer to the object.
Can you show the implementation of AS_SetArgBasedOnType?
Based on how you're calling it, it should be doing something like this in order to be correct:
void AS_SetArgBasedOnType(void **arg, const string &type, int index)
// check if the parameter is a handle (it's not really enough to do a find, but you get the idea)
if( string.find("@") != string::npos )
// Call SetArgObject and inform the address of the object
For handles it would also be valid to use SetArgAddress.
Is the CalcMuzzlePoint() function called from the script, or does it crash before that? If it is called, is the pointer you receive the expected one?
Curiosity: Why is your loop that calls AS_SetArgBasedOnType going from 2 to numArgs + 2, when you subtract 2 whenever you use the index? ;)
This one brings quite a lot of under-the-hood improvements, such as reduced compilation times, less overhead in calling script interface methods, inline allocation of class members, reduced size of saved bytecode, improved error reporting for loading invalid bytecode, automatically resolve ambigiuous enum values, etc.
The script language has a new built-in math operator ** for calculating the exponent. Of course, this operator is overloadable just like the rest of the operators. This operator also added 7 new instructions for the VM to handle the primitive types.
Several of the add-ons have been tweaked and adjusted to make them easier to use.
Some of the improvements in this release were contributed by the community members GGLucas and Jason Goepel. So thanks should go out to them this time.
class Scene1 : IScene
@controller = loadController("Menu/HUD.axm");
Widget@ widget = controller.GetWidget("Overhead");
// Create a delegate object and connect it to the signal handler
As you can see the Connect method will receive a pointer to the delegate as a normal script function, which you can then use to prepare and execute in a script context just as if it was a global script function.
The existance of a user defined constructor doesn't imply that that the object is not a POD type. If the members can be safely accessed even before the constructor is called without causing any harm, then it can still be considered a POD type.
The above class is an ordinary POD type even though it has user defined constructors. Think of it like this. Can any harm be done if you interpret a random address into uninitialized memory as the type and then access the members? If no harm can be done then the type is a POD type, but if some harm can be done then it is not a POD type.
asOBJ_POD and the various asOBJ_APP_CLASS_ flags are not directly related to each other. The first tells AngelScript that it is safe to access the unitialized memory and thus it can allow direct bitwise copies of the objects, and the second is used to allow AngelScript to properly passed values of the type to the application registered functions in native calling conventions.
Ideally you would use the templated GetTypeTraits<T>() helper add-on function to determine the correct combination of the asOBJ_APP_CLASS_ flags automatically. This function is only available for compilers that support C++11 though, so if you use an older compiler you'll need to determine the flags manually.
Basically you'll want to use asOBJ_POD for any C++ type that is a plain-old-data type, i.e. doesn't have any virtual function table, and doesn't have any members that require explicit initialization and/or clean-up (e.g. pointers, file handle ids, etc).
There is no problem in providing constructors for objects registered with asOBJ_POD. The flag just says they are not required, not that they are not allowed. Without the asOBJ_POD flag, AngelScript would require the application to register both constructor (at least one) and destructor for the object.
The use of asOBJ_POD also allows AngelScript to make some optimizations, as it can safely inline POD objects within script classes without worrying about invalid memory access due to uninitialized objects while executing the script class constructor.
If your definition of 'mature' means that the libraries interface cannot evolve anymore, then I guess AngelScript isn't mature yet (even after 10+ years of development). But if your definition of 'mature' is how many successful projects use AngelScript and how long it's been available then AngelScript is really quite mature. Guess, which definition of 'mature' I use. ;)
Most developers that use AngelScript keep a copy of the version they integrate, they even check-in the source code in their own repository. This removes any dependency on my repository and avoids confusion when other users download your project (as it will include the exact version of AngelScript you're using). The developer is then also in full control when he wants to upgrade to the latest version of AngelScript, or if he'd rather continue using an older version. Some developers upgrade with every new release (usually it is just a couple of tweaks to the existing code), others only upgrade every couple of years (and usually have a little more work).
On the topic of version numbering. The 1st digit is the major version. I'll only change this to 3 when I'm ready to take the step to remove old functionality (and breaking script compatibility). The 2nd digit is the interface version. I change this everytime there is a change to the interface (though usually it is just an additional parameter, or method, or similar). The 3rd digit is for releases that doesn't change the interface, but implement something new. On some occasions I've also used a final letter, without changing the numbers. This is when releasing only bug fixes, without any other changes.
I try to avoid changing the interface all the time. Normally I hold off on features that change the interface until I have a couple of different ones that I can release together, but I cannot stop it all together as then I'll soon run out of options to evolve the library. I also definitely will not maintain 2 parallel versions. That would only lead to even more confusion and would take away from my already too few available hours to work on the library.
Think of your first alternative as a parallel thread in your application. The application will allow the context to execute for a while, then the context will wait (suspend) until it is time to execute again.
The other option is more like to event handling. Anytime there is an event in the application, the context is executed to handle that even and may use global variables (or properties registered by the application) to keep state information between executions.
Both options are perfectly viable with AngelScript, and it will only depend on your preference.
In my opinion the second option is easier to implement and manage, for the same reason that a singlethreaded application is easier to implement and manage compared to a multithreaded application.
The flags asOBJ_APP_CLASS_ALLINTS/FLOATS are used to tell AngelScript what the type of content the object has, so AngelScript can decide how the object should be passed to registered functions in native calling conventions. The only ABI so far that needs these flags is the AMD/Intel 64bit ABI that the g++ compiler uses. This specific ABI can decide to put the object in the CPU float registers or general registers depending on the type of the members of the class.
On any other platform or compiler the flags will have no effect.
The documentation that describes when/how to use these flags is here:
You can only set arguments on the context after Prepare() and before the first Execute(). The SetArg methods returns an error if not in this state. I bet you didn't check the return code, am I right? ;)
When a context is suspended and then resumed with another call to Execute() it will continue at the exact same position where it was suspended, which means that any function arguments that were passed into the function in the first call will already have been read and used. Even if the context would allow you to set the arguments while the context was suspended there would be no guarantee that the script would actually re-read the arguments when resuming.
If you mean to change the argument, why not allow the script to run to it end and then simply call the script again with the new argument? I.e. remove the while loop and the SuspendMe() call.