Gibas11 Temat założony przez niniejszego użytkownika |
[C++] [SFML] [LUA] Funkcja zawarta w klasie nie nadpisuje jej składowej » 2015-12-27 17:47:44 Witam, funkcja int luaVirtualMachine::api_read( lua_State * L ) wywoływana jest przez skrypt lua z innego wątku, z nieznanego mi powodu mimo ustawienia zmiennej „_reguiresData” zmienna ta zachowuje poprzednią wartość. Próbowałem ustawić zmienną na volatile i wyłączyć optymalizacje - bez efektu #include <SFML/System.hpp> #include <iostream> #include <queue> #include <cstring> #include <string>
using namespace std;
extern "C" { #include "lua5.2/lua.h" #include "lua5.2/lualib.h" #include "lua5.2/lauxlib.h" }
class luaVirtualMachine { private: string output; string input; sf::Thread luaScript; lua_State * state; char * _file; void execute(); bool ready; bool running; bool _reguiresData; int api_read( lua_State * L ); int api_write( lua_State * L ); public: luaVirtualMachine(); luaVirtualMachine( const char * file ); ~luaVirtualMachine(); bool open( const char * file ); bool close(); bool launch(); bool isRunning(); bool reguiresData(); void putstring( string c ); string getstring(); };
void luaVirtualMachine::execute() { luaL_dofile( state, _file ); running = false; }
int luaVirtualMachine::api_read( lua_State * L ) { _reguiresData = true; cout << _reguiresData << endl; for(;; ) { if( !reguiresData() ) { lua_pushstring( L, input.c_str() ); break; } cout.flush(); } return 1; }
luaVirtualMachine::luaVirtualMachine() : luaScript( & luaVirtualMachine::execute, this ) { ready = false; running = false; _reguiresData = false; } luaVirtualMachine::luaVirtualMachine( const char * file ) : luaScript( & luaVirtualMachine::execute, this ) { open( file ); running = false; _reguiresData = false; } luaVirtualMachine::~luaVirtualMachine() { close(); }
bool luaVirtualMachine::open( const char * file ) { if( ready ) return false; state = luaL_newstate(); luaL_openlibs( state ); lua_register( state, "read",( lua_CFunction ) & luaVirtualMachine::api_read ); _file = new char[ strlen( file ) + 1 ]; strcpy( _file, file ); ready = true; return true; } bool luaVirtualMachine::close() { if( !ready ) return false; lua_close( state ); ready = false; delete _file; return true; } bool luaVirtualMachine::launch() { if( !ready ) return false; running = true; luaScript.launch(); return true; }
bool luaVirtualMachine::isRunning() { return running; } bool luaVirtualMachine::reguiresData() { return _reguiresData; }
void luaVirtualMachine::putstring( string s ) { input = s; _reguiresData = false; } string luaVirtualMachine::getstring() { return output; }
int main() { luaVirtualMachine lvm1( "example.lua" ); lvm1.launch(); while( lvm1.isRunning() ) { cout << lvm1.reguiresData(); if( lvm1.reguiresData() ) { string str; cin >> str; lvm1.putstring( str ); } } return 0; }
EDIT: Poprawiłem literówkę. |
|
1aam2am1 |
» 2015-12-27 18:11:26 Linijkę wyżej zmieniasz ją na true |
|
Gibas11 Temat założony przez niniejszego użytkownika |
» 2015-12-27 18:17:07 No właśnie, a tak jak mówiłem w innym wątku (11 linia od dołu) wyświetla mi, że dalej jest równa 0 , w tym problem. |
|
Monika90 |
» 2015-12-27 18:39:27 Taka zmienna powinna być atomowa: std::atomic<bool>.
lua_register( state, "read",( lua_CFunction ) & luaVirtualMachine::api_read );
|
To jest prawdopodobnie błędne. |
|
Gibas11 Temat założony przez niniejszego użytkownika |
» 2015-12-27 19:00:38 Mimo ustawienia typu na atomic < bool > nic się nie zmieniło. Co do rzutowania tego wskaźnika to wyglądało mi to dziwnie ale działa. (testowałem - funkcja jest poprawnie wywoływana) Zamieszczam jeszcze raz kod, z kilkoma drobnymi zmianami. (Włącznie z atomic < bool > ) #include <SFML/System.hpp> #include <iostream> #include <cstring> #include <string> #include <atomic>
using namespace std;
extern "C" { #include "lua5.2/lua.h" #include "lua5.2/lualib.h" #include "lua5.2/lauxlib.h" }
class luaVirtualMachine { private: string output; string input; sf::Thread luaScript; lua_State * state; char * _file; void execute(); bool ready; bool running; atomic < bool > _reguiresData; int api_read( lua_State * L ); int api_write( lua_State * L ); public: luaVirtualMachine(); luaVirtualMachine( const char * file ); ~luaVirtualMachine(); bool open( const char * file ); bool close(); bool launch(); bool isRunning(); bool reguiresData(); void reguiresData( bool opt ); void putstring( string c ); string getstring(); };
void luaVirtualMachine::execute() { luaL_dofile( state, _file ); running = false; }
int luaVirtualMachine::api_read( lua_State * L ) { reguiresData( true ); for(;; ) { if( !reguiresData() ) { lua_pushstring( L, input.c_str() ); break; } cout.flush(); } return 1; }
luaVirtualMachine::luaVirtualMachine() : luaScript( & luaVirtualMachine::execute, this ) { ready = false; running = false; reguiresData( false ); } luaVirtualMachine::luaVirtualMachine( const char * file ) : luaScript( & luaVirtualMachine::execute, this ) { ready = false; open( file ); running = false; reguiresData( false ); } luaVirtualMachine::~luaVirtualMachine() { close(); }
bool luaVirtualMachine::open( const char * file ) { if( ready ) return false; state = luaL_newstate(); luaL_openlibs( state ); lua_register( state, "read",( lua_CFunction ) & luaVirtualMachine::api_read ); _file = new char[ strlen( file ) + 1 ]; strcpy( _file, file ); ready = true; return true; } bool luaVirtualMachine::close() { if( !ready ) return false; lua_close( state ); ready = false; delete _file; return true; } bool luaVirtualMachine::launch() { if( !ready ) return false; running = true; luaScript.launch(); return true; }
bool luaVirtualMachine::isRunning() { return running; } bool luaVirtualMachine::reguiresData() { return _reguiresData; } void luaVirtualMachine::reguiresData( bool opt ) { _reguiresData = opt; }
void luaVirtualMachine::putstring( string s ) { input = s; reguiresData( false ); } string luaVirtualMachine::getstring() { return output; }
int main() { luaVirtualMachine lvm1( "example.lua" ); lvm1.launch(); while( lvm1.isRunning() ) { if( lvm1.reguiresData() ) { string str; cin >> str; lvm1.putstring( str ); } } return 0; }
|
|
Monika90 |
» 2015-12-27 19:05:01 std::cout << this << std::endl;
Dodaj tę linijkę w funkcji api_read oraz w konstruktorze klasy i porównaj wyświetlone adresy. |
|
Gibas11 Temat założony przez niniejszego użytkownika |
» 2015-12-27 19:08:40 Ups, inne. :< Albo lua robi coś co mi się nie podoba tutaj: lua_register( state, "read",( lua_CFunction ) & luaVirtualMachine::api_read ); . albo nie mam chwilowo żadnego pomysłu. EDIT: Wydaje mi się, czy adres z konstruktora ma 64 bity a z funkcji 32? |
|
Monika90 |
» 2015-12-27 19:20:33 EDIT: Wydaje mi się, czy adres z konstruktora ma 64 bity a z funkcji 32? |
Nie. Lua oczekuje wskaźnika do zwykłej funkcji, a nie funkcji składowej. To są różne typy funkcji, niestatyczne funkcje składowe mają ukryty parametr, czyli wskaźnik this. Interpreter tego parametru nie przekazuje. Skąd w ogóle miałby wiedzieć pod jakim adresem znajduje się Twój obiekt? Wywoływanie niestatycznych funkcji składowych z Lua wydaje się być skomplikowane, zobacz np. tutaj https://bitbucket.org/alexames/luawrapper/src |
|
« 1 » 2 |