⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 oasisscriptsystem.cpp

📁 使用stl技术,(还没看,是听说的)
💻 CPP
字号:
/******************************************************************************

 * This source file is part of Bad Camel Gaming

 * Copyright (C) 2003  Zephie Greyvenstein

 * See Readme.html for acknowledgements

 *

 * This library is free software; you can redistribute it and/or

 * modify it under the terms of the GNU Lesser General Public

 * License as published by the Free Software Foundation; either

 * version 2.1 of the License, or (at your option) any later version.

 *

 * This library is distributed in the hope that it will be useful,

 * but WITHOUT ANY WARRANTY; without even the implied warranty of

 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU

 * Lesser General Public License for more details.

 *

 * You should have received a copy of the GNU Lesser General Public

 * License along with this library; if not, write to the Free Software

 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

 *****************************************************************************/



/*****************************************************************************

 * FILENAME    : oasisScriptSystem.cpp

 * DESCRIPTION : Scripting engine

 * AUTHOR      : Zephie Greyvenstein, Godot

 ****************************************************************************/



#include "oasisScriptSystem.h"

#include "oasisScriptInterpreter.h"

#include "oasisScriptCommon.h"

#include "oasisConsoleSystem.h"

#include "oasisVector3.h"

#include "oasisQuaternion.h"

#include "oasisAudible.h"

#include "oasisMovable.h"

#include "oasisPhysical.h"

#include "oasisSound.h"

#include "oasisPhysics.h"

#include "oasisPool.h"

#include "oasisVisible.h"

#include "oasisEntity.h"

#include "oasisColour.h"

#include "oasisScriptExtension.h"

#include "oasisRoot.h"



#include "OgreLogManager.h"

#include "OgreStringVector.h"

#include "OgreDataChunk.h"



//#include <stdio.h>

//#include <stdarg.h>



namespace Oasis {

  

  template< > scriptSystem *singleton< scriptSystem >::singletonPtr = 0;

  

  scriptSystem::scriptSystem( ) : system( "Script" ) {   

    

/// TODO: InterpreterManager or not?    _parseAllSources( ".scripts" );

    loaded = LNONE;    

    specifics = NULL;

  }

  

  scriptSystem::~scriptSystem( ) {

    if( loaded != LNONE && specifics )

      delete specifics;  

  }

  

  scriptSystem &scriptSystem::get( void ) {

    return singleton< scriptSystem >::get( );

  }

  

  scriptSystem *scriptSystem::getPtr( void ) {

    return singleton< scriptSystem >::getPtr( );

  }

  

  void scriptSystem::reset( void ) {

    if( loaded == LNONE ) return;

    specifics->reset( );

  }



  void scriptSystem::initLanguage( Language toinit ) {

    int i = 0;

    if( loaded != LNONE ) {

      delete specifics;

      specifics = NULL;

      loaded = LNONE;

    }

    if( toinit == LLUA ) {

#ifndef HAS_LUA

      scriptLog( "How are you going to use Lua scripts w/o Lua?" );

#endif

#ifdef HAS_LUA

      specifics = new scriptLuaInterpreter( );

      loaded = LLUA;

#endif

    }

    else if( toinit == LRUBY ) {

#ifndef HAS_RUBY

      scriptLog( "How are you going to use Ruby scripts w/o Ruby?" );

#endif

#ifdef HAS_RUBY

      specifics = new scriptRubyInterpreter( );

      loaded = LRUBY;

#endif      

    }

    else {

      scriptLog( "Attemptimg to load script, but Language isn't defined." ); 

    }



    //Setup the extensions to any particular language

    for( ; i < extensions.size( ) ; i++ )

      extensions[i]->enableScripting( );

      

  }

  

  void scriptSystem::update( real time ) {

    //PENDING: Do we even need this anymore?

  }

    

  void *scriptSystem::executeString(uint8 &type, const char *command, ... ) {

    char buffer[4097];

    void *retv;

    if( loaded == LNONE || specifics == 0 ) return NULL;

    va_list list;

    va_start( list, command );



  ::vsnprintf( buffer, 4096, command, list );

    string strcmd = buffer;

    retv = specifics->executeString( strcmd, type );



    va_end( list );

    return retv;

  }

  

  void scriptSystem::executeScript( const string &name ) {

    if( loaded == LNONE || specifics == 0 ) return;

    

    uint8 i=0;

    string strname;

    

    if( loaded == LLUA )  

      strname = name + ".lua";

    else if ( loaded == LRUBY )  

      strname = name + ".rb";

    for( i=0; i<root::get().directories.size(); i++ ) {

      string strbuf = root::get().directories[i] + strname;

      scriptSystem::get().scriptLog( string( "Trying: " ) + strbuf );

      if( specifics->executeScript( strbuf ) ) 

        break; 

    }

    

    if( i==root::get().directories.size() )

      scriptSystem::get().scriptLog( string( "Couldn't find: " ) + strname );

    

  }



  void scriptSystem::scriptLog( const string &message ) {

    Ogre::LogManager::getSingleton( ).logMessage( "SCRIPT: " + message );

    //std::cout << " SCRIPT " + message << std::endl;

    if ( consoleSystem::getPtr( ) ) {

      consoleSystem::get( ).write( message );

    }

  }

  

