Skip to content

Commit 672cff5

Browse files
committed
Add script reading
Console will read scripts from resources/commands Also create Console class.
1 parent d36e618 commit 672cff5

File tree

8 files changed

+167
-16
lines changed

8 files changed

+167
-16
lines changed

apps/freeablo/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,7 @@ add_library(freeablo_lib # split into a library so I can link to it from tests
163163
fasavegame/gameloader.cpp
164164
)
165165

166-
target_link_libraries(freeablo_lib PUBLIC NuklearMisc Render Audio Serial Input Random enet cxxopts fmt::fmt)
166+
target_link_libraries(freeablo_lib PUBLIC NuklearMisc Render Audio Serial Input Random enet cxxopts fmt::fmt Script)
167167
target_include_directories(freeablo_lib PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
168168

169169
add_executable(freeablo main.cpp)

apps/freeablo/fagui/guimanager.cpp

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@
2323
#include <memory>
2424
#include <misc/misc.h>
2525
#include <misc/stringops.h>
26+
#include <script/console.h>
27+
#include <script/luascript.h>
2628
#include <serial/textstream.h>
2729
#include <string>
2830

@@ -532,29 +534,21 @@ namespace FAGui
532534

533535
void GuiManager::consolePanel(nk_context* ctx)
534536
{
535-
static constexpr size_t bufferSize = 1024 * 1024;
536-
static std::string boxBuffer;
537-
static int boxLen;
538-
static constexpr size_t inputSize = 512;
539-
static char input[inputSize];
540-
static int inputLen;
537+
auto& c = Script::Console::getInstance();
541538
drawPanel(ctx,
542539
PanelType::console,
543540
[&]() {
544541
nk_layout_space_begin(ctx, NK_STATIC, 0, INT_MAX);
545542
nk_layout_space_push(ctx, nk_rect(5, 5, 490, 250));
546-
nk_edit_string(ctx, NK_EDIT_BOX | NK_EDIT_READ_ONLY, const_cast<char*>(boxBuffer.c_str()), &boxLen, bufferSize, nk_filter_default);
543+
nk_edit_string(ctx, NK_EDIT_BOX | NK_EDIT_READ_ONLY, c->getBufferPtr(), c->getBufferLen(), c->getBuffer().length(), nk_filter_default);
547544
const int32_t height = FARender::Renderer::get()->smallFont()->height + 15;
548545
nk_layout_space_push(ctx, nk_rect(5, 270, 490, height));
549-
nk_flags active = nk_edit_string(ctx, NK_EDIT_FIELD | NK_EDIT_SIG_ENTER, input, &inputLen, inputSize, nk_filter_ascii);
546+
nk_flags active =
547+
nk_edit_string(ctx, NK_EDIT_FIELD | NK_EDIT_SIG_ENTER, c->getInput(), c->getInputLen(), c->getInputSize(), nk_filter_ascii);
550548

551549
if (active & NK_EDIT_COMMITED)
552550
{
553-
input[inputLen] = '\n';
554-
++inputLen;
555-
boxBuffer.append(input, inputLen);
556-
boxLen += inputLen;
557-
inputLen = 0;
551+
c->inputCommited();
558552
}
559553
nk_layout_space_end(ctx);
560554
},

components/CMakeLists.txt

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ add_library(DiabloExe
109109
diabloexe/characterstats.cpp
110110
diabloexe/affix.cpp
111111
diabloexe/affix.h
112-
diabloexe/talkdata.h)
112+
diabloexe/talkdata.h)
113113
target_link_libraries(DiabloExe Misc FAIO)
114114
set_target_properties(DiabloExe PROPERTIES COMPILE_FLAGS "${FA_COMPILER_FLAGS}")
115115

@@ -144,5 +144,18 @@ add_library(NuklearMisc
144144
nuklearmisc/standaloneguispritehandler.cpp
145145
nuklearmisc/standaloneguispritehandler.h
146146
)
147+
147148
set_target_properties(NuklearMisc PROPERTIES COMPILE_FLAGS "${FA_COMPILER_FLAGS}")
148149
target_link_libraries(NuklearMisc nuklear nativefiledialog Input Render)
150+
151+
add_library(Script
152+
script/luascript.cpp
153+
script/luascript.h
154+
script/console.cpp
155+
script/console.h
156+
)
157+
158+
find_package(Lua REQUIRED)
159+
160+
target_link_libraries(Script ${LUA_LIBRARIES} Filesystem)
161+
set_target_properties(Script PROPERTIES COMPILE_FLAGS "${FA_COMPILER_FLAGS}")

components/script/console.cpp

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
#include "console.h"
2+
#include "luascript.h"
3+
4+
#include <filesystem/resolver.h>
5+
#include <misc/stringops.h>
6+
7+
namespace Script
8+
{
9+
static std::string luaStdOut;
10+
std::unique_ptr<Console> Console::mInstance = nullptr;
11+
12+
Console::Console() : mBuffer({}), bufferLen(0), inputLen(0), mScript(LuaScript::getInstance()), mCommandsPath("resources/commands/")
13+
{
14+
// Hack. Redirects the print output to the console.
15+
mScript->registerGlobalFunction("print", [](lua_State* state) -> int {
16+
int n = lua_gettop(state);
17+
if (n >= 1)
18+
{
19+
for (int i = n; i > 0; --i)
20+
{
21+
const char* str = lua_tostring(state, -i);
22+
luaStdOut += str;
23+
}
24+
}
25+
26+
else
27+
{
28+
luaStdOut = "";
29+
}
30+
return 0;
31+
});
32+
}
33+
34+
std::unique_ptr<Console>& Console::getInstance()
35+
{
36+
if (!mInstance)
37+
{
38+
mInstance = std::unique_ptr<Console>(new Console());
39+
}
40+
41+
return mInstance;
42+
}
43+
44+
void Console::inputCommited()
45+
{
46+
std::string command = "";
47+
command.append(mInput, inputLen);
48+
mInput[inputLen] = '\n';
49+
++inputLen;
50+
mBuffer.append(mInput, inputLen);
51+
bufferLen += inputLen;
52+
inputLen = 0;
53+
54+
auto args = Misc::StringUtils::split(command, ' '); // TODO: parse args and pass them to the script
55+
filesystem::path scriptPath = filesystem::resolver().resolve(mCommandsPath / (args[0] + ".lua"));
56+
if (scriptPath.exists())
57+
{
58+
mScript->runScript(scriptPath.str());
59+
std::string msg = luaStdOut.empty() ? ">> nil\n" : (">> \"" + luaStdOut + "\"\n");
60+
mBuffer += msg;
61+
bufferLen += msg.length();
62+
luaStdOut = "";
63+
}
64+
65+
else
66+
{
67+
std::string msg = ">> Command '" + command + "' not found\n";
68+
mBuffer += msg;
69+
bufferLen += msg.length();
70+
luaStdOut = "";
71+
}
72+
}
73+
}

components/script/console.h

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
#pragma once
2+
3+
#include "luascript.h"
4+
5+
#include <filesystem/path.h>
6+
#include <memory>
7+
#include <string>
8+
9+
namespace Script
10+
{
11+
class Console
12+
{
13+
std::string mBuffer;
14+
int bufferLen;
15+
static constexpr size_t inputSize = 512;
16+
char mInput[inputSize];
17+
int inputLen;
18+
std::unique_ptr<LuaScript>& mScript;
19+
filesystem::path mCommandsPath;
20+
static std::unique_ptr<Console> mInstance;
21+
22+
public:
23+
static std::unique_ptr<Console>& getInstance();
24+
25+
char* getInput() { return mInput; };
26+
std::string& getBuffer() { return mBuffer; };
27+
char* getBufferPtr() const { return const_cast<char*>(mBuffer.c_str()); }
28+
int* getBufferLen() { return &bufferLen; }
29+
int* getInputLen() { return &inputLen; }
30+
constexpr size_t getInputSize() const { return inputSize; }
31+
32+
void inputCommited();
33+
34+
private:
35+
Console();
36+
};
37+
}

components/script/luascript.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
namespace Script
66
{
7+
std::unique_ptr<LuaScript> LuaScript::mInstance = nullptr;
78
LuaScript::LuaScript() : mState(luaL_newstate()) { luaL_openlibs(mState); }
89

910
LuaScript::~LuaScript()
@@ -12,6 +13,14 @@ namespace Script
1213
lua_close(mState);
1314
}
1415

16+
std::unique_ptr<LuaScript>& LuaScript::getInstance()
17+
{
18+
if (!mInstance)
19+
mInstance = std::unique_ptr<LuaScript>(new LuaScript());
20+
21+
return mInstance;
22+
}
23+
1524
void LuaScript::printError(const std::string& variable, const std::string& reason)
1625
{
1726
#ifndef NDEBUG
@@ -111,4 +120,16 @@ namespace Script
111120
exit(1);
112121
}
113122
}
123+
124+
void LuaScript::eval(const char* script)
125+
{
126+
lua_settop(mState, 0);
127+
128+
if (luaL_dostring(mState, script))
129+
{
130+
std::cerr << "Lua error: " << lua_tostring(mState, -1) << "\n";
131+
lua_pop(mState, 1);
132+
exit(1);
133+
}
134+
}
114135
}

