lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


Hi Peter,

We talked about lua before, if you remembering. I aked a question about the 
difference between lua_dofile and luaL_loadfile and why lua_dofile is working 
and luaL_loadfile isn't working. In the attachment i send you some classes i 
which i had written for a game project im working for. It's job is to wrapp 
some functions of a other class, but this shouldn't be important.

In cScripting.cpp about line 18 i load the script. luaL_loadfile returns 0. 
But if i call it cames attempt to call a nil value. Today i had a quick view 
in the lua sources. Speciely lauxlib.c.
The only difference between this two functions is that lua_dofile 
luaL_loadfile over aux_do calles. If i delete in aux_do the lua_pcall all 
went and i compile the lua new. lua_dofile works too. But their is no 
difference to take luaL_loadfile directly. Have you a clue why and is it 
dangerous to delete the lua_pcall in the lua sources. Because it is a bit 
faster and we trying to get the game as fast as possible.

Thanks for your time and help and have a nice day,
  	- Johannes


#ifndef __SCRIPT__H__

#define __SCRIPT__H__

namespace script
{
class cScript;
class cScriptPoint;
class cScriptList;
class cInterpreter;
};


#include "cScripting.h"

#endif /*__SCRIPT__H__*/

function test_lua_scripting()

	show()

end


function test()

	show()
	
end
LIBS = `sdl-config --cflags --libs` -llua -llualib
OBJ = ../cObject.cpp ../cObjectContainer.cpp ../cScripting.cpp main.cpp

test: $(OBJ)
	g++ $(OBJ) -o test $(LIBS)

cObject.o: ../cObject.cpp
	g++ -c -g ../cObject.cpp $(LIBS)

cObjectContainer.o: ../cObjectContainer.cpp
	g++ -c -g ../cObjectContainer.cpp $(LIBS)

cScripting.o: ../cScripting.cpp
	g++ -c -g ../cScripting.cpp $(LIBS)

main.o: main.cpp
	g++ -c -g main.cpp $(LIBS)
#include "../cScripting.h"

using namespace script;

int main(int argc, char *argv[])
{

    cInterpreter *interp = cInterpreter::getInstance();
    cScriptList *script_list = cScriptList::getInstance();
    
    obj::cBaseObject *test_object1;

    int test_script1 = script_list->addScript("test.lua", "test_lua_scripting");
    cerr<<test_script1<<endl;
    int test_script2 = script_list->addScript("test.lua", "test_lua_scripting");
    cerr<<test_script2<<endl;
    int test_script3 = script_list->addScript("test.lua", "test_lua_scripting");
    cerr<<test_script3<<endl;
    int test_script4 = script_list->addScript("test2.lua", "test");
    cerr<<test_script4<<endl;

    interp->runScript(test_object1, script_list->getScript(test_script1)); 
    interp->runScript(test_object1, script_list->getScript(test_script2));
    interp->runScript(test_object1, script_list->getScript(test_script3));
    interp->runScript(test_object1, script_list->getScript(test_script4));

    test_script2 = script_list->deleteScript(test_script2);

    interp->runScript(test_object1, script_list->getScript(test_script1));
    interp->runScript(test_object1, script_list->getScript(test_script2));
    interp->runScript(test_object1, script_list->getScript(test_script3));
    interp->runScript(test_object1, script_list->getScript(test_script4));

	cerr<<"third time"<<endl;

    test_script4 = script_list->deleteScript(test_script4);

    interp->runScript(test_object1, script_list->getScript(test_script1));
    interp->runScript(test_object1, script_list->getScript(test_script2));
    interp->runScript(test_object1, script_list->getScript(test_script3));
    interp->runScript(test_object1, script_list->getScript(test_script4));



    return 0;
}


#ifndef _LUA_SCRIPTING_H_
#define _LUA_SCRIPTING_H_

extern "C"{
    #include <lua.h>
    #include <lauxlib.h>
    #include <lualib.h>
}

#include <iostream>
#include <fstream>
#include "cObject.h"

/**
* Namescpae aller Klassen, die mit dem Scripting der cObject Klassen zu tuen hat
*/

namespace script {


/**
* Speichert die eigentlichen Scriptdaten
* @author Johannes Hager email: hager.j@gmx.de
*/

class cScript{

    private:

        int m_id;			/**< Id des Scriptes */
        int counter_used;		/**< wieviele Instanzen nutzen dieses Script */
        char *script_file;
        char *script_function;

    public:

    	/**
	* @param 	Name des Scriptes
	* @param 	Name der Lua Funktion, innerhalb des Scriptes
	*/
        cScript(char *filename, char *function_name);
        ~cScript();

    protected:

        int getId();
        void setId(int id);

	/**
	* erhöht counter_used um eins
	* @param	void
	* @return	void
	*/
	void inkCounter();

	/**
	* verringert counter_used um eins
	* @param 	void
	* @return	void
	*/
        void dekCounter();
        int getCounter();
        char *getFile();
        char *getFunction();

