Jump to content

  • Log In with Google      Sign In   
  • Create Account

Andreas Jonsson

Member Since 26 Mar 2000
Offline Last Active Today, 10:37 AM

#5127868 AngelScript 2.28.1

Posted by Andreas Jonsson on 31 January 2014 - 06:51 PM

It's time for the first release of 2014.


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.




#5127830 Delegates from application (for gui)

Posted by Andreas Jonsson on 31 January 2014 - 03:41 PM

I think you'll want to use delegates for this.


Your script would look something like this:


class Scene1 : IScene
     @controller = loadController("Menu/HUD.axm");
     Widget@ widget = controller.GetWidget("Overhead");
     // Create a delegate object and connect it to the signal handler

   void OnClick()

   GuiController@ controller;


The OnClickCallback is a funcdef that is registered from the application like this:


engine->RegisterFuncdef("void OnClickCallback()");


The SigClicked::Connect method is registered like this


engine->RegisterObjectMethod("SigClicked", "void Connect(OnClickCallback @)", asMETHODPR(SigClicked, (asIScriptFunction *), void), asCALL_THISCALL);


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.


Should you want to extract the object pointer and the class method from the delegate object and store those instead of the delegate itself, you can do so with the methods GetDelegateObject, GetDelegateObjectType, and GetDelegateFunction.




#5125895 When to use asOBJ_POD

Posted by Andreas Jonsson on 23 January 2014 - 10:06 AM

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.


For example:


class Vec2
   Vec2() : x(0), y() {}
   Vec2(float _x, float _y) : x(_x), y(_y) {}
   float x,y;


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.

#5125701 When to use asOBJ_POD

Posted by Andreas Jonsson on 22 January 2014 - 01:19 PM

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.

#5121732 Android - virtual function call issue

Posted by Andreas Jonsson on 06 January 2014 - 03:35 PM

I've managed to reproduce the problem on my BeagleBone with Linux, which shares the code for the native calling convention with Android.


I'll investigate this problem further and update you as soon as I have a fix for it.

#5120786 No AS binary packages

Posted by Andreas Jonsson on 02 January 2014 - 04:53 PM

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.

#5118108 variable persistence and does it make sense to have an 'idle loop'

Posted by Andreas Jonsson on 19 December 2013 - 07:43 AM

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.

#5115666 When to use asOBJ_APP_CLASS_ALLINTS

Posted by Andreas Jonsson on 09 December 2013 - 09:37 AM

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:


Manual: Value types and native calling convention




#5113915 Update script function argument on resume from suspend

Posted by Andreas Jonsson on 02 December 2013 - 07:15 PM

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. 


void main(float frameDelta)
  if( something )

#5113559 Default constructors vs default arguments

Posted by Andreas Jonsson on 01 December 2013 - 03:26 PM

I've implemented this in revision 1792.




#5112862 Alignment requirements

Posted by Andreas Jonsson on 28 November 2013 - 06:01 PM

I don't think it is because of anything malloc does. More likely the debug build uses different instructions to load the SIMD registers so the __m128 types doesn't require alignment. This is however something that would be in your application, and not in AngelScript. 


You can set custom memory functions with asSetGlobalMemoryFunctions(). With this the application can use memory routines that is guaranteed to always return 16byte aligned memory to the script library. You probably don't want to use 16byte aligned allocations for everything though, as it will waste a lot of memory when the allocations are smaller than 16bytes. 


This gave me an idea. The code in as_memory.h can perhaps be enhanced to have a new macro for allocating 16byte aligned memory, e.g. asNEW16 and asNEWARRAY16. This macro can then call a new userAlloc16 global function. The pieces of code I mentioned above that need to guarantee 16byte aligned memory would then only have to call these macros instead of the existing ones to allocate the memory. 

#5111449 Problem with array of handles

Posted by Andreas Jonsson on 23 November 2013 - 09:50 AM

I've implemented the findByRef in revision 1785

#5111105 Global Variables

Posted by Andreas Jonsson on 21 November 2013 - 04:00 PM

With the current version of AngelScript I can think of two ways of solving this.



1. By having some function for retrieving the existing object from the application, through a lookup. You can then have your 'secret' global variables call this function as part of their initializations.

// Secret Global Section
const MyLinkedType@ v1 = __GetExistingObject('whatever');

// User section
const MyLinkedType@ u1 = v1

int main()
    const MyLinkedType@ u2 = v1

    if (u1 is v1)
        return 1;
    else if (u2 is v1)
        return 2;  // This is what returns.
        return 0;

2. Register the 'secret' global variables from the application, instead of declaring them as part of the script. You can use dynamic configuration groups to unregister the global variables in case they change.








As a future enhancement to better support what you want I can think of 2 solutions:


1. Allow resetting global variables selectively. The application could then manually initialize some of the global variables like you currently do, and mark them as finished. Then call ResetGlobalVars to have the script engine initialize the remaining variables.


2. Implement the already planned export-import feature. With this you could compile the secret global variables in a separate module and mark them for export. The user written module will then import the global variables already pre-initialized.

#5109927 [PATCH] Compiler performance improvements

Posted by Andreas Jonsson on 17 November 2013 - 08:44 AM

I've finished incorporating these improvements into the WIP version. (revision 1779).


With the improvements I see an average improvement of around 30% in the compilation times. 


I didn't include the changes as-is, so when you pick up the new version you'll will not see exactly the code you provided, but you should see that all the improvements you made has made it into the code, and in some cases I made further improvements on top of them.




#5109635 Problem with array of handles

Posted by Andreas Jonsson on 15 November 2013 - 09:05 PM

Yes, you're right. Two different functions with appropriate names is better.