hometiscriptIntegration

Integration

Integration of TIScript is pretty straightforward. Let's take a look on it step by step. I will use C++ here for the sake of conciseness. C API is also available - just take a look on tiscript.h and comments inside.

Step 1. Creating the engine

side note:
std_stream implementation
/* console io */
class std_stream: public tiscript::stream
{
virtual int  get()
  { return fgetc( stdin ); }
virtual bool put(int v)
  { return fputc( v, stdout ) != EOF; }
};

/* include TIScript C++ API header. */
#include "tiscript.hpp"

/* Create instance of simple stream which will be used by script for its stdio, stdin, stderr */
std_stream cio;

/* Create instance of engine */
tiscript::engine tis(&cio);

At this point we have working instance of the engine in variable tis.

Step 2. Defining native classes

Native classe are classes implemented in C++ to be called from script. Native class definition is an instance of struct TIS_class_def.  

/* MessageBox class - standard message box object */

TIS_class_def MessageBoxClass =
{
 "MessageBox",          // name of the class as it seen in script
 MessageBox_methods,    // list of methods
 MessageBox_properties, // list of properties
 MessageBox_destructor  // destructor function
};
As you may see above, to define class you need to provide:
  • list of method definitions - array of pairs: name/pointer to C++ functions - implementation of the method. Function with the name "this" will serve a role of constructor.
  • list of property definitions - array of pairs: name/pointer to C++ functions - implementation of the property
  • and C++ function - implementation of destructor.  Script engine will call it during garabage collection.
Implementation of native method may look like as:
static VOID CALLBACK MessageBox_show(
    HSCRIPT hse,  // instance of the engine
    void** p_data_slot, // instance data slot (initialized in ctor)
    tiscript::value* argv, int argc, // vector of parameters of the method
    tiscript::value* retval) // return value of the method
{
 MessageBox_instance* pinst = (MessageBox_instance*)*p_data_slot;
 if( pinst )
   ::MessageBoxW(NULL, pinst->message, pinst->caption , MB_OK | MB_ICONEXCLAMATION);
 else // error, this is memeber function so it has to be invoked as
      // this.show() or mb.show() but not as MessageBox.show();
   tiscript::engine(hse).throw_error(L"member function!");  
}
 
/* add our native class to script name space */

tis.add(&MessageBoxClass);

At this point we have initialized scripting engine with our class registered. Next is ...

Step 3. Running scripts

/* creating input stream for reading our script code */
tiscript::file_in_stream in( "c:/test.js" );
if(!in.is_valid())
{
printf( "cannot open %s\n", "c:/test.js" );
return -1;
}
/* load and execute script from the in stream. */
if(!tis.load( &in ))
  return -2;
 
/* done */

Step 4. (optional) Calling script functions

Script execution starts immediately on load but you may want to call scripting functions from your C++ code. Never been easier, see:

/* defining array of parameters for script function */

tiscript::value argv[2] =
{
tiscript::value(1),
// int parameter
tiscript::value(L
"hello") // string parameter
};

/* assume that there is MyScriptFunction defined in script, let's call it then: */

tiscript::value r = tis.call(L"MyScriptFunction", argv, 2 /* argc */ );

/* in r we have result returned by MyScriptFunction, report it */
printf( "got from script:%S\n", r.get(L"?") );

Done. We have implemented all typical steps of script engine integration into C++ application.

Full source code of tis.exe - console application using TIScript is in /samples/console/tis.cpp of TIScript SDK.

TIScript

Classes
Download