        friend class cScriptList;
        friend class cInterpreter;
};

/**
* die einzelnen Knoten für cScriptList
* @author Johannes Hager email: hager.j@gmx.de
*/

class cScriptPoint{

    private:

        cScriptPoint *m_pNext;			/**< Zeiger auf naechsten Listenknoten */
        cScriptPoint *m_pLast;			/**< Zeiger auf vorherigen Listenknoten */

        friend class cScriptList;

    public:

        cScript *m_pScript;			/**< Zeiger auf das eigentliche Script */

        cScriptPoint();

	/**
	* Wird von cScriptList->addScript() aufgerufen und erzeugt den neuen Konten in der Liste
	* @param	Name der Scriptdatei
	* @param	Name der Lua Funktion
	* @param	Zeiger auf den nächsten Knoten in der Liste
	* @param	Zeiger auf den vorherigen Knoten in der Liste
	*/
        cScriptPoint(char *filename, char *function_name, cScriptPoint *next, cScriptPoint
	*last);

        ~cScriptPoint();

	/**
	* Kann die Scriptdaten des Knoten ändern / Vorsicht noch nicht benuten!
	*/

	// noch nicht korrekt implementiert
	int loadScript(char *filename, char *function_name);

        char *getFile();
        char *getFunction();

        //get& and set...functions();

        void setNext(cScriptPoint *next);
        void setLast(cScriptPoint *last);
        cScriptPoint *getNext();
        cScriptPoint *getLast();
        int getId();


};


/**
* Klasse zur Verwaltung der cScriptPoint Klasse (eigengtliche Liste)
*/

class cScriptList{

    private:

        static cScriptList *m_pInstance;      /**< Zeiger auf die einzige Instance derKlasse */

        cScriptPoint *m_pFirst;			/**< Zeiger auf das erste Element der Liste */
        cScriptPoint *m_pLast;			/**< Zeiger auf das letzte Element der Liste */
        int m_iSize;				/**< Größe der Liste */

    public:

        cScriptList();
        ~cScriptList();

        static cScriptList* const getInstance();	/**< liefert Zeiger auf die einzige 								      Instanze der Klasse */

	/**
	* Fügt ein Script der Liste an und überprpüft ob dieses schon in der Liste ist.
	* Liefert einen Integer Wert als Id zurück mit welchem man Zugriff auf das Script hat
	* @param	Name der Scriptdatei
	* @param	Name der Lua Funktion
	* @return 	Script Id
	*/
        int addScript(char *filename, char *function_name);

	/**
	* Liefert einen Zeiger auf das cScript zurück (benötigt von cInterpreter->runScript(...)
	* @param 	Script Id
	* @return	Zeiger auf ein cScript
	*/
	cScript *getScript(int id);

	/**
	* Löscht ein Script aus der Liste
	* @param Script Id
	* @return wenn alles klappt eine 0, sprich Script gibt es nicht mehr
	*/
        int deleteScript(int id);
};

/**
* Stellt den lua State und die wrapper Funktionen zur Verfügung
*/

class cInterpreter{

    private:

        obj::cBaseObject *object;
        obj::cBaseObject *object1;
        cScript* at_run;

        static cInterpreter *m_pInstance;     /**< Zeiger auf die einzige Instanz der Klasse */

        // a whole mass of static wrapper functions...

        static int show(lua_State *L);		//nur zum tesen

    public:

        cInterpreter();
        ~cInterpreter();


	/**
	* Gibt Zeiger auf die einzige Instanz der Klasse zurück
	* @param	void
	* @return	Zeiger auf die einzige Instanz der Klasse
	*/
        static cInterpreter* const getInstance();


	/**
	* for handling ai, drawing operations etc...,
	* führt das übergebenen Lua Script aus welches Zugriff auf die static Funktionnen von
	* cBaseObject obj1 hat
	* @param	cObject Objekt :-)
	* @param	cScript
	*/
        bool runScript(obj::cBaseObject* obj1, cScript* script);

        // for doing the stuff after collision between two objects on the game field
        //int runScript(cObject& obj1, cObject& obj2, cScript& script);

};
}

#endif 

#include "cScripting.h"
using namespace script;
    
lua_State *L = lua_open();

/*********************************************************************
 *                                                                   *
 *                      cScript Class                                *
 *                                                                   *
 ********************************************************************/

cScript::cScript(char *filename, char *function_name){

    counter_used = 1;
    script_file = filename;
    script_function = function_name;
/* Important */    
    lua_dofile(L, filename);
    //luaL_loadfile(L, filename);
    // Why doesnt this work
    // It returns 0, i think that means all wents right
    // But if i call script it brings attempt to call a nil value

}

cScript::~cScript(){

}

void cScript::setId(int id){

    m_id = id;
}

int cScript::getId(){

    return m_id;
}

void cScript::inkCounter(){

    counter_used++;
}

void cScript::dekCounter(){

    counter_used--;
}

int cScript::getCounter(){

    return counter_used;
}

