Angelscript plugin status update.

486 views
Skip to first unread message

Jukka Jylänki

unread,
Dec 19, 2012, 12:36:53 PM12/19/12
to realxt...@googlegroups.com
Here's a short progress report on how the Angelscript research is going.

- Basic bindings are now in place. Scripts are able to understand types
'Scene', 'Entity', 'EC_Placeable', 'Transform', as well as all the
MathGeoLib types. This allows scripts to access the scene object
positions. See here for a test:
https://github.com/LudoCraft/Tundra/blob/angelscript/bin/scenes/Angelscript/script.as

- Boost shared_ptrs work and are wrapped behind a .get() function.
- Enums work (see AttributeChange::Type for example)
- Both value and reference types are available. MathGeoLib types come as
value types, others come as non-refcounted reference types. Angelscript
does not currently participate in memory management (except via
shared_ptrs), but all objects are owned in containers in Tundra core APIs.

Some things that do not yet work are QString and container types. Also
Angelscript does not have an understanding of Qt signals. There is no
delegate support in Angelscript, but it can be simulated on C++ side to
some extent.

Automatic QObject-based interop has been investigated to be impossible,
since Qt metatype mechanism does not offer the facilities for this that
Angelscript would require. QObject types can naturally be manually
exposed, but that requires interop code per class.

The Angelscript bindings generator is available at
https://github.com/juj/AngelscriptGenerator The generated bindings are
committed as part of the Angelscript plugin like with QtScript, so people
don't need to always generate them manually.

The security of Angelscript itself has been evaluated to be safe for
untrusted script execution. It has a good notion of exceptions, gracefully
fails on null pointers and handles, and it is possible to limit
long-running scripts (
http://www.angelcode.com/angelscript/sdk/docs/manual/doc_adv_timeout.html
). Limiting large memory usage needs to be implemented at a higher level,
but at least angelscript codebase does not call C system library exit(-1)
like Qt does when it runs out of memory. From the current bindings
mechanisms, only raw pointer access needs to be removed for types that can
be destroyed at runtime, but otherwise things look good.

The next (final) goal of this research task is to implement the same
script application on both JavaScript and Angelscript, and measure the
memory consumption and performance difference. This will be some kind of
synthetic test that stresses whole scene manipulation in the order of
~100-200 scene objects.

The tests will hopefully be run by the end of this week, since next week
is holidays already.

Jukka

Jukka Jylänki

unread,
Dec 20, 2012, 10:20:07 AM12/20/12
to realxt...@googlegroups.com
The benchmark tests with the Angelscript engine have now been done.

The test setup was the "Oulu3D" scene, which is a scene that contains 70
static mesh entities. A script was added to each of these entities that
simply animated the rotation of each mesh around its local up axis at each
frame. So, in total, there were 70 instantiated scripts running on each
object.

In JS:

frame.Updated.connect(Update);
var time = 0;
function Update(dt) {
time += dt;
var m = new float3x3();
m.SetRotatePartY(time);
me.placeable.SetOrientation(m.ToQuat());
}

and in AS:

float time = 0;
void update(float dt)
{
time += dt;
float3x3 m;
m.SetRotatePartY(time);
me.placeable.SetOrientation(m.ToQuat());
}

This is a very simple setup that stresses EC attribute write-only
modifications and math type creation and attribute set in a simple manner.
Both of these scripts are added to the Angelscript branch at
https://github.com/LudoCraft/Tundra/commit/84430c3c928c9b767019e0a5d45029636e46235d
if someone wants to try it out manually.

In the benchmark, both memory usage and runtime performance was measured
in a Windows Release build of Tundra. The figures are as follows:

Oulu3D scene without scripts - Memory: 331328 KB Time: 4.13 msecs/frame

Oulu3D scene in Javascript - Memory: 502384 KB Time: 13.02 msecs/frame
delta over static scene: +171056 KB Time: +8.89 msecs/frame

Oulu3D scene in Angelscript - Memory: 356760 KB Time: 5.02 msecs/frame
delta over static scene: +25432 KB Time: +0.89 msecs/frame


