Refactor GameController events
More precisely, refactor the code responsible for routing these GameController events to the Lua side. The issue with the previous solution was it relied on preprocessor macros to switch between Lua-ful and Lua-less builds.
This commit is contained in:
parent
27ddf78e0c
commit
33edb2e0e4
22
src/common/VariantIndex.h
Normal file
22
src/common/VariantIndex.h
Normal file
@ -0,0 +1,22 @@
|
||||
#pragma once
|
||||
#include <variant>
|
||||
#include <utility>
|
||||
|
||||
// https://stackoverflow.com/a/52303671
|
||||
template<typename VariantType, typename T, std::size_t index = 0>
|
||||
constexpr std::size_t VariantIndex()
|
||||
{
|
||||
static_assert(std::variant_size_v<VariantType> > index, "Type not found in variant");
|
||||
if constexpr (index == std::variant_size_v<VariantType>)
|
||||
{
|
||||
return index;
|
||||
}
|
||||
else if constexpr (std::is_same_v<std::variant_alternative_t<index, VariantType>, T>)
|
||||
{
|
||||
return index;
|
||||
}
|
||||
else
|
||||
{
|
||||
return VariantIndex<VariantType, T, index + 1>();
|
||||
}
|
||||
}
|
@ -13,9 +13,9 @@
|
||||
#include "RenderPreset.h"
|
||||
#include "Tool.h"
|
||||
|
||||
#include "GameControllerEvents.h"
|
||||
#ifdef LUACONSOLE
|
||||
# include "lua/LuaScriptInterface.h"
|
||||
# include "lua/LuaEvents.h"
|
||||
#else
|
||||
# include "lua/TPTScriptInterface.h"
|
||||
#endif
|
||||
@ -521,14 +521,12 @@ void GameController::CutRegion(ui::Point point1, ui::Point point2)
|
||||
|
||||
bool GameController::MouseMove(int x, int y, int dx, int dy)
|
||||
{
|
||||
MouseMoveEvent ev(x, y, dx, dy);
|
||||
return commandInterface->HandleEvent(LuaEvents::mousemove, &ev);
|
||||
return commandInterface->HandleEvent(MouseMoveEvent{ x, y, dx, dy });
|
||||
}
|
||||
|
||||
bool GameController::MouseDown(int x, int y, unsigned button)
|
||||
{
|
||||
MouseDownEvent ev(x, y, button);
|
||||
bool ret = commandInterface->HandleEvent(LuaEvents::mousedown, &ev);
|
||||
bool ret = commandInterface->HandleEvent(MouseDownEvent{ x, y, button });
|
||||
if (ret && y<YRES && x<XRES && !gameView->GetPlacingSave() && !gameView->GetPlacingZoom())
|
||||
{
|
||||
ui::Point point = gameModel->AdjustZoomCoords(ui::Point(x, y));
|
||||
@ -551,8 +549,7 @@ bool GameController::MouseDown(int x, int y, unsigned button)
|
||||
|
||||
bool GameController::MouseUp(int x, int y, unsigned button, MouseupReason reason)
|
||||
{
|
||||
MouseUpEvent ev(x, y, button, reason);
|
||||
bool ret = commandInterface->HandleEvent(LuaEvents::mouseup, &ev);
|
||||
bool ret = commandInterface->HandleEvent(MouseUpEvent{ x, y, button, reason });
|
||||
if (reason != mouseUpNormal)
|
||||
return ret;
|
||||
if (ret && foundSignID != -1 && y<YRES && x<XRES && !gameView->GetPlacingSave())
|
||||
@ -601,26 +598,22 @@ bool GameController::MouseUp(int x, int y, unsigned button, MouseupReason reason
|
||||
|
||||
bool GameController::MouseWheel(int x, int y, int d)
|
||||
{
|
||||
MouseWheelEvent ev(x, y, d);
|
||||
return commandInterface->HandleEvent(LuaEvents::mousewheel, &ev);
|
||||
return commandInterface->HandleEvent(MouseWheelEvent{ x, y, d });
|
||||
}
|
||||
|
||||
bool GameController::TextInput(String text)
|
||||
{
|
||||
TextInputEvent ev(text);
|
||||
return commandInterface->HandleEvent(LuaEvents::textinput, &ev);
|
||||
return commandInterface->HandleEvent(TextInputEvent{ text });
|
||||
}
|
||||
|
||||
bool GameController::TextEditing(String text)
|
||||
{
|
||||
TextEditingEvent ev(text);
|
||||
return commandInterface->HandleEvent(LuaEvents::textediting, &ev);
|
||||
return commandInterface->HandleEvent(TextEditingEvent{ text });
|
||||
}
|
||||
|
||||
bool GameController::KeyPress(int key, int scan, bool repeat, bool shift, bool ctrl, bool alt)
|
||||
{
|
||||
KeyEvent ev(key, scan, repeat, shift, ctrl, alt);
|
||||
bool ret = commandInterface->HandleEvent(LuaEvents::keypress, &ev);
|
||||
bool ret = commandInterface->HandleEvent(KeyPressEvent{ key, scan, repeat, shift, ctrl, alt });
|
||||
if (repeat)
|
||||
return ret;
|
||||
if (ret)
|
||||
@ -699,8 +692,7 @@ bool GameController::KeyPress(int key, int scan, bool repeat, bool shift, bool c
|
||||
|
||||
bool GameController::KeyRelease(int key, int scan, bool repeat, bool shift, bool ctrl, bool alt)
|
||||
{
|
||||
KeyEvent ev(key, scan, repeat, shift, ctrl, alt);
|
||||
bool ret = commandInterface->HandleEvent(LuaEvents::keyrelease, &ev);
|
||||
bool ret = commandInterface->HandleEvent(KeyReleaseEvent{ key, scan, repeat, shift, ctrl, alt });
|
||||
if (repeat)
|
||||
return ret;
|
||||
if (ret)
|
||||
@ -773,14 +765,12 @@ void GameController::Blur()
|
||||
{
|
||||
// Tell lua that mouse is up (even if it really isn't)
|
||||
MouseUp(0, 0, 0, mouseUpBlur);
|
||||
BlurEvent ev;
|
||||
commandInterface->HandleEvent(LuaEvents::blur, &ev);
|
||||
commandInterface->HandleEvent(BlurEvent{});
|
||||
}
|
||||
|
||||
void GameController::Exit()
|
||||
{
|
||||
CloseEvent ev;
|
||||
commandInterface->HandleEvent(LuaEvents::close, &ev);
|
||||
commandInterface->HandleEvent(CloseEvent{});
|
||||
gameView->CloseActiveWindow();
|
||||
HasDone = true;
|
||||
}
|
||||
|
98
src/gui/game/GameControllerEvents.h
Normal file
98
src/gui/game/GameControllerEvents.h
Normal file
@ -0,0 +1,98 @@
|
||||
#pragma once
|
||||
#include "Config.h"
|
||||
#include "common/String.h"
|
||||
#include <variant>
|
||||
|
||||
struct TextInputEvent
|
||||
{
|
||||
String text;
|
||||
};
|
||||
|
||||
struct TextEditingEvent
|
||||
{
|
||||
String text;
|
||||
};
|
||||
|
||||
struct KeyEvent
|
||||
{
|
||||
int key;
|
||||
int scan;
|
||||
bool repeat;
|
||||
bool shift;
|
||||
bool ctrl;
|
||||
bool alt;
|
||||
};
|
||||
|
||||
struct KeyPressEvent : public KeyEvent
|
||||
{
|
||||
};
|
||||
|
||||
struct KeyReleaseEvent : public KeyEvent
|
||||
{
|
||||
};
|
||||
|
||||
struct MouseDownEvent
|
||||
{
|
||||
int x;
|
||||
int y;
|
||||
unsigned int button;
|
||||
};
|
||||
|
||||
struct MouseUpEvent
|
||||
{
|
||||
int x;
|
||||
int y;
|
||||
unsigned int button;
|
||||
int reason;
|
||||
};
|
||||
|
||||
struct MouseMoveEvent
|
||||
{
|
||||
int x;
|
||||
int y;
|
||||
int dx;
|
||||
int dy;
|
||||
};
|
||||
|
||||
struct MouseWheelEvent
|
||||
{
|
||||
int x;
|
||||
int y;
|
||||
int d;
|
||||
};
|
||||
|
||||
struct TickEvent
|
||||
{
|
||||
};
|
||||
|
||||
struct BlurEvent
|
||||
{
|
||||
};
|
||||
|
||||
struct CloseEvent
|
||||
{
|
||||
};
|
||||
|
||||
struct BeforeSimEvent
|
||||
{
|
||||
};
|
||||
|
||||
struct AfterSimEvent
|
||||
{
|
||||
};
|
||||
|
||||
using GameControllerEvent = std::variant<
|
||||
TextInputEvent,
|
||||
TextEditingEvent,
|
||||
KeyPressEvent,
|
||||
KeyReleaseEvent,
|
||||
MouseDownEvent,
|
||||
MouseUpEvent,
|
||||
MouseMoveEvent,
|
||||
MouseWheelEvent,
|
||||
TickEvent,
|
||||
BlurEvent,
|
||||
CloseEvent,
|
||||
BeforeSimEvent,
|
||||
AfterSimEvent
|
||||
>;
|
@ -2,9 +2,8 @@
|
||||
#include "Config.h"
|
||||
|
||||
#include "common/String.h"
|
||||
#include "lua/LuaEvents.h"
|
||||
#include "gui/game/GameControllerEvents.h"
|
||||
|
||||
class Event;
|
||||
class GameModel;
|
||||
class GameController;
|
||||
class Tool;
|
||||
@ -25,7 +24,7 @@ public:
|
||||
|
||||
virtual void OnTick() { }
|
||||
|
||||
virtual bool HandleEvent(LuaEvents::EventTypes eventType, Event * event) { return true; }
|
||||
virtual bool HandleEvent(const GameControllerEvent &event) { return true; }
|
||||
|
||||
virtual int Command(String command);
|
||||
virtual String FormatCommand(String command);
|
||||
|
@ -1,252 +0,0 @@
|
||||
#include "LuaEvents.h"
|
||||
#ifdef LUACONSOLE
|
||||
# include "LuaCompat.h"
|
||||
# include "LuaScriptInterface.h"
|
||||
# include "common/Platform.h"
|
||||
# include "gui/interface/Engine.h"
|
||||
#endif
|
||||
|
||||
void Event::PushInteger(lua_State * l, int num)
|
||||
{
|
||||
#ifdef LUACONSOLE
|
||||
lua_pushinteger(l, num);
|
||||
#endif
|
||||
}
|
||||
|
||||
void Event::PushBoolean(lua_State * l, bool flag)
|
||||
{
|
||||
#ifdef LUACONSOLE
|
||||
lua_pushboolean(l, flag);
|
||||
#endif
|
||||
}
|
||||
|
||||
void Event::PushString(lua_State * l, ByteString str)
|
||||
{
|
||||
#ifdef LUACONSOLE
|
||||
tpt_lua_pushByteString(l, str);
|
||||
#endif
|
||||
}
|
||||
|
||||
TextInputEvent::TextInputEvent(String text):
|
||||
text(text)
|
||||
{}
|
||||
|
||||
int TextInputEvent::PushToStack(lua_State * l)
|
||||
{
|
||||
PushString(l, text.ToUtf8());
|
||||
return 1;
|
||||
}
|
||||
|
||||
TextEditingEvent::TextEditingEvent(String text):
|
||||
text(text)
|
||||
{}
|
||||
|
||||
int TextEditingEvent::PushToStack(lua_State * l)
|
||||
{
|
||||
PushString(l, text.ToUtf8());
|
||||
return 1;
|
||||
}
|
||||
|
||||
KeyEvent::KeyEvent(int key, int scan, bool repeat, bool shift, bool ctrl, bool alt):
|
||||
key(key),
|
||||
scan(scan),
|
||||
repeat(repeat),
|
||||
shift(shift),
|
||||
ctrl(ctrl),
|
||||
alt(alt)
|
||||
{}
|
||||
|
||||
int KeyEvent::PushToStack(lua_State * l)
|
||||
{
|
||||
PushInteger(l, key);
|
||||
PushInteger(l, scan);
|
||||
PushBoolean(l, repeat);
|
||||
PushBoolean(l, shift);
|
||||
PushBoolean(l, ctrl);
|
||||
PushBoolean(l, alt);
|
||||
|
||||
return 6;
|
||||
}
|
||||
|
||||
MouseDownEvent::MouseDownEvent(int x, int y, int button):
|
||||
x(x),
|
||||
y(y),
|
||||
button(button)
|
||||
{}
|
||||
|
||||
int MouseDownEvent::PushToStack(lua_State * l)
|
||||
{
|
||||
PushInteger(l, x);
|
||||
PushInteger(l, y);
|
||||
PushInteger(l, button);
|
||||
|
||||
return 3;
|
||||
}
|
||||
|
||||
MouseUpEvent::MouseUpEvent(int x, int y, int button, int reason):
|
||||
x(x),
|
||||
y(y),
|
||||
button(button),
|
||||
reason(reason)
|
||||
{}
|
||||
|
||||
int MouseUpEvent::PushToStack(lua_State * l)
|
||||
{
|
||||
PushInteger(l, x);
|
||||
PushInteger(l, y);
|
||||
PushInteger(l, button);
|
||||
PushInteger(l, reason);
|
||||
|
||||
return 4;
|
||||
}
|
||||
|
||||
MouseMoveEvent::MouseMoveEvent(int x, int y, int dx, int dy):
|
||||
x(x),
|
||||
y(y),
|
||||
dx(dx),
|
||||
dy(dy)
|
||||
{}
|
||||
|
||||
int MouseMoveEvent::PushToStack(lua_State * l)
|
||||
{
|
||||
PushInteger(l, x);
|
||||
PushInteger(l, y);
|
||||
PushInteger(l, dx);
|
||||
PushInteger(l, dy);
|
||||
|
||||
return 4;
|
||||
}
|
||||
|
||||
MouseWheelEvent::MouseWheelEvent(int x, int y, int d):
|
||||
x(x),
|
||||
y(y),
|
||||
d(d)
|
||||
{}
|
||||
|
||||
int MouseWheelEvent::PushToStack(lua_State * l)
|
||||
{
|
||||
PushInteger(l, x);
|
||||
PushInteger(l, y);
|
||||
PushInteger(l, d);
|
||||
|
||||
return 3;
|
||||
}
|
||||
|
||||
#ifdef LUACONSOLE
|
||||
int LuaEvents::RegisterEventHook(lua_State *l, ByteString eventName)
|
||||
{
|
||||
if (lua_isfunction(l, 2))
|
||||
{
|
||||
tpt_lua_pushByteString(l, eventName);
|
||||
lua_rawget(l, LUA_REGISTRYINDEX);
|
||||
if (!lua_istable(l, -1))
|
||||
{
|
||||
lua_pop(l, 1);
|
||||
lua_newtable(l);
|
||||
tpt_lua_pushByteString(l, eventName);
|
||||
lua_pushvalue(l, -2);
|
||||
lua_rawset(l, LUA_REGISTRYINDEX);
|
||||
}
|
||||
int c = lua_objlen(l, -1);
|
||||
lua_pushvalue(l, 2);
|
||||
lua_rawseti(l, -2, c + 1);
|
||||
}
|
||||
lua_pushvalue(l, 2);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int LuaEvents::UnregisterEventHook(lua_State *l, ByteString eventName)
|
||||
{
|
||||
if (lua_isfunction(l, 2))
|
||||
{
|
||||
tpt_lua_pushByteString(l, eventName);
|
||||
lua_rawget(l, LUA_REGISTRYINDEX);
|
||||
if (!lua_istable(l, -1))
|
||||
{
|
||||
lua_pop(l, -1);
|
||||
lua_newtable(l);
|
||||
tpt_lua_pushByteString(l, eventName);
|
||||
lua_pushvalue(l, -2);
|
||||
lua_rawset(l, LUA_REGISTRYINDEX);
|
||||
}
|
||||
int len = lua_objlen(l, -1);
|
||||
int adjust = 0;
|
||||
for (int i = 1; i <= len; i++)
|
||||
{
|
||||
lua_rawgeti(l, -1, i + adjust);
|
||||
// unregister the function
|
||||
if (lua_equal(l, 2, -1))
|
||||
{
|
||||
lua_pop(l, 1);
|
||||
adjust++;
|
||||
i--;
|
||||
}
|
||||
// Update the function index in the table if we've removed a previous function
|
||||
else if (adjust)
|
||||
lua_rawseti(l, -2, i);
|
||||
else
|
||||
lua_pop(l, 1);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool LuaEvents::HandleEvent(LuaScriptInterface *luacon_ci, Event *event, ByteString eventName)
|
||||
{
|
||||
ui::Engine::Ref().LastTick(Platform::GetTime());
|
||||
bool cont = true;
|
||||
lua_State* l = luacon_ci->l;
|
||||
tpt_lua_pushByteString(l, eventName);
|
||||
lua_rawget(l, LUA_REGISTRYINDEX);
|
||||
if (!lua_istable(l, -1))
|
||||
{
|
||||
lua_pop(l, 1);
|
||||
lua_newtable(l);
|
||||
tpt_lua_pushByteString(l, eventName);
|
||||
lua_pushvalue(l, -2);
|
||||
lua_rawset(l, LUA_REGISTRYINDEX);
|
||||
}
|
||||
int len = lua_objlen(l, -1);
|
||||
for (int i = 1; i <= len && cont; i++)
|
||||
{
|
||||
lua_rawgeti(l, -1, i);
|
||||
int numArgs = event->PushToStack(l);
|
||||
int callret = lua_pcall(l, numArgs, 1, 0);
|
||||
if (callret)
|
||||
{
|
||||
if (luacon_geterror(luacon_ci) == "Error: Script not responding")
|
||||
{
|
||||
ui::Engine::Ref().LastTick(Platform::GetTime());
|
||||
for (int j = i; j <= len - 1; j++)
|
||||
{
|
||||
lua_rawgeti(l, -2, j + 1);
|
||||
lua_rawseti(l, -3, j);
|
||||
}
|
||||
lua_pushnil(l);
|
||||
lua_rawseti(l, -3, len);
|
||||
i--;
|
||||
}
|
||||
luacon_ci->Log(CommandInterface::LogError, luacon_geterror(luacon_ci));
|
||||
lua_pop(l, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!lua_isnoneornil(l, -1))
|
||||
cont = lua_toboolean(l, -1);
|
||||
lua_pop(l, 1);
|
||||
}
|
||||
len = lua_objlen(l, -1);
|
||||
}
|
||||
lua_pop(l, 1);
|
||||
return cont;
|
||||
}
|
||||
|
||||
|
||||
String LuaEvents::luacon_geterror(LuaScriptInterface * luacon_ci)
|
||||
{
|
||||
luaL_tostring(luacon_ci->l, -1);
|
||||
String err = tpt_lua_optString(luacon_ci->l, -1, "failed to execute");
|
||||
lua_pop(luacon_ci->l, 1);
|
||||
return err;
|
||||
}
|
||||
#endif
|
@ -1,160 +0,0 @@
|
||||
#pragma once
|
||||
#include "Config.h"
|
||||
|
||||
#include "common/String.h"
|
||||
|
||||
struct lua_State;
|
||||
class LuaScriptInterface;
|
||||
|
||||
class Event
|
||||
{
|
||||
protected:
|
||||
void PushInteger(lua_State * l, int num);
|
||||
void PushBoolean(lua_State * l, bool flag);
|
||||
void PushString(lua_State * l, ByteString str);
|
||||
|
||||
public:
|
||||
virtual int PushToStack(lua_State * l) = 0;
|
||||
virtual ~Event() = default;
|
||||
};
|
||||
|
||||
class TextInputEvent : public Event
|
||||
{
|
||||
String text;
|
||||
|
||||
public:
|
||||
TextInputEvent(String text);
|
||||
|
||||
int PushToStack(lua_State * l) override;
|
||||
};
|
||||
|
||||
class TextEditingEvent : public Event
|
||||
{
|
||||
String text;
|
||||
|
||||
public:
|
||||
TextEditingEvent(String text);
|
||||
|
||||
int PushToStack(lua_State * l) override;
|
||||
};
|
||||
|
||||
class KeyEvent : public Event
|
||||
{
|
||||
int key;
|
||||
int scan;
|
||||
bool repeat;
|
||||
bool shift;
|
||||
bool ctrl;
|
||||
bool alt;
|
||||
|
||||
public:
|
||||
KeyEvent(int key, int scan, bool repeat, bool shift, bool ctrl, bool alt);
|
||||
|
||||
int PushToStack(lua_State * l) override;
|
||||
};
|
||||
|
||||
class MouseDownEvent : public Event
|
||||
{
|
||||
int x;
|
||||
int y;
|
||||
int button;
|
||||
|
||||
public:
|
||||
MouseDownEvent(int x, int y, int button);
|
||||
|
||||
int PushToStack(lua_State * l) override;
|
||||
};
|
||||
|
||||
class MouseUpEvent : public Event
|
||||
{
|
||||
int x;
|
||||
int y;
|
||||
int button;
|
||||
int reason;
|
||||
|
||||
public:
|
||||
MouseUpEvent(int x, int y, int button, int reason);
|
||||
|
||||
int PushToStack(lua_State * l) override;
|
||||
};
|
||||
|
||||
class MouseMoveEvent : public Event
|
||||
{
|
||||
int x;
|
||||
int y;
|
||||
int dx;
|
||||
int dy;
|
||||
|
||||
public:
|
||||
MouseMoveEvent(int x, int y, int dx, int dy);
|
||||
|
||||
int PushToStack(lua_State * l) override;
|
||||
};
|
||||
|
||||
class MouseWheelEvent : public Event
|
||||
{
|
||||
int x;
|
||||
int y;
|
||||
int d;
|
||||
|
||||
public:
|
||||
MouseWheelEvent(int x, int y, int d);
|
||||
|
||||
int PushToStack(lua_State * l) override;
|
||||
};
|
||||
|
||||
class TickEvent : public Event
|
||||
{
|
||||
public:
|
||||
int PushToStack(lua_State *l) override { return 0; }
|
||||
};
|
||||
|
||||
class BlurEvent : public Event
|
||||
{
|
||||
public:
|
||||
int PushToStack(lua_State *l) override { return 0; }
|
||||
};
|
||||
|
||||
class CloseEvent : public Event
|
||||
{
|
||||
public:
|
||||
int PushToStack(lua_State *l) override { return 0; }
|
||||
};
|
||||
|
||||
class BeforeSimEvent : public Event
|
||||
{
|
||||
public:
|
||||
int PushToStack(lua_State *l) override { return 0; }
|
||||
};
|
||||
|
||||
class AfterSimEvent : public Event
|
||||
{
|
||||
public:
|
||||
int PushToStack(lua_State *l) override { return 0; }
|
||||
};
|
||||
|
||||
class LuaEvents
|
||||
{
|
||||
public:
|
||||
enum EventTypes {
|
||||
keypress,
|
||||
keyrelease,
|
||||
textinput,
|
||||
textediting,
|
||||
mousedown,
|
||||
mouseup,
|
||||
mousemove,
|
||||
mousewheel,
|
||||
tick,
|
||||
blur,
|
||||
close,
|
||||
beforesim,
|
||||
aftersim,
|
||||
};
|
||||
|
||||
static int RegisterEventHook(lua_State *l, ByteString eventName);
|
||||
static int UnregisterEventHook(lua_State *l, ByteString eventName);
|
||||
static bool HandleEvent(LuaScriptInterface *luacon_ci, Event *event, ByteString eventName);
|
||||
|
||||
static String luacon_geterror(LuaScriptInterface *luacon_ci);
|
||||
};
|
@ -3,6 +3,7 @@
|
||||
|
||||
#include "client/http/Request.h" // includes curl.h, needs to come first to silence a warning on windows
|
||||
#include "bzip2/bz2wrap.h"
|
||||
#include "common/VariantIndex.h"
|
||||
|
||||
#include "LuaScriptInterface.h"
|
||||
|
||||
@ -18,7 +19,6 @@
|
||||
#include "LuaBit.h"
|
||||
#include "LuaButton.h"
|
||||
#include "LuaCheckbox.h"
|
||||
#include "LuaEvents.h"
|
||||
#include "LuaLabel.h"
|
||||
#include "LuaProgressBar.h"
|
||||
#include "LuaSlider.h"
|
||||
@ -420,6 +420,14 @@ tpt.partsdata = nil");
|
||||
lua_el_mode_v = std::vector<int>(PT_NUM, 0);
|
||||
lua_el_mode = &lua_el_mode_v[0];
|
||||
|
||||
gameControllerEventHandlers = std::vector<LuaSmartRef>(std::variant_size<GameControllerEvent>::value, l);
|
||||
for (auto &ref : gameControllerEventHandlers)
|
||||
{
|
||||
lua_newtable(l);
|
||||
ref.Assign(l, -1);
|
||||
lua_pop(l, 1);
|
||||
}
|
||||
|
||||
luaCtypeDrawHandlers = std::vector<LuaSmartRef>(PT_NUM, l);
|
||||
luaCreateHandlers = std::vector<LuaSmartRef>(PT_NUM, l);
|
||||
luaCreateAllowedHandlers = std::vector<LuaSmartRef>(PT_NUM, l);
|
||||
@ -4156,33 +4164,60 @@ void LuaScriptInterface::initEventAPI()
|
||||
lua_getglobal(l, "event");
|
||||
lua_setglobal(l, "evt");
|
||||
|
||||
lua_pushinteger(l, LuaEvents::keypress); lua_setfield(l, -2, "keypress");
|
||||
lua_pushinteger(l, LuaEvents::keyrelease); lua_setfield(l, -2, "keyrelease");
|
||||
lua_pushinteger(l, LuaEvents::textinput); lua_setfield(l, -2, "textinput");
|
||||
lua_pushinteger(l, LuaEvents::textediting); lua_setfield(l, -2, "textediting");
|
||||
lua_pushinteger(l, LuaEvents::mousedown); lua_setfield(l, -2, "mousedown");
|
||||
lua_pushinteger(l, LuaEvents::mouseup); lua_setfield(l, -2, "mouseup");
|
||||
lua_pushinteger(l, LuaEvents::mousemove); lua_setfield(l, -2, "mousemove");
|
||||
lua_pushinteger(l, LuaEvents::mousewheel); lua_setfield(l, -2, "mousewheel");
|
||||
lua_pushinteger(l, LuaEvents::tick); lua_setfield(l, -2, "tick");
|
||||
lua_pushinteger(l, LuaEvents::blur); lua_setfield(l, -2, "blur");
|
||||
lua_pushinteger(l, LuaEvents::close); lua_setfield(l, -2, "close");
|
||||
lua_pushinteger(l, LuaEvents::beforesim); lua_setfield(l, -2, "beforesim");
|
||||
lua_pushinteger(l, LuaEvents::aftersim); lua_setfield(l, -2, "aftersim");
|
||||
lua_pushinteger(l, VariantIndex<GameControllerEvent, TextInputEvent >()); lua_setfield(l, -2, "textinput" );
|
||||
lua_pushinteger(l, VariantIndex<GameControllerEvent, TextEditingEvent>()); lua_setfield(l, -2, "textediting");
|
||||
lua_pushinteger(l, VariantIndex<GameControllerEvent, KeyPressEvent >()); lua_setfield(l, -2, "keypress" );
|
||||
lua_pushinteger(l, VariantIndex<GameControllerEvent, KeyReleaseEvent >()); lua_setfield(l, -2, "keyrelease" );
|
||||
lua_pushinteger(l, VariantIndex<GameControllerEvent, MouseDownEvent >()); lua_setfield(l, -2, "mousedown" );
|
||||
lua_pushinteger(l, VariantIndex<GameControllerEvent, MouseUpEvent >()); lua_setfield(l, -2, "mouseup" );
|
||||
lua_pushinteger(l, VariantIndex<GameControllerEvent, MouseMoveEvent >()); lua_setfield(l, -2, "mousemove" );
|
||||
lua_pushinteger(l, VariantIndex<GameControllerEvent, MouseWheelEvent >()); lua_setfield(l, -2, "mousewheel" );
|
||||
lua_pushinteger(l, VariantIndex<GameControllerEvent, TickEvent >()); lua_setfield(l, -2, "tick" );
|
||||
lua_pushinteger(l, VariantIndex<GameControllerEvent, BlurEvent >()); lua_setfield(l, -2, "blur" );
|
||||
lua_pushinteger(l, VariantIndex<GameControllerEvent, CloseEvent >()); lua_setfield(l, -2, "close" );
|
||||
lua_pushinteger(l, VariantIndex<GameControllerEvent, BeforeSimEvent >()); lua_setfield(l, -2, "beforesim" );
|
||||
lua_pushinteger(l, VariantIndex<GameControllerEvent, AfterSimEvent >()); lua_setfield(l, -2, "aftersim" );
|
||||
}
|
||||
|
||||
int LuaScriptInterface::event_register(lua_State * l)
|
||||
{
|
||||
int eventName = luaL_checkinteger(l, 1);
|
||||
int eventType = luaL_checkinteger(l, 1);
|
||||
luaL_checktype(l, 2, LUA_TFUNCTION);
|
||||
return LuaEvents::RegisterEventHook(l, ByteString::Build("tptevents-", eventName));
|
||||
if (eventType < 0 || eventType >= int(luacon_ci->gameControllerEventHandlers.size()))
|
||||
{
|
||||
luaL_error(l, "Invalid event type: %i", lua_tointeger(l, 1));
|
||||
}
|
||||
luacon_ci->gameControllerEventHandlers[eventType].Push(l);
|
||||
auto length = lua_objlen(l, -1);
|
||||
lua_pushvalue(l, 2);
|
||||
lua_rawseti(l, -2, length + 1);
|
||||
lua_pushvalue(l, 2);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int LuaScriptInterface::event_unregister(lua_State * l)
|
||||
{
|
||||
int eventName = luaL_checkinteger(l, 1);
|
||||
int eventType = luaL_checkinteger(l, 1);
|
||||
luaL_checktype(l, 2, LUA_TFUNCTION);
|
||||
return LuaEvents::UnregisterEventHook(l, ByteString::Build("tptevents-", eventName));
|
||||
if (eventType < 0 || eventType >= int(luacon_ci->gameControllerEventHandlers.size()))
|
||||
{
|
||||
luaL_error(l, "Invalid event type: %i", lua_tointeger(l, 1));
|
||||
}
|
||||
luacon_ci->gameControllerEventHandlers[eventType].Push(l);
|
||||
auto length = lua_objlen(l, -1);
|
||||
int skip = 0;
|
||||
for (auto i = 1U; i <= length; ++i)
|
||||
{
|
||||
lua_rawgeti(l, -1, i);
|
||||
if (!skip && lua_equal(l, -1, 2))
|
||||
{
|
||||
skip = 1;
|
||||
}
|
||||
lua_pop(l, 1);
|
||||
lua_rawgeti(l, -1, i + skip);
|
||||
lua_rawseti(l, -2, i);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int LuaScriptInterface::event_getmodifiers(lua_State * l)
|
||||
@ -4494,9 +4529,109 @@ void LuaScriptInterface::initHttpAPI()
|
||||
lua_setglobal(l, "http");
|
||||
}
|
||||
|
||||
bool LuaScriptInterface::HandleEvent(LuaEvents::EventTypes eventType, Event * event)
|
||||
static int PushGameControllerEvent(lua_State * l, const GameControllerEvent &event)
|
||||
{
|
||||
return LuaEvents::HandleEvent(this, event, ByteString::Build("tptevents-", eventType));
|
||||
if (auto *textInputEvent = std::get_if<TextInputEvent>(&event))
|
||||
{
|
||||
tpt_lua_pushString(l, textInputEvent->text);
|
||||
return 1;
|
||||
}
|
||||
else if (auto *textEditingEvent = std::get_if<TextEditingEvent>(&event))
|
||||
{
|
||||
tpt_lua_pushString(l, textEditingEvent->text);
|
||||
return 1;
|
||||
}
|
||||
else if (auto *keyPressEvent = std::get_if<KeyPressEvent>(&event))
|
||||
{
|
||||
lua_pushinteger(l, keyPressEvent->key);
|
||||
lua_pushinteger(l, keyPressEvent->scan);
|
||||
lua_pushboolean(l, keyPressEvent->repeat);
|
||||
lua_pushboolean(l, keyPressEvent->shift);
|
||||
lua_pushboolean(l, keyPressEvent->ctrl);
|
||||
lua_pushboolean(l, keyPressEvent->alt);
|
||||
return 6;
|
||||
}
|
||||
else if (auto *keyReleaseEvent = std::get_if<KeyReleaseEvent>(&event))
|
||||
{
|
||||
lua_pushinteger(l, keyReleaseEvent->key);
|
||||
lua_pushinteger(l, keyReleaseEvent->scan);
|
||||
lua_pushboolean(l, keyReleaseEvent->repeat);
|
||||
lua_pushboolean(l, keyReleaseEvent->shift);
|
||||
lua_pushboolean(l, keyReleaseEvent->ctrl);
|
||||
lua_pushboolean(l, keyReleaseEvent->alt);
|
||||
return 6;
|
||||
}
|
||||
else if (auto *mouseDownEvent = std::get_if<MouseDownEvent>(&event))
|
||||
{
|
||||
lua_pushinteger(l, mouseDownEvent->x);
|
||||
lua_pushinteger(l, mouseDownEvent->y);
|
||||
lua_pushinteger(l, mouseDownEvent->button);
|
||||
return 3;
|
||||
}
|
||||
else if (auto *mouseUpEvent = std::get_if<MouseUpEvent>(&event))
|
||||
{
|
||||
lua_pushinteger(l, mouseUpEvent->x);
|
||||
lua_pushinteger(l, mouseUpEvent->y);
|
||||
lua_pushinteger(l, mouseUpEvent->button);
|
||||
lua_pushinteger(l, mouseUpEvent->reason);
|
||||
return 4;
|
||||
}
|
||||
else if (auto *mouseMoveEvent = std::get_if<MouseMoveEvent>(&event))
|
||||
{
|
||||
lua_pushinteger(l, mouseMoveEvent->x);
|
||||
lua_pushinteger(l, mouseMoveEvent->y);
|
||||
lua_pushinteger(l, mouseMoveEvent->dx);
|
||||
lua_pushinteger(l, mouseMoveEvent->dy);
|
||||
return 4;
|
||||
}
|
||||
else if (auto *mouseWheelEvent = std::get_if<MouseWheelEvent>(&event))
|
||||
{
|
||||
lua_pushinteger(l, mouseWheelEvent->x);
|
||||
lua_pushinteger(l, mouseWheelEvent->y);
|
||||
lua_pushinteger(l, mouseWheelEvent->d);
|
||||
return 3;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool LuaScriptInterface::HandleEvent(const GameControllerEvent &event)
|
||||
{
|
||||
ui::Engine::Ref().LastTick(Platform::GetTime());
|
||||
bool cont = true;
|
||||
gameControllerEventHandlers[event.index()].Push(l);
|
||||
int len = lua_objlen(l, -1);
|
||||
for (int i = 1; i <= len && cont; i++)
|
||||
{
|
||||
lua_rawgeti(l, -1, i);
|
||||
int numArgs = PushGameControllerEvent(l, event);
|
||||
int callret = lua_pcall(l, numArgs, 1, 0);
|
||||
if (callret)
|
||||
{
|
||||
if (luacon_geterror() == "Error: Script not responding")
|
||||
{
|
||||
ui::Engine::Ref().LastTick(Platform::GetTime());
|
||||
for (int j = i; j <= len - 1; j++)
|
||||
{
|
||||
lua_rawgeti(l, -2, j + 1);
|
||||
lua_rawseti(l, -3, j);
|
||||
}
|
||||
lua_pushnil(l);
|
||||
lua_rawseti(l, -3, len);
|
||||
i--;
|
||||
}
|
||||
Log(CommandInterface::LogError, luacon_geterror());
|
||||
lua_pop(l, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!lua_isnoneornil(l, -1))
|
||||
cont = lua_toboolean(l, -1);
|
||||
lua_pop(l, 1);
|
||||
}
|
||||
len = lua_objlen(l, -1);
|
||||
}
|
||||
lua_pop(l, 1);
|
||||
return cont;
|
||||
}
|
||||
|
||||
void LuaScriptInterface::OnTick()
|
||||
@ -4508,8 +4643,7 @@ void LuaScriptInterface::OnTick()
|
||||
lua_setfield(l, -2, "NUM_PARTS");
|
||||
}
|
||||
lua_pop(l, 1);
|
||||
TickEvent ev;
|
||||
HandleEvent(LuaEvents::tick, &ev);
|
||||
HandleEvent(TickEvent{});
|
||||
}
|
||||
|
||||
int LuaScriptInterface::Command(String command)
|
||||
@ -4806,6 +4940,7 @@ LuaScriptInterface::~LuaScriptInterface() {
|
||||
luaCreateAllowedHandlers.clear();
|
||||
luaCreateHandlers.clear();
|
||||
luaCtypeDrawHandlers.clear();
|
||||
gameControllerEventHandlers.clear();
|
||||
lua_el_mode_v.clear();
|
||||
lua_el_func_v.clear();
|
||||
lua_gr_func_v.clear();
|
||||
|
@ -5,7 +5,7 @@
|
||||
#include "LuaSmartRef.h"
|
||||
|
||||
#include "CommandInterface.h"
|
||||
#include "lua/LuaEvents.h"
|
||||
#include "gui/game/GameControllerEvents.h"
|
||||
#include "simulation/StructProperty.h"
|
||||
#include "simulation/ElementDefs.h"
|
||||
|
||||
@ -194,6 +194,7 @@ class LuaScriptInterface: public CommandInterface
|
||||
|
||||
std::vector<LuaSmartRef> lua_el_func_v, lua_gr_func_v, lua_cd_func_v;
|
||||
std::vector<int> lua_el_mode_v;
|
||||
std::vector<LuaSmartRef> gameControllerEventHandlers;
|
||||
|
||||
public:
|
||||
int tpt_index(lua_State *l);
|
||||
@ -212,7 +213,7 @@ public:
|
||||
void custom_init_can_move();
|
||||
|
||||
void OnTick() override;
|
||||
bool HandleEvent(LuaEvents::EventTypes eventType, Event * event) override;
|
||||
bool HandleEvent(const GameControllerEvent &event) override;
|
||||
|
||||
void Init();
|
||||
void SetWindow(ui::Window * window);
|
||||
|
@ -6,7 +6,6 @@ powder_files = files(
|
||||
'Update.cpp',
|
||||
'PowderToySDL.cpp',
|
||||
'lua/CommandInterface.cpp',
|
||||
'lua/LuaEvents.cpp',
|
||||
'lua/TPTScriptInterface.cpp',
|
||||
'lua/TPTSTypes.cpp',
|
||||
)
|
||||
|
@ -4999,7 +4999,7 @@ void Simulation::BeforeSim()
|
||||
if (!sys_pause||framerender)
|
||||
{
|
||||
#ifdef LUACONSOLE
|
||||
luacon_ci->HandleEvent(LuaEvents::beforesim, new BeforeSimEvent());
|
||||
luacon_ci->HandleEvent(BeforeSimEvent{});
|
||||
#endif
|
||||
|
||||
air->update_air();
|
||||
@ -5204,7 +5204,7 @@ void Simulation::AfterSim()
|
||||
}
|
||||
|
||||
#ifdef LUACONSOLE
|
||||
luacon_ci->HandleEvent(LuaEvents::aftersim, new AfterSimEvent());
|
||||
luacon_ci->HandleEvent(AfterSimEvent{});
|
||||
#endif
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user