Before everything, several links (useful) :
Now, time to show the current scripting implem^Mbeginning of implementation in Samoth :
class Script
{
public:
/* "Normal" constructor */
Script( const std::string& _filename );
/* Alternative constructor : loads a script from a buffer. Second parameter has no importance at all. */
Script( const std::string& _buffer, bool foo );
/* Only exists for SqPlus binding : mustn't be used. Never. It's evil. EVIL. */
Script() {}
/* Destructor */
~Script();
/* Returns the script's linked file name (empty string if the script was loaded from buffer) */
const std::string& getFileName() const;
/* Takes the script function's name as parameter, and returns the associated functor
T is the type of the variable returned by the called function.*/
template<class T> SqPlus::SquirrelFunction<T> call( const std::string& scriptFunctionName );
/* Same as the precedent, with T = void. But more elegant. */
SqPlus::SquirrelFunction<void> call( const std::string& scriptFunctionName );
private:
void init();
std::string mFilename;
bool mInitialized;
/* Every script is run inside the same virtual machine ; to differenciate them,
each one has its one squirrel table. By keeping a reference to this table, we
are able to choose between script1's foo() and script2's foo() functions. */
SquirrelObject mScriptObjectTable;
};And, in the .cc file :
void Script::init()
{
if( mInitialized )
{
// Don't do it twice.
return;
}
// Compile the script from a file
SquirrelObject scriptObject = SquirrelVM::CompileScript( mFilename.c_str() );
// We create a squirrel table, which will be the "namespace" of our script.
mScriptObjectTable = SquirrelVM::CreateTable();
// And we run the script inside this table
SquirrelVM::RunScript( scriptObject, &mScriptObjectTable );
mInitialized = true;
}
template<class T> SqPlus::SquirrelFunction<T> Script::call( const std::string& squirrelFunctionName )
{
if( !mInitialized ) init();
return SqPlus::SquirrelFunction<T>( mScriptObjectTable, squirrelFunctionName.c_str() );
}
SqPlus::SquirrelFunction<void> Script::call( const std::string& squirrelFunctionName )
{
if( !mInitialized ) init();
return SqPlus::SquirrelFunction<void>( mScriptObjectTable, squirrelFunctionName.c_str() );
}
For example, to call a function whose name is "onInit()", which doesn't return anything :
Script test( "../scripts/script1.nut" );
test.call( "onInit" )();
As you can see, before loading the script, we call SquirrelVM::CreateTable(). Squirrel doesn't provide "script identifiants" or functions like "getScript( unsigned int id )" ; but to call a function from a determined script, we have to access the right one. That's why each script is run inside a table : as we keep a reference to this table, we can call the script.