Jump to content

  • Log In with Google      Sign In   
  • Create Account

Andreas Jonsson

Member Since 26 Mar 2000
Offline Last Active Yesterday, 03:20 PM

#5284265 AngelScript and Fastdelegates

Posted by on 30 March 2016 - 08:45 AM

True, an arbitrary method pointer can have different sizes. But in your case the method pointer to the FastDelegate's operator() method will always be of the same size regardless of the arguments (on MSVC it will have the size of a simple pointer), but in your case you're probably best to typedef a simple class method as it will be more portable.



// Declare a simple dummy class so the compiler can determine what a method pointer would look like,

// i.e. it can see that the method pointer won't need to keep track of multiple or virtual inheritances

class CSimpleDummy {};

typedef void (CSimpleDummy::*SIMPLEMETHOD_t)();
// Take the address of the FastDelegate's class method like this:
SIMPLEMETHOD_t methodAddr = reinterpret_cast<SIMPLEMETHOD_t >(&ScriptComponentMethodString::operator());

The methodAddr can then be passed from the exe to the dll just like any other primitive type. AngelScript will take care of interpreting the method pointer and setting up the arguments for the call dynamically based on what you tell it in the function declaration string when registering the method with the engine.

#5283625 Various unexpected behaviors of AngelScript 2.31.0

Posted by on 26 March 2016 - 04:36 PM

I've fixed all the bugs reported here in revision 2308.




#5282692 Various unexpected behaviors of AngelScript 2.31.0

Posted by on 22 March 2016 - 11:49 AM

All, except the last are valid bugs and I'll look into them, and have them fixed a.s.a.p.


The last one is as you suspect a special case, and while it may look odd, it is specifically designed to work so that this type of expression can be used in code where you don't know at the time of writing the actual type of the argument given to the function. Consider for example macros, templates, or mixins, where you write the code once and then reuse it in different situations.


I also have a case in the console sample that takes advantage of this. Here I register various overloads of a special function called _grab that is used to catch the value of the expression written on the console input line and print it on the screen. When the expression doesn't have any value (i.e. void) then the overload _grab() is used. The statement written to the console input is then compiled and executed by the application like this:

void ExecString(asIScriptEngine *engine, string &arg)
  string script;
  // Wrap the expression in with a call to _grab, which allow us to print the resulting value
  script = "_grab(" + arg + ")";
  int r = ExecuteString(engine, script.c_str(), engine->GetModule("console"));
  if( r < 0 )
    cout << "Invalid script statement. " << endl;
  else if( r == asEXECUTION_EXCEPTION )
    cout << "A script exception was raised." << endl;

If this is causing a problem for you I could add an engine property to allow you to turn off this behaviour in your application.

#5280453 Crash instead of null pointer exception on opIndex

Posted by on 09 March 2016 - 07:07 PM

There was indeed a bug in asBC_Thiscall1. Even if your first opIndex had returned a null handle (instead of a reference) it would still crash since asBC_Thiscall1 didn't verify the object pointer.


I've fixed this now in revision 2303.




#5280445 Difference between object handles/references

Posted by on 09 March 2016 - 06:09 PM

The difference between a reference and handle in AngelScript is pretty much the same as the difference between a reference and a pointer in C++.


You already stated one of the differences: "I also understand that a reference cannot be null and a object handle can be".


Another difference is that a reference cannot be reassigned to point to a different object while an handle can be.



When registering functions with AngelScript you'll have to be careful with the choice of reference versus handle due to the reference counting. When registering the function as returning a reference, the C++ function must not increment the ref counter of the object, but when registering the function as returning a handle, the C++ function must increment the ref counter of the object (or use auto handles to tell AngelScript to do that for you). If you don't do this correctly you may end up with memory leaks, or crashes due to the objects being freed too early.

#5279671 Crash instead of null pointer exception on opIndex

Posted by on 05 March 2016 - 09:59 AM

How is the opIndex method registered with the engine? Is it registered to return a reference, or a handle?


A method that is registered to return a reference really shouldn't be allowed to return a null pointer as the reference is expected to be to a valid object. Only return a null pointer if you're also raising an exception to tell the engine that the returned reference shouldn't be accessed.



Still, I'll see what to do about this. I have a feeling that this problem was introduced in version 2.30.1 (released last year) when I added the bytecode instruction asBC_Thiscall1 to optimize access to array elements (and any other method that takes a single 32bit integer argument).

#5278388 AngelScript 2.31.0 is finally out

Posted by on 26 February 2016 - 07:38 PM

Wow, it's been 6 long months since the last release. Never before during the 13 years that I've been working on AngelScript has it been this far between two releases. 
Naturally, with such a long period, the number of changes that have been made are also larger than anytime before. As this is a major release, there is also interface breaking changes. Not to worry though the changes are for the better, and I'm certain that it shouldn't take much work for users to upgrade to the new version. 
The most significant change to the interface is that the asIObjectType has been removed. Instead the new asITypeInfo has been introduced. asITypeInfo has all the methods that asIObjectType had before to inspect object types, and it also has new methods to inspect enums, typedefs, and funcdefs. With this change I've unified the way that type information can be handled by the application, which I hope should be welcome change.
Of course, some methods on the other interfaces, e.g. asIScriptEngine, asIScriptContext, asIScriptModule, etc, have been changed to reflect the move from asIObjectType to asITypeInfo, but developers ought to feel right at home with the changes.
These changes to the application interface has also triggered a rather extensive refactoring of the code within the library, so that was another reason for the long period since the last release.
Some other enhancements that also made it in to this release are:
  • support for storing an auxiliary pointer with functions registered using asCALL_GENERIC
  • included engine property asEP_ALLOW_UNICODE_IDENTIFIERS for those who do not like the restriction of using only English alphabet in the scripts
  • funcdefs can now be registered/declared as members of classes
  • included a simple datetime script add-on for telling the time
  • added a method getInput in asrun to allow it to take input from the user