char *cScript::getFile(){

    return script_file;
}

char *cScript::getFunction(){

    return script_function;
}


/*********************************************************************
 *                                                                   *
 *                      cScriptPoint Class                           *
 *                                                                   *
 ********************************************************************/

cScriptPoint::cScriptPoint(){


}

cScriptPoint::cScriptPoint(char *filename, char *function_name, cScriptPoint *next, cScriptPoint *last){
                      
    m_pScript = new cScript(filename,function_name);
    
    m_pNext = next;
    m_pLast = last;
}

cScriptPoint::~cScriptPoint(){


}


void cScriptPoint::setNext(cScriptPoint *next){

    m_pNext = next;
}

void cScriptPoint::setLast(cScriptPoint *last){

    m_pLast = last;
}

cScriptPoint *cScriptPoint::getNext(){

    return m_pNext;
}

cScriptPoint *cScriptPoint::getLast(){

    return m_pLast;
}



/*********************************************************************
 *                                                                   *
 *                  cScriptListe Class                               *
 *                                                                   *
 ********************************************************************/

cScriptList::cScriptList(){

    m_pFirst = NULL;
    m_pLast = NULL;
}

cScriptList::~cScriptList(){

    cScriptPoint *marker = m_pFirst;
    while(marker != NULL);
    {

        m_pFirst = m_pFirst->getNext();
        delete marker;
        marker = m_pFirst;
    }
}

int cScriptList::addScript(char *filename, char *function_name){
         

    if(m_pFirst == NULL){
        m_pFirst = new cScriptPoint(filename, function_name, NULL, NULL);
        m_pLast = m_pFirst;
        m_iSize = 1;
        m_pLast->m_pScript->setId(m_iSize);
    }
    else{

        cScriptPoint *temp = m_pFirst;
        
        while(temp != NULL){
            if(strcmp(function_name, temp->m_pScript->getFunction()) == 0){
                return temp->m_pScript->getId();
                temp->m_pScript->inkCounter();
            }
            temp = temp->m_pNext;
        }

        m_pLast->setNext(new cScriptPoint(filename, function_name, NULL, m_pLast));
        m_pLast = m_pLast->getNext();
        m_iSize++;
        m_pLast->m_pScript->setId(m_pLast->getLast()->m_pScript->getId() + 1);
    }
      
    return m_pLast->m_pScript->getId();
}

cScript *cScriptList::getScript(int id){

    cScriptPoint *temp = m_pFirst;
    while(temp != NULL){
        if(temp->m_pScript->getId() == id)
            return temp->m_pScript;
        temp = temp->getNext();
    }

    return NULL;
}

int cScriptList::deleteScript(int id){

    cScriptPoint *marker = m_pFirst;
    while(id != marker->m_pScript->getId()){
        marker = marker->getNext();
    }
    if(marker->m_pScript->getId() == id){

        marker->m_pScript->inkCounter();

        if(marker->m_pScript->getCounter() <= 0){

            cScriptPoint *temp_last = marker->getLast();
            cScriptPoint *temp_next = marker->getNext();

            temp_last->setNext(temp_next);
            temp_next->setLast(temp_last);
            m_iSize--;

            delete marker;
            return 0;
        }
    }else{
        return 0;
    }
    return 0;
}





/*********************************************************************
 *                                                                   *
 *                  cInterpreter Class                               *
 *                                                                   *
 *********************************************************************/

cInterpreter::cInterpreter(){

    lua_baselibopen(L);
    lua_iolibopen(L);

    // registriert Wrapperfunktionen in lua
    lua_register(L, "show", show);              //nur zum testen

}

cInterpreter::~cInterpreter(){

    lua_close(L);
 
}  

cScriptList* const cScriptList::getInstance(){

   if(!m_pInstance)
   {
        m_pInstance = new cScriptList;
   }

   return m_pInstance;

}


cScriptList *cScriptList::m_pInstance = NULL;

/************** Beginn Wrapper Functions ******************/

//nur zum testen
int cInterpreter::show(lua_State *L){

    cout<<"test"<<endl;

    return 1;
}

/************** End Wrapper Functions *********************/

cInterpreter* const cInterpreter::getInstance(){

   if(!m_pInstance)
   {
        m_pInstance = new cInterpreter;
   }

   return m_pInstance;

}


bool cInterpreter::runScript(obj::cBaseObject* obj1, cScript* script){

    if(script == NULL){
        return false;
    }else{

        object = obj1;
        at_run = script;


        lua_getglobal(L, at_run->getFunction());

        int status = lua_pcall(L, 0, 0, 0);         // Argumente und Returns ermoeglichen
        if (status) {
            const char *msg = lua_tostring(L, -1);
            if (msg == NULL) msg = "(error with no message)";
                cerr<<"Error: "<<msg<<endl;			//Fehlerabfrage einbauen
            lua_pop(L, 1);
        }
    }
    return true;
}

cInterpreter *cInterpreter::m_pInstance = NULL;