Computed on a per-script instance basis, each Javascript script instance
takes up 2443.66 KB of memory, whereas each Angelscript script instance
takes up 363.31 KB of memory. Executing the script takes 0.127
msecs/instance/frame for Javascript, but only 0.013 msecs/instance/frame
for Angelscript.

The overall difference is dramatic. Angelscript is ten-fold faster and
uses less than a fifth of the memory of what the QtScript engine needs.
Impressive!

Other observations:
- QtScript has gone into deprecated unmaintained state in Qt, they favor
a different QML/QtQuick architecture starting from Qt5. (reference:
https://github.com/realXtend/naali/issues/542 )
- Angelscript is way more portable than Qt (
http://www.angelcode.com/angelscript/features.html ) It builds without
problems on Windows, Linux, OSX, iOS, Android, NPAPI, NaCl and even
Emscripten (see here for a live demo
https://dl.dropbox.com/u/40949268/emcc/MathGeoLibTestAS.html )
- Angelscript is actively developed and looks like a healthy project (
http://www.angelcode.com/angelscript/users.html )
- Angelscript is statically typed, and offers better error reporting than
Qtscript. The biggest problems, namely typoing a (member) variable in
Javascript silently creates a new one, and that it's possible to assign to
a temporary that will get deleted, are impossible cases in Angelscript.

The final verdict is that Angelscript makes QtScript look slow,
memory-hogging, bloated, insecure, buggy, unmaintained, unportable and
clumsy. Going into development for a mature and maintained Angelscript
script engine plugin should be considered a long-term goal.

jj

Jonne Nauha

unread,
Dec 20, 2012, 10:44:27 AM12/20/12
to realxt...@googlegroups.com
This looks great. The mem usage is pretty funny, and this is without loading the big qt extensions into the engine :)

Did you investigate is there any automated way to expose qt core and gui to angelscript? My only gripe with this is if manipulating QWidgets in my script gets harder or impossible. Angelscript would still be ideal to write server side logic or other "headless" scripts for logic like your example has. How do we solve the dynamic widget creation and manipulation, or is it even doable?

Best regards,
Jonne Nauha
Adminotech developer


Jukka Jylänki

unread,
Dec 21, 2012, 4:23:11 AM12/21/12
to realxt...@googlegroups.com
Providing bindings for Qt was investigated using the QMetaType machinery
(in a similar way to what Ali's FunctionInvoker work does), but the end
result was that it is not possible automatically, since the required
function pointers cannot be fetched via QMetaType. Instead, the
AngelscriptGenerator tool could be used to generate bindings for Qt types,
but there are a number of features to implement to it to make it work.

Using QWidgets on mobile is not much of an option anyways, so alternate
solutions need to be found. One such is Lasse's investigation of
librocket, we'll see how it turns out and what his recommendation will be.

jj

On Thu, 20 Dec 2012 17:44:27 +0200, Jonne Nauha <jo...@adminotech.com>
wrote:
>> me.placeable.SetOrientation(m.**ToQuat());
>> }
>>
>> and in AS:
>>
>> float time = 0;
>> void update(float dt)
>> {
>> time += dt;
>> float3x3 m;
>> m.SetRotatePartY(time);
>> me.placeable.SetOrientation(m.**ToQuat());
>> }
>>
>> This is a very simple setup that stresses EC attribute write-only
>> modifications and math type creation and attribute set in a simple
>> manner.
>> Both of these scripts are added to the Angelscript branch at
>> https://github.com/LudoCraft/**Tundra/commit/**
>> 84430c3c928c9b767019e0a5d45029**636e46235d<https://github.com/LudoCraft/Tundra/commit/84430c3c928c9b767019e0a5d45029636e46235d>if
>> someone wants to try it out manually.
>>
>> In the benchmark, both memory usage and runtime performance was measured
>> in a Windows Release build of Tundra. The figures are as follows:
>>
>> Oulu3D scene without scripts - Memory: 331328 KB Time: 4.13 msecs/frame
>>
>> Oulu3D scene in Javascript - Memory: 502384 KB Time: 13.02 msecs/frame
>> delta over static scene: +171056 KB Time: +8.89 msecs/frame
>>
>> Oulu3D scene in Angelscript - Memory: 356760 KB Time: 5.02 msecs/frame
>> delta over static scene: +25432 KB Time: +0.89 msecs/frame
>>
>>
>> Computed on a per-script instance basis, each Javascript script instance
>> takes up 2443.66 KB of memory, whereas each Angelscript script instance
>> takes up 363.31 KB of memory. Executing the script takes 0.127
>> msecs/instance/frame for Javascript, but only 0.013 msecs/instance/frame
>> for Angelscript.
>>
>> The overall difference is dramatic. Angelscript is ten-fold faster and
>> uses less than a fifth of the memory of what the QtScript engine needs.
>> Impressive!
>>
>> Other observations:
>> - QtScript has gone into deprecated unmaintained state in Qt, they
>> favor
>> a different QML/QtQuick architecture starting from Qt5. (reference:
>> https://github.com/realXtend/**naali/issues/542<https://github.com/realXtend/naali/issues/542>)
>> - Angelscript is way more portable than Qt (
>> http://www.angelcode.com/**
>> angelscript/features.html<http://www.angelcode.com/angelscript/features.html>)
>> It builds without problems on Windows, Linux, OSX, iOS, Android, NPAPI,
>> NaCl and even Emscripten (see here for a live demo
>> https://dl.dropbox.com/u/**40949268/emcc/**MathGeoLibTestAS.html<https://dl.dropbox.com/u/40949268/emcc/MathGeoLibTestAS.html>)
>> - Angelscript is actively developed and looks like a healthy project (
>> http://www.angelcode.com/**angelscript/users.html<http://www.angelcode.com/angelscript/users.html>)
>> - Angelscript is statically typed, and offers better error reporting
>> than
>> Qtscript. The biggest problems, namely typoing a (member) variable in
>> Javascript silently creates a new one, and that it's possible to assign
>> to
>> a temporary that will get deleted, are impossible cases in Angelscript.
>>
>> The final verdict is that Angelscript makes QtScript look slow,
>> memory-hogging, bloated, insecure, buggy, unmaintained, unportable and
>> clumsy. Going into development for a mature and maintained Angelscript
>> script engine plugin should be considered a long-term goal.
>>
>> jj
>>
>>
>> On Wed, 19 Dec 2012 19:36:53 +0200, Jukka Jylänki <
>> jukka....@ludocraft.com> wrote:
>>
>> Here's a short progress report on how the Angelscript research is
>> going.
>>>
>>> - Basic bindings are now in place. Scripts are able to understand
>>> types
>>> 'Scene', 'Entity', 'EC_Placeable', 'Transform', as well as all the
>>> MathGeoLib types. This allows scripts to access the scene object
>>> positions.
>>> See here for a test: https://github.com/LudoCraft/**
>>> Tundra/blob/angelscript/bin/**scenes/Angelscript/script.as<https://github.com/LudoCraft/Tundra/blob/angelscript/bin/scenes/Angelscript/script.as>
>>>
>>> - Boost shared_ptrs work and are wrapped behind a .get() function.
>>> - Enums work (see AttributeChange::Type for example)
>>> - Both value and reference types are available. MathGeoLib types come
>>> as value types, others come as non-refcounted reference types.
>>> Angelscript
>>> does not currently participate in memory management (except via
>>> shared_ptrs), but all objects are owned in containers in Tundra core
>>> APIs.
>>>
>>> Some things that do not yet work are QString and container types. Also
>>> Angelscript does not have an understanding of Qt signals. There is no
>>> delegate support in Angelscript, but it can be simulated on C++ side to
>>> some extent.
>>>
>>> Automatic QObject-based interop has been investigated to be impossible,
>>> since Qt metatype mechanism does not offer the facilities for this that
>>> Angelscript would require. QObject types can naturally be manually
>>> exposed,
>>> but that requires interop code per class.
>>>
>>> The Angelscript bindings generator is available at
>>> https://github.com/juj/**AngelscriptGenerator<https://github.com/juj/AngelscriptGenerator>The
>>> generated bindings are committed as part of the Angelscript plugin like
>>> with QtScript, so people don't need to always generate them manually.
>>>
>>> The security of Angelscript itself has been evaluated to be safe for
>>> untrusted script execution. It has a good notion of exceptions,
>>> gracefully
>>> fails on null pointers and handles, and it is possible to limit
>>> long-running scripts ( http://www.angelcode.com/**
>>> angelscript/sdk/docs/manual/**doc_adv_timeout.html<http://www.angelcode.com/angelscript/sdk/docs/manual/doc_adv_timeout.html>).
>>> Limiting large memory usage needs to be implemented at a higher level,
>>> but at least angelscript codebase does not call C system library
>>> exit(-1)
>>> like Qt does when it runs out of memory. From the current bindings
>>> mechanisms, only raw pointer access needs to be removed for types that
>>> can
>>> be destroyed at runtime, but otherwise things look good.
>>>
>>> The next (final) goal of this research task is to implement the same
>>> script application on both JavaScript and Angelscript, and measure the
>>> memory consumption and performance difference. This will be some kind
>>> of
>>> synthetic test that stresses whole scene manipulation in the order of
>>> ~100-200 scene objects.
>>>
>>> The tests will hopefully be run by the end of this week, since next
>>> week
>>> is holidays already.
>>>
>>> Jukka
>>>
>>
>> --
>> http://groups.google.com/**group/realxtend-dev<http://groups.google.com/group/realxtend-dev>
>> http://wiki.realxtend.org
>> http://dev.realxtend.org
>>

to...@playsign.net

unread,
Dec 27, 2012, 11:20:34 PM12/27/12
to realxt...@googlegroups.com
Hi, and thanks for the research reports! One remark about the scripting benchmark with regards to qtscript use in current Tundra:
 
To actually script rotation or any manipulation of n objects with current Tundra the recommended way is *not* what is described in the benchmark, i.e. you should not create a separate script *engine* for each object. Instead, use of a single engine is usually better exactly to avoid the overhead. In many real application cases it also makes the programming simpler if you have some app that needs to handle many objects.
 
So instead of 70 engines with individual scripts, the much more efficient current way is to simply make one script, put it for example in a so-called application entity (just an invisible non-placed entity with a script component), get a hold of all the target objects there and do the rotations in one go. Or use the script app mechanism devised for this purpose earlier by Jukka and others at Ludo (I don’t usually use that though but just simple make such application scripts).
 
Am just noting this for information to outsiders and new developers considering Tundra, to not leave the impression that the way that benchmark was designed would be the recommended way to develop applications -- nor that the memory overhead with n engines would block application development. You can make arbitrarily complex applications with one script engine instance and not have problems with memory.
 
Tundra differs from the Linden scripting (LSL) model here: scripts are not limited to access one object only, but can do anything in the scene. For normal e.g. game development I think that is a great benefit in Tundra. Comparing with SL & Opensimulator techs, Tundra scripts are more like Opensim’s region modules in that sense -- just simpler to dev with the quite nice & clear API and very nice automated live reloading of the code. A complex application can consist of e.g. classes and method calls normally instead of requiring scene objects to text-message each other in LSL style (that is possible too with entity-actions).
 
Even if someone wants LSL style limited scoping for untrusted scripts for example so that a script can only modify the object it is attached to and not anything else in the scene, with QtScript separate engines would not be the way but you can create individual script contexts and use a single for a few engines to run all those contexts (which you might have hundreds or thousands).
 
That said, the research still holds and many of the points are valid. This post is just to clarify current best practices and possibilities with QtScript in Tundra. Angelscript sure is an interesting lightweight newcomer to the scripting scene. Javascript has a huge strong point due to the dominance but also several well known problems in the language itself (for example lack of operator overloading is very unfortunate with vector and matrix math heavy 3d apps!) -- possibly we can just consider it as a compiler target / runtime in the browsers, instead of it being directly the lang in which all the apps should be written (though that is still an attractive and kind of easy and safe way, and can be more efficient with e.g. the qt5 script biz or direct use of V8 etc.). Even in browser lands some prefer to write in e.g. CoffeeScript and then compile/translate that to Javascript, to get a dev language with nicer syntax and semantics.
 
Cheers,
~Toni
 
From: Jukka Jylänki
  static mesh entities. A script was added to each of these entities that 
simply animated the rotation of each mesh around its local up axis at each 
frame. So, in total, there were 70 instantiated scripts running on each 
object.
 
(...)
Reply all
Reply to author
Forward
0 new messages