I never intended to make AngelScript a stand-alone scripting language, but I've been adding some functionality to the asrun sample every once in a while, and it is has now reached a stage where it can actually be used to script some tasks that I would normally use other script languages for. For example, I now use asrun to prepare the SDK package for the release. It actually feels quite cool to see this work out so well despite it not being the intended use for the library.

#5272449 Request for script builder add-on

Posted by on 24 January 2016 - 04:58 AM

Come to think of it. Overloading just the fopen call is probably not so useful. 


The CScriptBuilder already allows you to override how files are found by setting the IncludeCallback. You can use this to determine the correct file name, or even load a section from memory in case you're using some kind of virtual file system.



I'm thinking that instead of overloading the fopen call, I'll add a new method AddSection(const char *sectionName). By default, this method will simply call the AddSectionFromFile, but if the IncludeCallback is set it will invoke that to allow custom lookup of the file.

#5272300 Request for script builder add-on

Posted by on 22 January 2016 - 04:05 PM

Sure. I'll consider it for a future release.


Feel free to customize the add-ons. :) They are just provided to give a starting point to the application developers, but they are not required to be used as-is, or even at all. 

#5271553 Sharing modules (but not globally)

Posted by on 17 January 2016 - 09:28 AM

An already compiled script module can be appended with new global functions and global variables through the use of asIScriptModule::CompileFunction and CompileGlobalVar, but it is not possible to append arbitrary scripts that may contain multiple functions, classes, etc.


Even if it was possible to append to an existing module (which is actually something I already have on my to-do list), I'm not sure it would be easy to remove part of the module when your GUI loaded a different document. How should the application or script engine know what should be removed?




Perhaps you could do something like this:


1. When loadDocument is called

2. Application serializes any existing objects, values in the module (i.e. store a backup)

3. Create a new module

4. Add the original "inventory.as" script, plus all the embedded script sections from the XML

5. Compile the module

6. If the compilation is successful, restore (deserialize) the objects and values from the previous backup



This is often known as 'hot loading' modified scripts, and normally used to allow the source code to be modified on-the-fly, but should work perfectly in your case too. The serializer add-on can be used to make the backup of values and objects and then restore them.

#5271267 Lambdas/Anon.Functions: Status, implementation

Posted by on 15 January 2016 - 07:29 AM

Hi Ingwie. Welcome to the forum! :)


Yes. anonymous functions, a.k.a. lambdas, are now supported by AngelScript (since the last public release, 2.30.2).


Implementation wise, they are just ordinary script functions and can be passed to the application as a function pointer the same way. The function pointer is represented by the asIScriptFunction interface to the application. Using the function pointer it can be called using the script context normally.


The manual has an article that shows how to pass a function pointer to the application and then calling it.




#5268242 Accessing an object managed by the engine through a global variable

Posted by on 28 December 2015 - 06:43 PM

What about setting the value of the global parameter through GetAddressOfGlobalVar() like I showed you above? Is that okay? And is the global variable still allowed to be a handle even though the object type is not garbage collected?


Yes. This is the correct way of doing it.


asOBJ_NOCOUNT just means that the type doesn't rely on reference counting for controlling the lifetime of the objects, it doesn't mean that the types cannot be references through handles (which in this case behave pretty much the same way as ordinary pointers in C++).


Had the type been reference counted, you would still use GetAddressOfGlobalVar() to set the value, but you would have to take care to call Release on the previous object and AddRef on the new object when changing the address.

#5268202 Accessing an object managed by the engine through a global variable

Posted by on 28 December 2015 - 10:42 AM

What you've done is perfectly fine if you trust the script writers not to do something unexpected with the ScriptComponent reference. For example, if the script store a reference to the ScriptComponent in some other variable for use at a later time. That might end up causing crashes due to dangling pointers if the script tries to access the object after it has been destroyed in the game engine. 


If you do not trust the script writers, e.g. if you plan to allow end users to write their own scripts, then you may want to use a little more secure way of managing your pointers, e.g. add proper reference counting in the objects to make sure they aren't destroyed while there are still active references to them, and probably also use weak-references to avoid keeping objects alive longer than necessary.

#5265294 Array doesn't properly document find and findByRef

Posted by on 07 December 2015 - 11:53 AM

Thanks. I'll make the necessary adjustments.

#5264130 Support for unicode identifiers

Posted by on 29 November 2015 - 12:13 PM

Having the tokenizer call a callback for every identifier would probably impact the compiler performance quite a bit for everyone, even those who would not use the callback.  


Instead I suggest you modify the CScriptBuilder add-on to translate special identifiers to keywords before passing the script to the compiler. The CScriptBuilder already has logic for doing a pre-compile pass on the code script and change some things, so it should be quite easy for you to implement that on your own.


Alternatively you can customize the asCTokenizer to translate the special identifiers for you.