lua: added extended type() function and replaced in_instance() by get_class()
Dieser Commit ist enthalten in:
Ursprung
efc2c2a602
Commit
f7f289e1d6
39
server/src/lua/checkarguments.hpp
Normale Datei
39
server/src/lua/checkarguments.hpp
Normale Datei
@ -0,0 +1,39 @@
|
|||||||
|
/**
|
||||||
|
* server/src/lua/checkarguments.hpp
|
||||||
|
*
|
||||||
|
* This file is part of the traintastic source code.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2021 Reinder Feenstra
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program 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 General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef TRAINTASTIC_SERVER_LUA_CHECKARGUMENTS_HPP
|
||||||
|
#define TRAINTASTIC_SERVER_LUA_CHECKARGUMENTS_HPP
|
||||||
|
|
||||||
|
#include "error.hpp"
|
||||||
|
|
||||||
|
namespace Lua {
|
||||||
|
|
||||||
|
inline void checkArguments(lua_State* L, int count)
|
||||||
|
{
|
||||||
|
const int top = lua_gettop(L);
|
||||||
|
if(top != count)
|
||||||
|
errorExpectedNArgumentsGotN(L, count, top);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
@ -23,6 +23,7 @@
|
|||||||
#include "class.hpp"
|
#include "class.hpp"
|
||||||
#include "push.hpp"
|
#include "push.hpp"
|
||||||
#include "object.hpp"
|
#include "object.hpp"
|
||||||
|
#include "checkarguments.hpp"
|
||||||
|
|
||||||
#include "../board/board.hpp"
|
#include "../board/board.hpp"
|
||||||
#include "../board/boardlist.hpp"
|
#include "../board/boardlist.hpp"
|
||||||
@ -126,96 +127,148 @@ static bool isInstance(const ::ObjectPtr& object)
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
inline static void setField(lua_State* L, std::string_view key)
|
inline static void registerValue(lua_State* L, std::string_view key)
|
||||||
{
|
{
|
||||||
static_assert(std::is_base_of_v<::Object, T>);
|
static_assert(std::is_base_of_v<::Object, T>);
|
||||||
push(L, key);
|
|
||||||
|
// add to global class (used by Class::push)
|
||||||
|
lua_getglobal(L, metaTableName);
|
||||||
*reinterpret_cast<IsInstance*>(lua_newuserdata(L, sizeof(IsInstance))) = isInstance<T>;
|
*reinterpret_cast<IsInstance*>(lua_newuserdata(L, sizeof(IsInstance))) = isInstance<T>;
|
||||||
luaL_newmetatable(L, metaTableName);
|
if(luaL_newmetatable(L, metaTableName))
|
||||||
|
{
|
||||||
|
lua_pushcfunction(L, Class::__tostring);
|
||||||
|
lua_setfield(L, -2, "__tostring");
|
||||||
|
}
|
||||||
lua_setmetatable(L, -2);
|
lua_setmetatable(L, -2);
|
||||||
|
lua_rawsetp(L, -2, T::classId.data());
|
||||||
|
lua_pop(L, 1);
|
||||||
|
|
||||||
|
// add to sandbox class global:
|
||||||
|
Lua::push(L, key);
|
||||||
|
Class::push<T>(L);
|
||||||
lua_settable(L, -3);
|
lua_settable(L, -3);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Class::registerValues(lua_State* L)
|
void Class::registerValues(lua_State* L)
|
||||||
{
|
{
|
||||||
assert(lua_istable(L, -1));
|
assert(lua_istable(L, -1)); // sandboxes global class
|
||||||
|
|
||||||
setField<Board>(L, "BOARD");
|
lua_newtable(L); // global
|
||||||
setField<BoardList>(L, "BOARD_LIST");
|
lua_setglobal(L, metaTableName);
|
||||||
|
|
||||||
setField<StraightRailTile>(L, "STRAIGHT_RAIL_TILE");
|
registerValue<Board>(L, "BOARD");
|
||||||
setField<TunnelRailTile>(L, "TUNNEL_RAIL_TILE");
|
registerValue<BoardList>(L, "BOARD_LIST");
|
||||||
setField<BufferStopRailTile>(L, "BUFFER_STOP_RAIL_TILE");
|
|
||||||
setField<Curve45RailTile>(L, "CURVE_45_RAIL_TILE");
|
|
||||||
setField<Curve90RailTile>(L, "CURVE_90_RAIL_TILE");
|
|
||||||
setField<Cross45RailTile>(L, "CROSS_45_RAIL_TILE");
|
|
||||||
setField<Cross90RailTile>(L, "CROSS_90_RAIL_TILE");
|
|
||||||
setField<Bridge45RightRailTile>(L, "BRIDGE_45_RIGHT_RAIL_TILE");
|
|
||||||
setField<Bridge45LeftRailTile>(L, "BRIDGE_45_LEFT_RAIL_TILE");
|
|
||||||
setField<Bridge90RailTile>(L, "BRIDGE_90_RAIL_TILE");
|
|
||||||
setField<TurnoutSingleSlipRailTile>(L, "TURNOUT_SINGLE_SLIP_RAIL_TILE");
|
|
||||||
setField<TurnoutLeft90RailTile>(L, "TURNOUT_LEFT_90_RAIL_TILE");
|
|
||||||
setField<TurnoutRight45RailTile>(L, "TURNOUT_RIGHT_45_RAIL_TILE");
|
|
||||||
setField<TurnoutLeft45RailTile>(L, "TURNOUT_LEFT_45_RAIL_TILE");
|
|
||||||
setField<TurnoutRight90RailTile>(L, "TURNOUT_RIGHT_90_RAIL_TILE");
|
|
||||||
setField<TurnoutDoubleSlipRailTile>(L, "TURNOUT_DOUBLE_SLIP_RAIL_TILE");
|
|
||||||
setField<TurnoutWyeRailTile>(L, "TURNOUT_WYE_RAIL_TILE");
|
|
||||||
setField<TurnoutLeftCurvedRailTile>(L, "TURNOUT__RAIL_TILE");
|
|
||||||
setField<Turnout3WayRailTile>(L, "TURNOUT_3WAY_RAIL_TILE");
|
|
||||||
setField<TurnoutRightCurvedRailTile>(L, "TURNOUT_RIGHT_CURVED_RAIL_TILE");
|
|
||||||
setField<Signal2AspectRailTile>(L, "SIGNAL_2_ASPECT_RAIL_TILE");
|
|
||||||
setField<Signal3AspectRailTile>(L, "SIGNAL_3_ASPECT_RAIL_TILE");
|
|
||||||
setField<SensorRailTile>(L, "SENSOR_RAIL_TILE");
|
|
||||||
setField<BlockRailTile>(L, "BLOCK_RAIL_TILE");
|
|
||||||
|
|
||||||
setField<Clock>(L, "CLOCK");
|
registerValue<StraightRailTile>(L, "STRAIGHT_RAIL_TILE");
|
||||||
|
registerValue<TunnelRailTile>(L, "TUNNEL_RAIL_TILE");
|
||||||
|
registerValue<BufferStopRailTile>(L, "BUFFER_STOP_RAIL_TILE");
|
||||||
|
registerValue<Curve45RailTile>(L, "CURVE_45_RAIL_TILE");
|
||||||
|
registerValue<Curve90RailTile>(L, "CURVE_90_RAIL_TILE");
|
||||||
|
registerValue<Cross45RailTile>(L, "CROSS_45_RAIL_TILE");
|
||||||
|
registerValue<Cross90RailTile>(L, "CROSS_90_RAIL_TILE");
|
||||||
|
registerValue<Bridge45RightRailTile>(L, "BRIDGE_45_RIGHT_RAIL_TILE");
|
||||||
|
registerValue<Bridge45LeftRailTile>(L, "BRIDGE_45_LEFT_RAIL_TILE");
|
||||||
|
registerValue<Bridge90RailTile>(L, "BRIDGE_90_RAIL_TILE");
|
||||||
|
registerValue<TurnoutSingleSlipRailTile>(L, "TURNOUT_SINGLE_SLIP_RAIL_TILE");
|
||||||
|
registerValue<TurnoutLeft90RailTile>(L, "TURNOUT_LEFT_90_RAIL_TILE");
|
||||||
|
registerValue<TurnoutRight45RailTile>(L, "TURNOUT_RIGHT_45_RAIL_TILE");
|
||||||
|
registerValue<TurnoutLeft45RailTile>(L, "TURNOUT_LEFT_45_RAIL_TILE");
|
||||||
|
registerValue<TurnoutRight90RailTile>(L, "TURNOUT_RIGHT_90_RAIL_TILE");
|
||||||
|
registerValue<TurnoutDoubleSlipRailTile>(L, "TURNOUT_DOUBLE_SLIP_RAIL_TILE");
|
||||||
|
registerValue<TurnoutWyeRailTile>(L, "TURNOUT_WYE_RAIL_TILE");
|
||||||
|
registerValue<TurnoutLeftCurvedRailTile>(L, "TURNOUT__RAIL_TILE");
|
||||||
|
registerValue<Turnout3WayRailTile>(L, "TURNOUT_3WAY_RAIL_TILE");
|
||||||
|
registerValue<TurnoutRightCurvedRailTile>(L, "TURNOUT_RIGHT_CURVED_RAIL_TILE");
|
||||||
|
registerValue<Signal2AspectRailTile>(L, "SIGNAL_2_ASPECT_RAIL_TILE");
|
||||||
|
registerValue<Signal3AspectRailTile>(L, "SIGNAL_3_ASPECT_RAIL_TILE");
|
||||||
|
registerValue<SensorRailTile>(L, "SENSOR_RAIL_TILE");
|
||||||
|
registerValue<BlockRailTile>(L, "BLOCK_RAIL_TILE");
|
||||||
|
|
||||||
setField<WLANmaus>(L, "WLANMAUS_CONTROLLER");
|
registerValue<Clock>(L, "CLOCK");
|
||||||
setField<ControllerList>(L, "CONTROLLER_LIST");
|
|
||||||
|
registerValue<WLANmaus>(L, "WLANMAUS_CONTROLLER");
|
||||||
|
registerValue<ControllerList>(L, "CONTROLLER_LIST");
|
||||||
#ifdef USB_XPRESSNET
|
#ifdef USB_XPRESSNET
|
||||||
setField<USBXpressNetController>(L, "USB_XPRESSNET_CONTROLLER");
|
registerValue<USBXpressNetController>(L, "USB_XPRESSNET_CONTROLLER");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
setField<RocoZ21>(L, "Z21_COMMAND_STATION");
|
registerValue<RocoZ21>(L, "Z21_COMMAND_STATION");
|
||||||
setField<VirtualCommandStation>(L, "VIRTUAL_COMMAND_STATION");
|
registerValue<VirtualCommandStation>(L, "VIRTUAL_COMMAND_STATION");
|
||||||
setField<LocoNetTCPBinary>(L, "LOCONET_TCP_BINARY_COMMAND_STATION");
|
registerValue<LocoNetTCPBinary>(L, "LOCONET_TCP_BINARY_COMMAND_STATION");
|
||||||
#ifdef USB_XPRESSNET
|
#ifdef USB_XPRESSNET
|
||||||
setField<USBXpressNetInterface>(L, "USB_XPRESSNET_INTERFACE");
|
registerValue<USBXpressNetInterface>(L, "USB_XPRESSNET_INTERFACE");
|
||||||
#endif
|
#endif
|
||||||
setField<XpressNetSerial>(L, "XPRESSNET_SERIAL_COMMAND_STATION");
|
registerValue<XpressNetSerial>(L, "XPRESSNET_SERIAL_COMMAND_STATION");
|
||||||
setField<DCCPlusPlusSerial>(L, "DCCPLUSPLUS_SERIAL_COMMAND_STATION");
|
registerValue<DCCPlusPlusSerial>(L, "DCCPLUSPLUS_SERIAL_COMMAND_STATION");
|
||||||
setField<CommandStationList>(L, "COMMAND_STATION_LIST");
|
registerValue<CommandStationList>(L, "COMMAND_STATION_LIST");
|
||||||
setField<LocoNetSerial>(L, "LOCONET_SERIAL_COMMAND_STATION");
|
registerValue<LocoNetSerial>(L, "LOCONET_SERIAL_COMMAND_STATION");
|
||||||
|
|
||||||
setField<DecoderFunction>(L, "DECODER_FUNCTION");
|
registerValue<DecoderFunction>(L, "DECODER_FUNCTION");
|
||||||
setField<DecoderList>(L, "DECODER_LIST");
|
registerValue<DecoderList>(L, "DECODER_LIST");
|
||||||
setField<Decoder>(L, "DECODER");
|
registerValue<Decoder>(L, "DECODER");
|
||||||
setField<DecoderFunctions>(L, "DECODER_FUNCTIONS");
|
registerValue<DecoderFunctions>(L, "DECODER_FUNCTIONS");
|
||||||
|
|
||||||
setField<LocoNetInput>(L, "LOCONET_INPUT");
|
registerValue<LocoNetInput>(L, "LOCONET_INPUT");
|
||||||
setField<XpressNetInput>(L, "XPRESSNET_INPUT");
|
registerValue<XpressNetInput>(L, "XPRESSNET_INPUT");
|
||||||
setField<InputList>(L, "INPUT_LIST");
|
registerValue<InputList>(L, "INPUT_LIST");
|
||||||
|
|
||||||
setField<OutputList>(L, "OUTPUT_LIST");
|
registerValue<OutputList>(L, "OUTPUT_LIST");
|
||||||
setField<LocoNetOutput>(L, "LOCONET_OUTPUT");
|
registerValue<LocoNetOutput>(L, "LOCONET_OUTPUT");
|
||||||
|
|
||||||
setField<RailVehicleList>(L, "RAIL_VEHICLE_LIST");
|
registerValue<RailVehicleList>(L, "RAIL_VEHICLE_LIST");
|
||||||
setField<Locomotive>(L, "LOCOMOTIVE");
|
registerValue<Locomotive>(L, "LOCOMOTIVE");
|
||||||
setField<FreightCar>(L, "FREIGHT_CAR");
|
registerValue<FreightCar>(L, "FREIGHT_CAR");
|
||||||
|
|
||||||
setField<Train>(L, "TRAIN");
|
registerValue<Train>(L, "TRAIN");
|
||||||
setField<TrainList>(L, "TRAIN_LIST");
|
registerValue<TrainList>(L, "TRAIN_LIST");
|
||||||
|
|
||||||
setField<World>(L, "WORLD");
|
registerValue<World>(L, "WORLD");
|
||||||
}
|
}
|
||||||
|
|
||||||
int Class::isInstance(lua_State* L)
|
void Class::push(lua_State* L, std::string_view classId)
|
||||||
{
|
{
|
||||||
if(lua_gettop(L) != 2)
|
lua_getglobal(L, metaTableName);
|
||||||
errorExpectedNArgumentsGotN(L, 2, lua_gettop(L));
|
assert(lua_istable(L, -1));
|
||||||
|
lua_rawgetp(L, -1, classId.data());
|
||||||
|
assert(lua_isuserdata(L, -1));
|
||||||
|
lua_insert(L, lua_gettop(L) - 1);
|
||||||
|
lua_pop(L, 1);
|
||||||
|
assert(lua_isuserdata(L, -1));
|
||||||
|
}
|
||||||
|
|
||||||
push(L, (*reinterpret_cast<IsInstance*>(luaL_checkudata(L, 2, metaTableName)))(Object::test(L, 1)));
|
void Class::push(lua_State* L, const ObjectPtr& object)
|
||||||
|
{
|
||||||
|
push(L, object->getClassId());
|
||||||
|
}
|
||||||
|
|
||||||
|
int Class::__tostring(lua_State* L)
|
||||||
|
{
|
||||||
|
Sandbox::getGlobal(L, metaTableName);
|
||||||
|
|
||||||
|
// get the real table, the global is wrapped for write protection:
|
||||||
|
lua_getmetatable(L, -1);
|
||||||
|
lua_getfield(L, -1, "__index");
|
||||||
|
assert(lua_istable(L, -1));
|
||||||
|
|
||||||
|
// loop over table to find value and the return key
|
||||||
|
const int idx = lua_gettop(L);
|
||||||
|
lua_pushnil(L);
|
||||||
|
while(lua_next(L, idx))
|
||||||
|
{
|
||||||
|
const bool eq = lua_compare(L, 1, -1, LUA_OPEQ);
|
||||||
|
lua_pop(L, 1); // pop value
|
||||||
|
if(eq)
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
lua_pushlstring(L, NULL, 0);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Class::getClass(lua_State* L)
|
||||||
|
{
|
||||||
|
checkArguments(L, 1);
|
||||||
|
push(L, Object::check(L, 1));
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -32,7 +32,19 @@ struct Class
|
|||||||
{
|
{
|
||||||
static void registerValues(lua_State* L);
|
static void registerValues(lua_State* L);
|
||||||
|
|
||||||
static int isInstance(lua_State* L);
|
static void push(lua_State* L, std::string_view classId);
|
||||||
|
static void push(lua_State* L, const ObjectPtr& object);
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
static void push(lua_State* L)
|
||||||
|
{
|
||||||
|
static_assert(std::is_base_of_v<::Object, T>);
|
||||||
|
push(L, T::classId);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int __tostring(lua_State* L);
|
||||||
|
|
||||||
|
static int getClass(lua_State* L);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -27,6 +27,7 @@
|
|||||||
#include "log.hpp"
|
#include "log.hpp"
|
||||||
#include "class.hpp"
|
#include "class.hpp"
|
||||||
#include "to.hpp"
|
#include "to.hpp"
|
||||||
|
#include "type.hpp"
|
||||||
#include <version.hpp>
|
#include <version.hpp>
|
||||||
#include <traintastic/utils/str.hpp>
|
#include <traintastic/utils/str.hpp>
|
||||||
#include <traintastic/codename.hpp>
|
#include <traintastic/codename.hpp>
|
||||||
@ -72,7 +73,17 @@ constexpr std::array<std::string_view, 23> readOnlyGlobals = {{
|
|||||||
"set",
|
"set",
|
||||||
}};
|
}};
|
||||||
|
|
||||||
static void addBaseLib(lua_State* L, std::initializer_list<const char*> names)
|
static void addExtensions(lua_State* L, std::initializer_list<std::pair<const char*, lua_CFunction>> extensions)
|
||||||
|
{
|
||||||
|
assert(lua_istable(L, -1));
|
||||||
|
for(auto [name, func] : extensions)
|
||||||
|
{
|
||||||
|
lua_pushcfunction(L, func);
|
||||||
|
lua_setfield(L, -2, name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void addBaseLib(lua_State* L, std::initializer_list<const char*> names, std::initializer_list<std::pair<const char*, lua_CFunction>> extensions = {})
|
||||||
{
|
{
|
||||||
// load Lua baselib:
|
// load Lua baselib:
|
||||||
lua_pushcfunction(L, luaopen_base);
|
lua_pushcfunction(L, luaopen_base);
|
||||||
@ -85,11 +96,13 @@ static void addBaseLib(lua_State* L, std::initializer_list<const char*> names)
|
|||||||
assert(!lua_isnil(L, -1));
|
assert(!lua_isnil(L, -1));
|
||||||
lua_setfield(L, -2, name);
|
lua_setfield(L, -2, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
addExtensions(L, extensions);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void addLib(lua_State* L, const char* libraryName, lua_CFunction openFunction, std::initializer_list<const char*> names)
|
static void addLib(lua_State* L, const char* libraryName, lua_CFunction openFunction, std::initializer_list<const char*> names, std::initializer_list<std::pair<const char*, lua_CFunction>> extensions = {})
|
||||||
{
|
{
|
||||||
lua_createtable(L, 0, names.size());
|
lua_createtable(L, 0, names.size() + extensions.size());
|
||||||
|
|
||||||
luaL_requiref(L, libraryName, openFunction, 1);
|
luaL_requiref(L, libraryName, openFunction, 1);
|
||||||
|
|
||||||
@ -102,6 +115,8 @@ static void addLib(lua_State* L, const char* libraryName, lua_CFunction openFunc
|
|||||||
|
|
||||||
lua_pop(L, 1); // pop lib
|
lua_pop(L, 1); // pop lib
|
||||||
|
|
||||||
|
addExtensions(L, extensions);
|
||||||
|
|
||||||
Lua::ReadOnlyTable::wrap(L, -1);
|
Lua::ReadOnlyTable::wrap(L, -1);
|
||||||
lua_setfield(L, -2, libraryName);
|
lua_setfield(L, -2, libraryName);
|
||||||
}
|
}
|
||||||
@ -166,9 +181,14 @@ SandboxPtr Sandbox::create(Script& script)
|
|||||||
// setup globals:
|
// setup globals:
|
||||||
lua_newtable(L);
|
lua_newtable(L);
|
||||||
|
|
||||||
// add Lua lib functions:
|
// add standard Lua lib functions and extensions/replacements:
|
||||||
addBaseLib(L, {
|
addBaseLib(L,
|
||||||
"assert", "type", "pairs", "ipairs", "next", "tonumber", "tostring",
|
{
|
||||||
|
"assert", "pairs", "ipairs", "next", "tonumber", "tostring",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
{"type", type},
|
||||||
|
{"get_class", Class::getClass},
|
||||||
});
|
});
|
||||||
addLib(L, LUA_MATHLIBNAME, luaopen_math, {
|
addLib(L, LUA_MATHLIBNAME, luaopen_math, {
|
||||||
"abs", "acos", "asin", "atan", "ceil", "cos", "deg", "exp",
|
"abs", "acos", "asin", "atan", "ceil", "cos", "deg", "exp",
|
||||||
@ -211,10 +231,6 @@ SandboxPtr Sandbox::create(Script& script)
|
|||||||
Log::push(L);
|
Log::push(L);
|
||||||
lua_setfield(L, -2, "log");
|
lua_setfield(L, -2, "log");
|
||||||
|
|
||||||
// add is_instance function:
|
|
||||||
lua_pushcfunction(L, Class::isInstance);
|
|
||||||
lua_setfield(L, -2, "is_instance");
|
|
||||||
|
|
||||||
// add class types:
|
// add class types:
|
||||||
lua_newtable(L);
|
lua_newtable(L);
|
||||||
Class::registerValues(L);
|
Class::registerValues(L);
|
||||||
@ -252,7 +268,7 @@ Sandbox::StateData& Sandbox::getStateData(lua_State* L)
|
|||||||
|
|
||||||
int Sandbox::getGlobal(lua_State* L, const char* name)
|
int Sandbox::getGlobal(lua_State* L, const char* name)
|
||||||
{
|
{
|
||||||
lua_getglobal(L, LUA_SANDBOX); // get the sandbox
|
lua_getglobal(L, LUA_SANDBOX_GLOBALS); // get the sandbox
|
||||||
lua_pushstring(L, name);
|
lua_pushstring(L, name);
|
||||||
const int type = lua_gettable(L, -2); // get item
|
const int type = lua_gettable(L, -2); // get item
|
||||||
lua_insert(L, lua_gettop(L) - 1); // swap item and sandbox on the stack
|
lua_insert(L, lua_gettop(L) - 1); // swap item and sandbox on the stack
|
||||||
|
|||||||
80
server/src/lua/type.cpp
Normale Datei
80
server/src/lua/type.cpp
Normale Datei
@ -0,0 +1,80 @@
|
|||||||
|
/**
|
||||||
|
* server/src/lua/type.cpp
|
||||||
|
*
|
||||||
|
* This file is part of the traintastic source code.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2021 Reinder Feenstra
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program 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 General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "type.hpp"
|
||||||
|
#include "object.hpp"
|
||||||
|
#include "class.hpp"
|
||||||
|
#include "sandbox.hpp"
|
||||||
|
|
||||||
|
namespace Lua {
|
||||||
|
|
||||||
|
int type(lua_State* L)
|
||||||
|
{
|
||||||
|
const int tp = lua_type(L, 1);
|
||||||
|
|
||||||
|
if(tp == LUA_TUSERDATA)
|
||||||
|
{
|
||||||
|
if(auto object = Object::test(L, 1))
|
||||||
|
{
|
||||||
|
lua_pushstring(L, "object");
|
||||||
|
Class::push(L, object);
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(lua_getmetatable(L, 1))
|
||||||
|
{
|
||||||
|
lua_getfield(L, -1, "__name");
|
||||||
|
const char* name = lua_tostring(L, -1);
|
||||||
|
|
||||||
|
// check for enum:
|
||||||
|
Sandbox::getGlobal(L, "enum");
|
||||||
|
lua_getfield(L, -1, name);
|
||||||
|
if(lua_istable(L, -1))
|
||||||
|
{
|
||||||
|
lua_pop(L, 2);
|
||||||
|
lua_pushstring(L, "enum");
|
||||||
|
lua_replace(L, -3);
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
lua_pop(L, 2);
|
||||||
|
|
||||||
|
// check for set:
|
||||||
|
Sandbox::getGlobal(L, "set");
|
||||||
|
lua_getfield(L, -1, name);
|
||||||
|
if(lua_istable(L, -1))
|
||||||
|
{
|
||||||
|
lua_pop(L, 2);
|
||||||
|
lua_pushstring(L, "set");
|
||||||
|
lua_replace(L, -3);
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
lua_pop(L, 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
lua_pushstring(L, lua_typename(L, tp));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
34
server/src/lua/type.hpp
Normale Datei
34
server/src/lua/type.hpp
Normale Datei
@ -0,0 +1,34 @@
|
|||||||
|
/**
|
||||||
|
* server/src/lua/type.hpp
|
||||||
|
*
|
||||||
|
* This file is part of the traintastic source code.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2021 Reinder Feenstra
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program 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 General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef TRAINTASTIC_SERVER_LUA_TYPE_HPP
|
||||||
|
#define TRAINTASTIC_SERVER_LUA_TYPE_HPP
|
||||||
|
|
||||||
|
#include <lua.hpp>
|
||||||
|
|
||||||
|
namespace Lua {
|
||||||
|
|
||||||
|
int type(lua_State* L);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
Laden…
x
In neuem Issue referenzieren
Einen Benutzer sperren