mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-07-21 14:49:19 +02:00
Merge pull request #91 from jakubg1/lua-refactor
Refactor Lua bindings to make it work natively on Linux
This commit is contained in:
@@ -4,7 +4,6 @@
|
|||||||
#include "utilities/Logs.h"
|
#include "utilities/Logs.h"
|
||||||
#include "world/MemCell.h"
|
#include "world/MemCell.h"
|
||||||
#include "vehicle/Driver.h"
|
#include "vehicle/Driver.h"
|
||||||
#include "scripting/lua_ffi.h"
|
|
||||||
#include "simulation/simulation.h"
|
#include "simulation/simulation.h"
|
||||||
|
|
||||||
lua::lua()
|
lua::lua()
|
||||||
@@ -15,12 +14,33 @@ lua::lua()
|
|||||||
lua_atpanic(state, atpanic);
|
lua_atpanic(state, atpanic);
|
||||||
luaL_openlibs(state);
|
luaL_openlibs(state);
|
||||||
|
|
||||||
lua_getglobal(state, "package");
|
static constexpr luaL_Reg api[] =
|
||||||
lua_pushstring(state, "preload");
|
{
|
||||||
lua_gettable(state, -2);
|
{"event_create", scriptapi_event_create},
|
||||||
lua_pushcclosure(state, openffi, 0);
|
{"event_find", scriptapi_event_find},
|
||||||
lua_setfield(state, -2, "eu07.events");
|
{"event_exists", scriptapi_event_exists},
|
||||||
lua_settop(state, 0);
|
{"event_getname", scriptapi_event_getname},
|
||||||
|
{"event_dispatch", scriptapi_event_dispatch},
|
||||||
|
{"event_dispatch_n", scriptapi_event_dispatch_n},
|
||||||
|
{"track_find", scriptapi_track_find},
|
||||||
|
{"track_isoccupied", scriptapi_track_isoccupied},
|
||||||
|
{"track_isoccupied_n", scriptapi_track_isoccupied_n},
|
||||||
|
{"isolated_find", scriptapi_isolated_find},
|
||||||
|
{"isolated_isoccupied", scriptapi_isolated_isoccupied},
|
||||||
|
{"isolated_isoccupied_n", scriptapi_isolated_isoccupied_n},
|
||||||
|
{"train_getname", scriptapi_train_getname},
|
||||||
|
{"dynobj_putvalues", scriptapi_dynobj_putvalues},
|
||||||
|
{"memcell_find", scriptapi_memcell_find},
|
||||||
|
{"memcell_read", scriptapi_memcell_read},
|
||||||
|
{"memcell_read_n", scriptapi_memcell_read_n},
|
||||||
|
{"memcell_update", scriptapi_memcell_update},
|
||||||
|
{"memcell_update_n", scriptapi_memcell_update_n},
|
||||||
|
{"random", scriptapi_random},
|
||||||
|
{"writelog", scriptapi_writelog},
|
||||||
|
{"writeerrorlog", scriptapi_writeerrorlog},
|
||||||
|
{nullptr, nullptr}
|
||||||
|
};
|
||||||
|
luaL_register(state, "eu07.events", api);
|
||||||
}
|
}
|
||||||
|
|
||||||
lua::~lua()
|
lua::~lua()
|
||||||
@@ -29,184 +49,324 @@ lua::~lua()
|
|||||||
state = nullptr;
|
state = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string lua::get_error()
|
std::string lua::get_error() const
|
||||||
{
|
{
|
||||||
return std::string(lua_tostring(state, -1));
|
return lua_tostring(state, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void lua::interpret(std::string file)
|
void lua::interpret(const std::string& file) const
|
||||||
{
|
{
|
||||||
if (luaL_dofile(state, file.c_str())) {
|
if (luaL_dofile(state, file.c_str())) {
|
||||||
const char *str = lua_tostring(state, -1);
|
std::string str = lua_tostring(state, -1);
|
||||||
ErrorLog(std::string(str), logtype::lua);
|
ErrorLog("lua: Runtime error: " + str, logtype::lua);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOTE: we cannot throw exceptions in callbacks
|
|
||||||
// because it is not supported by LuaJIT on x86 windows
|
|
||||||
|
|
||||||
int lua::atpanic(lua_State *s)
|
int lua::atpanic(lua_State *s)
|
||||||
{
|
{
|
||||||
std::string err(lua_tostring(s, -1));
|
std::string err = lua_tostring(s, -1);
|
||||||
ErrorLog(err, logtype::lua);
|
ErrorLog("lua: Runtime error: " + err, logtype::lua);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int lua::openffi(lua_State *s)
|
/// Dereferences the function handler from the Lua registry.
|
||||||
|
void lua::unref(lua_State *L, const int ref)
|
||||||
{
|
{
|
||||||
if (luaL_dostring(s, lua_ffi))
|
luaL_unref(L, LUA_REGISTRYINDEX, ref);
|
||||||
{
|
|
||||||
ErrorLog(std::string(lua_tostring(s, -1)), logtype::lua);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined _WIN32
|
/// Executes the callback function of an event created with `scriptapi_event_create`.
|
||||||
# if defined __GNUC__
|
void lua::dispatch_event(lua_State *L, const int handler, basic_event *event, const TDynamicObject *activator)
|
||||||
# define EXPORT __attribute__ ((dllexport))
|
|
||||||
# else
|
|
||||||
# define EXPORT __declspec(dllexport)
|
|
||||||
# endif
|
|
||||||
#elif defined __GNUC__
|
|
||||||
# define EXPORT __attribute__ ((visibility ("default")))
|
|
||||||
#else
|
|
||||||
# define EXPORT
|
|
||||||
#endif
|
|
||||||
|
|
||||||
extern "C"
|
|
||||||
{
|
{
|
||||||
EXPORT basic_event* scriptapi_event_create(const char* name, double delay, double randomdelay, lua::eventhandler_t handler)
|
lua_rawgeti(L, LUA_REGISTRYINDEX, handler);
|
||||||
{
|
lua_pushlightuserdata(L, event);
|
||||||
basic_event *event = new lua_event(handler);
|
lua_pushlightuserdata(L, const_cast<TDynamicObject *>(activator));
|
||||||
event->m_name = std::string(name);
|
lua_call(L, 2, 0);
|
||||||
event->m_delay = delay;
|
}
|
||||||
event->m_delayrandom = randomdelay;
|
|
||||||
|
void lua::push_memcell_values(lua_State *L, const TMemCell *mc)
|
||||||
if (simulation::Events.insert(event))
|
{
|
||||||
return event;
|
lua_createtable(L, 0, 3);
|
||||||
else
|
lua_pushstring(L, "str");
|
||||||
return nullptr;
|
lua_pushstring(L, mc ? mc->Text().c_str() : nullptr);
|
||||||
}
|
lua_settable(L, -3);
|
||||||
|
lua_pushstring(L, "num1");
|
||||||
EXPORT basic_event* scriptapi_event_find(const char* name)
|
lua_pushnumber(L, mc ? mc->Value1() : 0.0);
|
||||||
{
|
lua_settable(L, -3);
|
||||||
std::string str(name);
|
lua_pushstring(L, "num2");
|
||||||
basic_event *e = simulation::Events.FindEvent(str);
|
lua_pushnumber(L, mc ? mc->Value2() : 0.0);
|
||||||
if (e)
|
lua_settable(L, -3);
|
||||||
return e;
|
}
|
||||||
else
|
|
||||||
WriteLog("lua: missing event: " + str);
|
memcell_values lua::get_memcell_values(lua_State *L, int idx)
|
||||||
return nullptr;
|
{
|
||||||
}
|
// For negative indices, we need to account for the extra item that is the key name/value extracted from the table.
|
||||||
|
if (idx < 0)
|
||||||
EXPORT TTrack* scriptapi_track_find(const char* name)
|
idx--;
|
||||||
{
|
memcell_values mc{nullptr, 0.0, 0.0};
|
||||||
std::string str(name);
|
lua_pushstring(L, "str");
|
||||||
TTrack *track = simulation::Paths.find(str);
|
lua_gettable(L, idx);
|
||||||
if (track)
|
if (lua_isstring(L, -1))
|
||||||
return track;
|
mc.str = lua_tostring(L, -1);
|
||||||
else
|
lua_pop(L, 1);
|
||||||
WriteLog("lua: missing track: " + str);
|
lua_pushstring(L, "num1");
|
||||||
return nullptr;
|
lua_gettable(L, idx);
|
||||||
}
|
if (lua_isnumber(L, -1))
|
||||||
|
mc.num1 = lua_tonumber(L, -1);
|
||||||
EXPORT bool scriptapi_track_isoccupied(TTrack* track)
|
lua_pop(L, 1);
|
||||||
{
|
lua_pushstring(L, "num2");
|
||||||
if (track)
|
lua_gettable(L, idx);
|
||||||
return !track->IsEmpty();
|
if (lua_isnumber(L, -1))
|
||||||
return false;
|
mc.num2 = lua_tonumber(L, -1);
|
||||||
}
|
lua_pop(L, 1);
|
||||||
|
return mc;
|
||||||
EXPORT TIsolated* scriptapi_isolated_find(const char* name)
|
}
|
||||||
{
|
|
||||||
std::string str(name);
|
int lua::scriptapi_event_create(lua_State *L)
|
||||||
TIsolated *isolated = TIsolated::Find(name);
|
{
|
||||||
if (isolated)
|
std::string name = lua_tostring(L, 1);
|
||||||
return isolated;
|
double delay = lua_tonumber(L, 2);
|
||||||
else
|
double randomdelay = lua_tonumber(L, 3);
|
||||||
WriteLog("lua: missing isolated: " + str);
|
lua_pushvalue(L, 4);
|
||||||
return nullptr;
|
int funcRef = luaL_ref(L, LUA_REGISTRYINDEX);
|
||||||
}
|
|
||||||
|
basic_event *event = new lua_event(L, funcRef);
|
||||||
EXPORT bool scriptapi_isolated_isoccupied(TIsolated* isolated)
|
event->m_name = name;
|
||||||
{
|
event->m_delay = delay;
|
||||||
if (isolated)
|
event->m_delayrandom = randomdelay;
|
||||||
return isolated->Busy();
|
if (simulation::Events.insert(event))
|
||||||
return false;
|
{
|
||||||
}
|
lua_pushlightuserdata(L, event);
|
||||||
|
return 1;
|
||||||
EXPORT const char* scriptapi_event_getname(basic_event *e)
|
}
|
||||||
{
|
return 0;
|
||||||
if (e)
|
}
|
||||||
return e->m_name.c_str();
|
|
||||||
return nullptr;
|
int lua::scriptapi_event_find(lua_State *L)
|
||||||
}
|
{
|
||||||
|
std::string name = lua_tostring(L, 1);
|
||||||
EXPORT const char* scriptapi_train_getname(TDynamicObject *dyn)
|
basic_event *event = simulation::Events.FindEvent(name);
|
||||||
{
|
if (event)
|
||||||
if (dyn && dyn->Mechanik)
|
{
|
||||||
return dyn->Mechanik->TrainName().c_str();
|
lua_pushlightuserdata(L, event);
|
||||||
return nullptr;
|
return 1;
|
||||||
}
|
}
|
||||||
|
ErrorLog("lua: missing event: " + name);
|
||||||
EXPORT void scriptapi_event_dispatch(basic_event *e, TDynamicObject *activator, double delay)
|
return 0;
|
||||||
{
|
}
|
||||||
if (e)
|
|
||||||
simulation::Events.AddToQuery(e, activator, delay);
|
int lua::scriptapi_event_exists(lua_State *L)
|
||||||
}
|
{
|
||||||
|
std::string name = lua_tostring(L, 1);
|
||||||
EXPORT double scriptapi_random(double a, double b)
|
basic_event *event = simulation::Events.FindEvent(name);
|
||||||
{
|
lua_pushboolean(L, event != nullptr);
|
||||||
return Random(a, b);
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
EXPORT void scriptapi_writelog(const char* txt)
|
int lua::scriptapi_event_getname(lua_State *L)
|
||||||
{
|
{
|
||||||
WriteLog("lua: log: " + std::string(txt), logtype::lua);
|
auto *event = static_cast<basic_event *>(lua_touserdata(L, 1));
|
||||||
}
|
if (event)
|
||||||
|
{
|
||||||
EXPORT void scriptapi_writeerrorlog(const char* txt)
|
lua_pushstring(L, event->m_name.c_str());
|
||||||
{
|
return 1;
|
||||||
ErrorLog("lua: log: " + std::string(txt), logtype::lua);
|
}
|
||||||
}
|
return 0;
|
||||||
|
}
|
||||||
struct memcell_values { const char *str; double num1; double num2; };
|
|
||||||
|
int lua::scriptapi_event_dispatch(lua_State *L)
|
||||||
EXPORT TMemCell* scriptapi_memcell_find(const char *name)
|
{
|
||||||
{
|
auto *event = static_cast<basic_event *>(lua_touserdata(L, 1));
|
||||||
std::string str(name);
|
auto *activator = static_cast<TDynamicObject *>(lua_touserdata(L, 2));
|
||||||
TMemCell *mc = simulation::Memory.find(str);
|
double delay = lua_tonumber(L, 3);
|
||||||
if (mc)
|
if (event)
|
||||||
return mc;
|
simulation::Events.AddToQuery(event, activator, delay);
|
||||||
else
|
return 0;
|
||||||
WriteLog("lua: missing memcell: " + str);
|
}
|
||||||
return nullptr;
|
|
||||||
}
|
int lua::scriptapi_event_dispatch_n(lua_State *L)
|
||||||
|
{
|
||||||
EXPORT memcell_values scriptapi_memcell_read(TMemCell *mc)
|
std::string name = lua_tostring(L, 1);
|
||||||
{
|
auto *activator = static_cast<TDynamicObject *>(lua_touserdata(L, 2));
|
||||||
if (!mc)
|
double delay = lua_tonumber(L, 3);
|
||||||
return { nullptr, 0.0, 0.0 };
|
basic_event *event = simulation::Events.FindEvent(name);
|
||||||
return { mc->Text().c_str(), mc->Value1(), mc->Value2() };
|
if (event)
|
||||||
}
|
simulation::Events.AddToQuery(event, activator, delay);
|
||||||
|
else
|
||||||
EXPORT void scriptapi_memcell_update(TMemCell *mc, const char *str, double num1, double num2)
|
ErrorLog("lua: missing event: " + name);
|
||||||
{
|
return 0;
|
||||||
if (!mc)
|
}
|
||||||
return;
|
|
||||||
mc->UpdateValues(std::string(str), num1, num2,
|
int lua::scriptapi_track_find(lua_State *L)
|
||||||
basic_event::flags::text | basic_event::flags::value1 | basic_event::flags::value2);
|
{
|
||||||
}
|
std::string name = lua_tostring(L, 1);
|
||||||
|
TTrack *track = simulation::Paths.find(name);
|
||||||
EXPORT void scriptapi_dynobj_putvalues(TDynamicObject *dyn, const char *str, double num1, double num2)
|
if (track)
|
||||||
{
|
{
|
||||||
if (!dyn)
|
lua_pushlightuserdata(L, track);
|
||||||
return;
|
return 1;
|
||||||
TLocation loc;
|
}
|
||||||
if (dyn->Mechanik)
|
ErrorLog("lua: missing track: " + name);
|
||||||
dyn->Mechanik->PutCommand(std::string(str), num1, num2, loc);
|
return 0;
|
||||||
else
|
}
|
||||||
dyn->MoverParameters->PutCommand(std::string(str), num1, num2, loc);
|
|
||||||
}
|
int lua::scriptapi_track_isoccupied(lua_State *L)
|
||||||
|
{
|
||||||
|
auto *track = static_cast<TTrack *>(lua_touserdata(L, 1));
|
||||||
|
if (track)
|
||||||
|
{
|
||||||
|
lua_pushboolean(L, !track->IsEmpty());
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int lua::scriptapi_track_isoccupied_n(lua_State *L)
|
||||||
|
{
|
||||||
|
std::string name = lua_tostring(L, 1);
|
||||||
|
TTrack *track = simulation::Paths.find(name);
|
||||||
|
if (track)
|
||||||
|
{
|
||||||
|
lua_pushboolean(L, !track->IsEmpty());
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
ErrorLog("lua: missing track: " + name);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int lua::scriptapi_isolated_find(lua_State *L)
|
||||||
|
{
|
||||||
|
std::string name = lua_tostring(L, 1);
|
||||||
|
TIsolated *isolated = TIsolated::Find(name);
|
||||||
|
if (isolated)
|
||||||
|
{
|
||||||
|
lua_pushlightuserdata(L, isolated);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
ErrorLog("lua: missing isolated: " + name);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int lua::scriptapi_isolated_isoccupied(lua_State *L)
|
||||||
|
{
|
||||||
|
auto *isolated = static_cast<TIsolated *>(lua_touserdata(L, 1));
|
||||||
|
if (isolated)
|
||||||
|
{
|
||||||
|
lua_pushboolean(L, isolated->Busy());
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int lua::scriptapi_isolated_isoccupied_n(lua_State *L)
|
||||||
|
{
|
||||||
|
std::string name = lua_tostring(L, 1);
|
||||||
|
TIsolated *isolated = TIsolated::Find(name);
|
||||||
|
if (isolated)
|
||||||
|
{
|
||||||
|
lua_pushboolean(L, isolated->Busy());
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
ErrorLog("lua: missing isolated: " + name);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int lua::scriptapi_train_getname(lua_State *L)
|
||||||
|
{
|
||||||
|
auto *dyn = static_cast<TDynamicObject *>(lua_touserdata(L, 1));
|
||||||
|
if (dyn && dyn->Mechanik)
|
||||||
|
{
|
||||||
|
lua_pushstring(L, dyn->Mechanik->TrainName().c_str());
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int lua::scriptapi_dynobj_putvalues(lua_State *L)
|
||||||
|
{
|
||||||
|
auto *dyn = static_cast<TDynamicObject *>(lua_touserdata(L, 1));
|
||||||
|
auto [str, num1, num2] = get_memcell_values(L, 2);
|
||||||
|
if (!dyn)
|
||||||
|
return 0;
|
||||||
|
TLocation loc{};
|
||||||
|
if (dyn->Mechanik)
|
||||||
|
dyn->Mechanik->PutCommand(str, num1, num2, loc);
|
||||||
|
else
|
||||||
|
dyn->MoverParameters->PutCommand(str, num1, num2, loc);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int lua::scriptapi_memcell_find(lua_State *L)
|
||||||
|
{
|
||||||
|
std::string str = lua_tostring(L, 1);
|
||||||
|
TMemCell *mc = simulation::Memory.find(str);
|
||||||
|
if (mc)
|
||||||
|
{
|
||||||
|
lua_pushlightuserdata(L, mc);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
ErrorLog("lua: missing memcell: " + str);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int lua::scriptapi_memcell_read(lua_State *L)
|
||||||
|
{
|
||||||
|
auto *mc = static_cast<TMemCell *>(lua_touserdata(L, 1));
|
||||||
|
push_memcell_values(L, mc);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int lua::scriptapi_memcell_read_n(lua_State *L)
|
||||||
|
{
|
||||||
|
std::string str = lua_tostring(L, 1);
|
||||||
|
TMemCell *mc = simulation::Memory.find(str);
|
||||||
|
push_memcell_values(L, mc);
|
||||||
|
if (!mc)
|
||||||
|
ErrorLog("lua: missing memcell: " + str);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int lua::scriptapi_memcell_update(lua_State *L)
|
||||||
|
{
|
||||||
|
auto *mc = static_cast<TMemCell *>(lua_touserdata(L, 1));
|
||||||
|
auto [str, num1, num2] = get_memcell_values(L, 2);
|
||||||
|
if (mc)
|
||||||
|
mc->UpdateValues(str, num1, num2,
|
||||||
|
basic_event::flags::text | basic_event::flags::value1 | basic_event::flags::value2);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int lua::scriptapi_memcell_update_n(lua_State *L)
|
||||||
|
{
|
||||||
|
std::string mstr = lua_tostring(L, 1);
|
||||||
|
auto [str, num1, num2] = get_memcell_values(L, 2);
|
||||||
|
TMemCell *mc = simulation::Memory.find(mstr);
|
||||||
|
if (mc)
|
||||||
|
mc->UpdateValues(str, num1, num2,
|
||||||
|
basic_event::flags::text | basic_event::flags::value1 | basic_event::flags::value2);
|
||||||
|
else
|
||||||
|
ErrorLog("lua: missing memcell: " + mstr);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int lua::scriptapi_random(lua_State *L)
|
||||||
|
{
|
||||||
|
double a = lua_tonumber(L, 1);
|
||||||
|
double b = lua_tonumber(L, 2);
|
||||||
|
lua_pushnumber(L, Random(a, b));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int lua::scriptapi_writelog(lua_State *L)
|
||||||
|
{
|
||||||
|
std::string txt = lua_tostring(L, 1);
|
||||||
|
WriteLog("lua: log: " + txt, logtype::lua);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int lua::scriptapi_writeerrorlog(lua_State *L)
|
||||||
|
{
|
||||||
|
std::string txt = lua_tostring(L, 1);
|
||||||
|
ErrorLog("lua: log: " + txt, logtype::lua);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,22 +1,49 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include <lua.hpp>
|
#include <lua.hpp>
|
||||||
|
#include <stdafx.h>
|
||||||
|
|
||||||
class basic_event;
|
class basic_event;
|
||||||
|
class TMemCell;
|
||||||
class TDynamicObject;
|
class TDynamicObject;
|
||||||
|
struct memcell_values { const char *str; double num1; double num2; };
|
||||||
|
|
||||||
class lua
|
class lua
|
||||||
{
|
{
|
||||||
lua_State *state;
|
lua_State *state;
|
||||||
|
|
||||||
static int atpanic(lua_State *s);
|
static int atpanic(lua_State *s);
|
||||||
static int openffi(lua_State *s);
|
|
||||||
|
static int scriptapi_event_create(lua_State *L);
|
||||||
|
static int scriptapi_event_find(lua_State *L);
|
||||||
|
static int scriptapi_event_exists(lua_State *L);
|
||||||
|
static int scriptapi_event_getname(lua_State *L);
|
||||||
|
static int scriptapi_event_dispatch(lua_State *L);
|
||||||
|
static int scriptapi_event_dispatch_n(lua_State *L);
|
||||||
|
static int scriptapi_track_find(lua_State *L);
|
||||||
|
static int scriptapi_track_isoccupied(lua_State *L);
|
||||||
|
static int scriptapi_track_isoccupied_n(lua_State *L);
|
||||||
|
static int scriptapi_isolated_find(lua_State *L);
|
||||||
|
static int scriptapi_isolated_isoccupied(lua_State *L);
|
||||||
|
static int scriptapi_isolated_isoccupied_n(lua_State *L);
|
||||||
|
static int scriptapi_train_getname(lua_State *L);
|
||||||
|
static int scriptapi_dynobj_putvalues(lua_State *L);
|
||||||
|
static int scriptapi_memcell_find(lua_State *L);
|
||||||
|
static int scriptapi_memcell_read(lua_State *L);
|
||||||
|
static int scriptapi_memcell_read_n(lua_State *L);
|
||||||
|
static int scriptapi_memcell_update(lua_State *L);
|
||||||
|
static int scriptapi_memcell_update_n(lua_State *L);
|
||||||
|
static int scriptapi_random(lua_State *L);
|
||||||
|
static int scriptapi_writelog(lua_State *L);
|
||||||
|
static int scriptapi_writeerrorlog(lua_State *L);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
lua();
|
lua();
|
||||||
~lua();
|
~lua();
|
||||||
|
|
||||||
std::string get_error();
|
std::string get_error() const;
|
||||||
void interpret(std::string file);
|
void interpret(const std::string& file) const;
|
||||||
|
static void unref(lua_State *L, int ref);
|
||||||
typedef void (*eventhandler_t)(basic_event*, const TDynamicObject*);
|
static void dispatch_event(lua_State *L, int handler, basic_event *event, const TDynamicObject *activator);
|
||||||
|
static void push_memcell_values(lua_State *L, const TMemCell *mc);
|
||||||
|
static memcell_values get_memcell_values(lua_State *L, int idx);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,96 +0,0 @@
|
|||||||
const char lua_ffi[] = R"STRING(
|
|
||||||
local ffi = require("ffi")
|
|
||||||
ffi.cdef[[
|
|
||||||
struct memcell_values { const char *str; double num1; double num2; };
|
|
||||||
|
|
||||||
typedef struct TEvent TEvent;
|
|
||||||
typedef struct TTrack TTrack;
|
|
||||||
typedef struct TIsolated TIsolated;
|
|
||||||
typedef struct TDynamicObject TDynamicObject;
|
|
||||||
typedef struct TMemCell TMemCell;
|
|
||||||
typedef struct memcell_values memcell_values;
|
|
||||||
|
|
||||||
TEvent* scriptapi_event_create(const char* name, double delay, double randomdelay, void (*handler)(TEvent*, TDynamicObject*));
|
|
||||||
TEvent* scriptapi_event_find(const char* name);
|
|
||||||
const char* scriptapi_event_getname(TEvent *e);
|
|
||||||
void scriptapi_event_dispatch(TEvent *e, TDynamicObject *activator, double delay);
|
|
||||||
|
|
||||||
TTrack* scriptapi_track_find(const char* name);
|
|
||||||
bool scriptapi_track_isoccupied(TTrack *track);
|
|
||||||
|
|
||||||
TIsolated* scriptapi_isolated_find(const char* name);
|
|
||||||
bool scriptapi_isolated_isoccupied(TIsolated *isolated);
|
|
||||||
|
|
||||||
const char* scriptapi_train_getname(TDynamicObject *dyn);
|
|
||||||
void scriptapi_dynobj_putvalues(TDynamicObject *dyn, const char *str, double num1, double num2);
|
|
||||||
|
|
||||||
TMemCell* scriptapi_memcell_find(const char *name);
|
|
||||||
memcell_values scriptapi_memcell_read(TMemCell *mc);
|
|
||||||
void scriptapi_memcell_update(TMemCell *mc, const char *str, double num1, double num2);
|
|
||||||
|
|
||||||
double scriptapi_random(double a, double b);
|
|
||||||
void scriptapi_writelog(const char* txt);
|
|
||||||
void scriptapi_writeerrorlog(const char* txt);
|
|
||||||
]]
|
|
||||||
|
|
||||||
local ns = ffi.C
|
|
||||||
|
|
||||||
local module = {}
|
|
||||||
|
|
||||||
module.event_create = ns.scriptapi_event_create
|
|
||||||
function module.event_preparefunc(f)
|
|
||||||
return ffi.cast("void (*)(TEvent*, TDynamicObject*)", f)
|
|
||||||
end
|
|
||||||
module.event_find = ns.scriptapi_event_find
|
|
||||||
function module.event_getname(a)
|
|
||||||
return ffi.string(ns.scriptapi_event_getname(a))
|
|
||||||
end
|
|
||||||
module.event_dispatch = ns.scriptapi_event_dispatch
|
|
||||||
function module.event_dispatch_n(a, b, c)
|
|
||||||
ns.scriptapi_event_dispatch(ns.scriptapi_event_find(a), b, c)
|
|
||||||
end
|
|
||||||
|
|
||||||
module.track_find = ns.scriptapi_track_find
|
|
||||||
module.track_isoccupied = ns.scriptapi_track_isoccupied
|
|
||||||
function module.track_isoccupied_n(a)
|
|
||||||
return ns.scriptapi_track_isoccupied(ns.scriptapi_track_find(a))
|
|
||||||
end
|
|
||||||
|
|
||||||
module.isolated_find = ns.scriptapi_isolated_find
|
|
||||||
module.isolated_isoccupied = ns.scriptapi_isolated_isoccupied
|
|
||||||
function module.isolated_isoccupied_n(a)
|
|
||||||
return ns.scriptapi_isolated_isoccupied(ns.scriptapi_isolated_find(a))
|
|
||||||
end
|
|
||||||
|
|
||||||
function module.train_getname(a)
|
|
||||||
return ffi.string(ns.scriptapi_train_getname(a))
|
|
||||||
end
|
|
||||||
function module.dynobj_putvalues(a, b)
|
|
||||||
ns.scriptapi_dynobj_putvalues(a, b.str, b.num1, b.num2)
|
|
||||||
end
|
|
||||||
|
|
||||||
module.memcell_find = ns.scriptapi_memcell_find
|
|
||||||
function module.memcell_read(a)
|
|
||||||
native = ns.scriptapi_memcell_read(a)
|
|
||||||
mc = { }
|
|
||||||
mc.str = ffi.string(native.str)
|
|
||||||
mc.num1 = native.num1
|
|
||||||
mc.num2 = native.num2
|
|
||||||
return mc
|
|
||||||
end
|
|
||||||
function module.memcell_read_n(a)
|
|
||||||
return module.memcell_read(ns.scriptapi_memcell_find(a))
|
|
||||||
end
|
|
||||||
function module.memcell_update(a, b)
|
|
||||||
ns.scriptapi_memcell_update(a, b.str, b.num1, b.num2)
|
|
||||||
end
|
|
||||||
function module.memcell_update_n(a, b)
|
|
||||||
ns.scriptapi_memcell_update(ns.scriptapi_memcell_find(a), b.str, b.num1, b.num2)
|
|
||||||
end
|
|
||||||
|
|
||||||
module.random = ns.scriptapi_random
|
|
||||||
module.writelog = ns.scriptapi_writelog
|
|
||||||
module.writeerrorlog = ns.scriptapi_writeerrorlog
|
|
||||||
|
|
||||||
return module;
|
|
||||||
)STRING";
|
|
||||||
@@ -2110,44 +2110,44 @@ friction_event::export_as_text_( std::ostream &Output ) const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef WITH_LUA
|
#ifdef WITH_LUA
|
||||||
lua_event::lua_event(lua::eventhandler_t func) {
|
lua_event::lua_event(lua_State *L, const int ref) {
|
||||||
lua_func = func;
|
lua_state = L;
|
||||||
|
lua_func = ref;
|
||||||
|
}
|
||||||
|
|
||||||
|
lua_event::~lua_event() {
|
||||||
|
lua::unref(lua_state, lua_func);
|
||||||
}
|
}
|
||||||
|
|
||||||
// prepares event for use
|
// prepares event for use
|
||||||
void
|
void lua_event::init() {
|
||||||
lua_event::init() {
|
// nothing to do here
|
||||||
// nothing to do here
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// event type string
|
// event type string
|
||||||
std::string
|
std::string lua_event::type() const {
|
||||||
lua_event::type() const {
|
return "lua";
|
||||||
return "lua";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// deserialize() subclass details
|
// deserialize() subclass details
|
||||||
void
|
void lua_event::deserialize_( cParser &Input, scene::scratch_data &Scratchpad ) {
|
||||||
lua_event::deserialize_( cParser &Input, scene::scratch_data &Scratchpad ) {
|
// preload next token
|
||||||
// preload next token
|
Input.getTokens();
|
||||||
Input.getTokens();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// run() subclass details
|
// run() subclass details
|
||||||
void
|
void lua_event::run_() {
|
||||||
lua_event::run_() {
|
|
||||||
try {
|
try {
|
||||||
if (lua_func)
|
if (lua_func != LUA_NOREF)
|
||||||
lua_func(this, m_activator);
|
lua::dispatch_event(lua_state, lua_func, this, m_activator);
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
ErrorLog(simulation::Lua.get_error());
|
ErrorLog("lua: Runtime error: " + simulation::Lua.get_error());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// export_as_text() subclass details
|
// export_as_text() subclass details
|
||||||
void
|
void lua_event::export_as_text_( std::ostream &Output ) const {
|
||||||
lua_event::export_as_text_( std::ostream &Output ) const {
|
// nothing to do here
|
||||||
// nothing to do here
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool lua_event::is_instant() const {
|
bool lua_event::is_instant() const {
|
||||||
|
|||||||
@@ -591,17 +591,19 @@ private:
|
|||||||
#ifdef WITH_LUA
|
#ifdef WITH_LUA
|
||||||
class lua_event : public basic_event {
|
class lua_event : public basic_event {
|
||||||
public:
|
public:
|
||||||
lua_event(lua::eventhandler_t func);
|
lua_event(lua_State *L, int ref);
|
||||||
void init() override;
|
~lua_event() override;
|
||||||
|
void init() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::string type() const override;
|
std::string type() const override;
|
||||||
void deserialize_( cParser &Input, scene::scratch_data &Scratchpad ) override;
|
void deserialize_( cParser &Input, scene::scratch_data &Scratchpad ) override;
|
||||||
void run_() override;
|
void run_() override;
|
||||||
void export_as_text_( std::ostream &Output ) const override;
|
void export_as_text_( std::ostream &Output ) const override;
|
||||||
bool is_instant() const override;
|
bool is_instant() const override;
|
||||||
|
|
||||||
lua::eventhandler_t lua_func = nullptr;
|
lua_State *lua_state = nullptr;
|
||||||
|
int lua_func = LUA_NOREF;
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user