components/script/luascript.h

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#include <misc/assert.h>
44

55
#include <iostream>
6+
#include <memory>
67
#include <string>
78
#include <vector>
89

@@ -14,15 +15,23 @@ namespace Script
1415
{
1516
lua_State* mState;
1617
int mLevel;
18+
static std::unique_ptr<LuaScript> mInstance;
1719

1820
public:
19-
LuaScript();
2021
~LuaScript();
2122

23+
static std::unique_ptr<LuaScript>& getInstance();
24+
2225
void printError(const std::string& variable, const std::string& reason);
2326

2427
template <typename T> void registerType(const std::string& metatable_name);
2528

29+
template <typename Func> void registerGlobalFunction(const std::string& functionName, Func func)
30+
{
31+
lua_pushcfunction(mState, func);
32+
lua_setglobal(mState, functionName.c_str());
33+
}
34+
2635
template <typename T> T get(const std::string& variable)
2736
{
2837
release_assert(mState);
@@ -74,8 +83,11 @@ namespace Script
7483
}
7584

7685
void runScript(const std::string& path);
86+
void eval(const char* script);
7787

7888
private:
89+
LuaScript();
90+
7991
bool luaGetToStack(const std::string& variable);
8092

8193
void clean();

resources/commands/hello.lua

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
print("ola mundo", 1)

0 commit comments

Comments
 (0)