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

📄 oasisscriptluainterpreter.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    : oasisScriptLuaInterpreter.cpp

 * DESCRIPTION : The grunt of the lua language.

 * AUTHOR      : Gaw (garcia@cs.ttu.edu)

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

//only compile if Lua is included in the library

#ifdef HAS_LUA

#include <vector>



#include "oasisScriptInterpreter.h"

#include "oasisScriptSystem.h"

#include "oasisVector3.h"

#include "oasisQuaternion.h"

#include "oasisScriptLuaInterpreter.h"



#include "OgreLogManager.h"



extern int tolua_engine_open( lua_State * );



namespace Oasis {

  

  scriptLuaInterpreter::scriptLuaInterpreter( ) 

    : scriptInterpreter( ) {   

    luaInterpreter = lua_open( ); 

    loadLibs( );

  }

  

  scriptLuaInterpreter::~scriptLuaInterpreter( ) {

    lua_close( luaInterpreter );

  }



  bool scriptLuaInterpreter::executeScript( string &name ) {

    scriptSystem::get( ).scriptLog( "Attempting to load " + name );

    return !lua_dofile( luaInterpreter, name.c_str( ) );

  }



  void *scriptLuaInterpreter::executeString( string &name, uint8 &type ) {

    int top = lua_gettop( luaInterpreter );

    lua_dostring( luaInterpreter, name.c_str( ) );

    //If anything in the size of the stack has changed, you have a return value

    //note the above technique doesn't work because a sub-interpreter

    //is started to evaluate the string.

    if( lua_gettop( luaInterpreter ) - top ) 

      return convertToC( ( void * ) NULL, type );

    

    type = '0';

    return ( void * ) NULL;

  }



  void scriptLuaInterpreter::reset( ) {

    lua_close( luaInterpreter );

    luaInterpreter = lua_open( ); 

    loadLibs( );

  }



  //This function displays errors to the console.

  int errorHandler( lua_State *L ) {

    string error = lua_tostring( L, 1 );

    scriptSystem::get( ).scriptLog( error );

    return 1;

  }

  

  void scriptLuaInterpreter::loadLibs( ) {

    lua_register( luaInterpreter, "_ALERT", ( lua_CFunction )&errorHandler );

    lua_register( luaInterpreter, "_OUTPUT", ( lua_CFunction )&errorHandler );

    luaopen_base( luaInterpreter ); 

    luaopen_table( luaInterpreter );

    luaopen_io( luaInterpreter );

    luaopen_string( luaInterpreter );

    luaopen_math( luaInterpreter );

    luaopen_debug( luaInterpreter ); 

    luaopen_loadlib( luaInterpreter ); 

    tolua_engine_open( luaInterpreter );

  }



  void scriptLuaInterpreter::loadLibrary(

                            int ( *callback )( lua_State * ) ) {

    callback( luaInterpreter ); 

  }



  void *scriptLuaInterpreter::convertFromC( void *cObject, uint8 type ) {

    //conversion from and to the stack are intertwined, pushing it on

    //now would only be error prone, this is done later.  During callFunction

    return cObject;

  }

  void scriptLuaInterpreter::_convertFromC( void *cObject, uint8 type ) {

    int i;

    //numbers

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

      lua_pushnumber( luaInterpreter, ( real ) *( int32 * ) cObject );

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

      lua_pushnumber( luaInterpreter, *( real * ) cObject );



    //bool

    else if( type == 'b' ) 

      lua_pushboolean( luaInterpreter, *( bool * ) cObject );

    

    

    //vector

    else if( type == 'v' ) {

      lua_newtable( luaInterpreter );

      lua_pushnumber( luaInterpreter, ( ( vector3 * ) cObject )->z );

      lua_pushnumber( luaInterpreter, ( ( vector3 * ) cObject )->y );

      lua_pushnumber( luaInterpreter, ( ( vector3 * ) cObject )->x );

      for( i = 0; i < 3; i++ ) 

        lua_rawseti( luaInterpreter, -( 4-i ), i+1 );

      lua_pushstring( luaInterpreter, "n" );

      lua_pushnumber( luaInterpreter, 3 );

      lua_settable( luaInterpreter, -3 );

    }

    

    //quaternion

    else if( type == 'q' ) {

      lua_newtable( luaInterpreter );

      lua_pushnumber( luaInterpreter, ( ( quaternion * ) cObject )->z );

      lua_pushnumber( luaInterpreter, ( ( quaternion * ) cObject )->y );

      lua_pushnumber( luaInterpreter, ( ( quaternion * ) cObject )->x );

      lua_pushnumber( luaInterpreter, ( ( quaternion * ) cObject )->w );

      for( i = 0; i<4; i++ ) 

        lua_rawseti( luaInterpreter, -( 5-i ), i+1 );

      lua_pushstring( luaInterpreter, "n" );

      lua_pushnumber( luaInterpreter, 4 );

      lua_settable( luaInterpreter, -3 );

    }

    

    //character

    else if( type == 'c' ) {

      char tmpstr[2];

      tmpstr[0] =  *( char * )cObject ;

      tmpstr[1] = 0;

      lua_pushstring( luaInterpreter, tmpstr );

    }

    else if( type == 's' ) 

     lua_pushstring( luaInterpreter, ( char * ) cObject ); 

    else 

      scriptSystem::get( ).scriptLog(

         " Error, bad typed passed to callFunction->_convertFromC " );

  }