  void *scriptSystem::callFunction(uint8 &returntype, 

                    string funct, char *types, ... ) {

    uint16 i;

    uint16 len = strlen( types );

    va_list list;

    string strtypes;

    void *next_arg;

    void ** input    = ( void ** ) new ( void * )[len];

    //This variable is going to store references to allocated memory

    //for later deletion.

    void ** input_cp = ( void ** ) new ( void * )[len];

    void * retv;

    if( loaded == LNONE || specifics == 0 ) return NULL;

    va_start( list, types );

    // populate the function's argument list

    // Note that va_* only allows for integer types (whether pointers

    // or just integer values), so we convert to/from.

    for( i = 0;i < len; i++ ) {

      if(types[i] == 'i') {

        int16 *ni = new int16;

        *ni = ( int16 ) va_arg( list, int32 );

        next_arg = ( void * ) ni;

      }

      else if(types[i] == 'd') {

        int32 *ni = new int32;

        *ni = va_arg( list, int32 );

        next_arg = ( void * ) ni;

      }

      else if(types[i] == 'c') {

        uint8 *ni = new uint8;

        *ni = ( uint8 ) va_arg( list, int32 );

        next_arg = ( void * ) ni;

      }

      else if(types[i] == 'b') {

        bool *ni = new bool;

        *ni = ( bool ) va_arg( list, int32 );

        next_arg = ( void * ) ni;

      }

      else if(types[i] == 's') {

        char *ni,*cp;

        ni = va_arg( list, char * );

        cp = new char[ strlen( ni ) ];

        strcpy( cp, ni );

        next_arg = ( void * ) cp;

      }

      else if(types[i] == 'f' || types[i] == 'r' ) {

        real *ni = new real;

        *ni = va_arg( list, real );

        next_arg = ( void * ) ni;

      }

      else if(types[i] == 'q') {

        quaternion *ni, *cp;

        ni = va_arg( list, quaternion * );

        cp = new quaternion( ni->w, ni->x, ni->y, ni->z );

        next_arg = ( void * ) cp;

      }

      else if(types[i] == 'v') {

        vector3 *ni, *cp;

        ni = va_arg( list, vector3 * );

        cp = new vector3( ni->x, ni->y, ni->z );

        next_arg = ( void * ) cp;

      }

      else {

        scriptSystem::get().scriptLog( "Unknown type passed to callFunction!!" );

      }

      input[i]=specifics->convertFromC( next_arg, types[i] );

      input_cp[i]=next_arg;

    }

    va_end( list );

    // call the scripted function, capture the output, convert the output.

    strtypes = types;

    // call the function ( non-specific to scripting language :) )

    retv = specifics->callFunction( funct, strtypes, input, returntype );

    // free the variables/return the converted ouput

   

    for( i = 0; i < len; i++ ) {

      freeVariable( input_cp[i], types[i] );

      specifics->freeVariable( input[i] );

    }

    

    return retv;

  }



  void scriptSystem::freeVariable( void * var, uint8 type )

  {

    if(type == 'i') 

      delete (int16 *) var;

      

    else if(type == 'd') 

      delete (int32 *) var;

      

    else if(type == 'c') 

      delete (uint8 *) var;

      

    else if(type == 'b') 

      delete (bool *) var;

      

    else if(type == 's') 

      delete (char *) var;

      

    else if(type == 'f' || type == 'r' ) 

      delete (real *) var;

      

    else if(type == 'q') 

      delete (quaternion *) var;

      

    else if(type == 'v') 

      delete (vector3 *) var;

      

    else if(type == '0') 

      return;

      

    //else

      //scriptSystem::get().scriptLog( "Tried to delete unknown type." );

  }

  string scriptSystem::toString( void *var, uint8 type ) {

    if(type == 'i' || type == 'd') {

      char ret[32];

      sprintf( ret, "%d", *( int32 * ) var );

      return string( ret ) + string( " : type 'int'" );

    }

    else if(type == 'c') {

      string ret = "0";

      ret[0] = *( char * )var;

      return ret + string( " : type 'char'" );

    }

    

    else if(type == 'b') 

      return ( *( bool * ) var ? "True" : "False" );

      

    else if(type == 's') 

      return string( ( char * ) var + string( " : type 'string'" ) );

      

    else if(type == 'f' || type == 'r' ) {

      char ret[64];

      sprintf( ret, "%f", *( real * ) var );

      return string( ret ) + string( " : type 'real'" );

    }

      

    else if(type == 'q') {

      char ret[256];

      quaternion *val = ( quaternion * ) var;

      sprintf( ret, "(w%f, x%f, y%f, z%f)", val->w, val->x, 

                                val->y, val->z );

      return string( ret ) + string( " : type 'quaternion'" );

    }

      

    else if(type == 'v') {

      char ret[256];

      vector3 *val = ( vector3 * ) var;

      sprintf( ret, "(x%f, y%f, z%f)", val->x, val->y, val->z );

      return string( ret ) + string( " : type 'vector3'" );

    }

      

    else if(type == '0') 

      return "Nil";

      

    else {

      /*string retv= " :Undefined";

      retv[0]=type;*/

      return "";

    }

    

  }

};

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -