Skip to content
Craig Minihan edited this page Oct 31, 2016 · 14 revisions

#Overview libscriptobject is a C++ library allowing applications to store scriptable objects and arrays and expose them to embedded scripting engines.

libscriptobject stores the objects on your C++ application's heap not in the scripting engines heap, therefore it works very well when you have very large numbers of scriptable objects which would not normally fit inside the managed memory space of a scripting engine.

Unlike C++ types scriptable objects are created at runtime. They are self-describing allowing callers to discover the number of fields, their names and their types dynamically.

#Key Concepts libscriptobject can support complex hierarchies of objects and arrays. An object may consist of many named and typed value fields, it may consist of other objects or it may consist of arrays. Arrays can in turn hold values, objects and other arrays. In this way complex object hierarchies may be expressed and exposed to embedded scripting engines like V8, SpiderMonkey or Python.

Values are expressed as strings, integers, floats, booleans, nulls and undefined. Objects, arrays and values are generally immutable in libscriptobject with one exception. It is possible to change the value of a string field in an object or an array - within limitations. Otherwise objects or arrays must be cloned to be modified.

##Objects and Arrays are Self-Describing In libscriptobject all objects and arrays expose members which allow callers to determine the number of fields, their types, their names and the values that they contain. This in turn can be exposed to your scripting engine allowing the hosted language to query for object metadata information dynamically.

For example, in JavaScript this may manifest itself as the following code:

  for (var name in obj) {
    var value = obj[name];
    // ...   
}

##Objects are Usually Very Similar Early scripting engines stored objects as key-value pairs, usually with fast lookup. Scripting engine developers soon noticed that most objects processed by their engines looked the same (same fields, same types, etc.). Therefore duplicating the key-value lookup in each instance was rather wasteful on CPU and memory.

As an optimization the V8 scripting engine actually generates static code when it encounters a new object 'type' and then loads the type definition as a dynamic module. In essence it is like knowing and statically defining the type at the compilation stage and embedding it in your applications binary. The CPU and memory performance gains of this technique were a major contributor to the early JavaScript performance lead held by V8.

In libscriptobject we don't generate code-on-the-fly to describe objects. When a new object is created the number of fields, their names and types are compared to known objects and if there is a match the object definition is re-used. This functionality is called the key-cache. In this way libscriptobject keeps memory overhead low and still gains from fast field name look-ups without needing exotic optimizations.

There is a catch to using shared object definitions, either by code-generation or shared key-value lookup. If objects have fields with randomly generated field names (i.e. GUIDs) then the performance gains are lost and the system performance may actually degrade substantially. In this case libscriptobject can create objects bypassing the key-cache.

##Object and Array Factories Objects and arrays are created by their respective specialized factory classes. To create either an object or an array you need to define a source for the instance. The factory decouples the creation process from the technicalities of the object source. In this way you can create objects from JSON, msgpack, from the script engine or from any source which can describe the object to be created.

##Limitations Objects and arrays are immutable with one exception: You may change the value of a string field as long as the new string is equal in length or shorter than the previous string. The object or array is not re-allocated, the new string data is simply written over the old string data and the string length is updated in the object metadata.