  void *scriptLuaInterpreter::convertToC( void *scriptObject, uint8 &type ) {

    void *ret;

    int index = lua_gettop( luaInterpreter );

    int toptype = lua_type( luaInterpreter, index );

    

    if ( toptype == LUA_TBOOLEAN ) { 

      ret = ( void * ) new bool( lua_toboolean( luaInterpreter, index ) );

      type = 'b';

    }

        

    else if ( toptype == LUA_TNUMBER ) { 

      ret = ( void * ) new real( lua_tonumber( luaInterpreter, index ) );

      type = 'r';

    }

    

    else if ( toptype == LUA_TSTRING ) {

      ret = ( void * ) lua_tostring( luaInterpreter, index );

      type = 's';

    }

        

    //We are only supporting vectors and quaternions,

    //so the list must 1) be linear and 2) contain either

    //3 or 4 elements of type real.

    else if ( toptype == LUA_TTABLE ) {

      std::vector < real > list;

      int i = 1;

      

      for( ; ; i++ ) {

        //Get array entry 'index' and push result on stack

        lua_rawgeti( luaInterpreter, index, i ); 

        //nil signifies no other entries in array

        //-1 means the top element in the stack.

        if( lua_isnil( luaInterpreter, -1 )) break;  

        //PENDING: What happens when this isn't a number?

        list.push_back( lua_tonumber( luaInterpreter, -1 ) );

        lua_pop( luaInterpreter, 1 );

      }

      //clean up the nil element

      lua_pop( luaInterpreter, 1 );



      if( list.size() == 3 ) {

        ret = ( void * ) new vector3( list[0], list[1], list[2] );

        type = 'v';

      }

      else if( list.size() == 4 ) {

        ret = ( void * ) new quaternion( list[0], list[1],

                            list[2], list[3] );

        type = 'q';

      }

      //Should never be more than 4.

      else {

        ret = ( void * ) NULL;

        type = '0';

      }

    }



    //Let's support passing in the type 'quaternion' and 'vector3'

    else if( toptype == LUA_TUSERDATA || toptype == LUA_TLIGHTUSERDATA ) {

      lua_getmetatable( luaInterpreter, index );

      //http://celestia.teyssier.org/lxr/source/src/celestia/celx.cpp

      lua_rawget( luaInterpreter, LUA_REGISTRYINDEX );



      //If the class isn't registered

      if( lua_type( luaInterpreter, -1 ) != LUA_TSTRING ) {

        lua_pop( luaInterpreter, 1 );

        type = '0';

        return ( void * ) NULL;

      }



      const char *name = lua_tostring( luaInterpreter, -1 );      

      lua_pop( luaInterpreter, 1 );

      //invalid name

      if( !name ) {

        type = '0';

        ret = ( void * ) NULL;

      }



      //vector3

      else if(strcmp( name, "vector3" ) == 0) {

        vector3 *flua = ( vector3 * ) 

                lua_touserdata( luaInterpreter, index );

        ret = new vector3( flua->x, flua->y, flua->z );

        type = 'v';

      }



      //quaternion

      else if(strcmp( name, "quaternion" ) == 0) {

        quaternion *flua = ( quaternion * )

                lua_touserdata( luaInterpreter, index );

        ret = new quaternion( flua->w, flua->x, flua->y, flua->z );

        type = 'q';

      }

    }

    

    else {

      ret = ( void * ) NULL;

      type = '0';

    }



    return ret;

  }



  void *scriptLuaInterpreter::callFunction( string &name, string &types, 

                                        void **arguments,

                                        uint8 &returntype ) {

    int i;

    int top = lua_gettop( luaInterpreter );

    //Lookup our function in the globals table.

    lua_pushstring( luaInterpreter, name.c_str( ) );

    lua_gettable( luaInterpreter, LUA_GLOBALSINDEX );

    //push the arguments on the stack.

    //PENDING:  Do these arguments get reversed?

    for( i=0; i < types.length( ); i++ ) {

      _convertFromC( arguments[i], types[i] );

    }

    lua_call( luaInterpreter, types.length(), 1 ); 

    

    if( top < lua_gettop( luaInterpreter ) )

      return convertToC( ( void * ) NULL, returntype );

    else {

      returntype = '0';

      return ( void * ) NULL;

    }

  }

  void scriptLuaInterpreter::freeVariable( void *script_var ) {

  }

};



#endif

⌨️ 快捷键说明

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