Skip to content

Commit e7e8960

Browse files
authored
Merge pull request #38 from aiekick/debugger
Debugger
2 parents 4741830 + e9b4d48 commit e7e8960

140 files changed

Lines changed: 1833 additions & 50527 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

3rdparty/ezlibs

CMakeLists.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -282,7 +282,6 @@ if (EXISTS ${CMAKE_BINARY_DIR}/current_build_type)
282282
add_custom_command(
283283
TARGET ${PROJECT} PRE_BUILD
284284
COMMAND echo "${PROJECT}_${CMAKE_SYSTEM_NAME}_${PROJECT_BUILD_CONFIG_NAME}_${ARCH}_v${MajorNumber}.${MinorNumber}.${BuildNumber}" > ${CMAKE_SOURCE_DIR}/VERSION
285-
DEPENDS ${PROJECT}
286285
)
287286

288287
#############################################################

VERSION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
LogToGraph_Windows_Debug_x64_v0.3.3629
1+
LogToGraph_Windows_Release_x64_v0.3.3629

apis/IScriptDebugger.h

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
/*
2+
Copyright 2022-2026 Stephane Cuillerdier (aka aiekick)
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
#pragma once
18+
#pragma warning(disable : 4251)
19+
20+
#include <string>
21+
#include <vector>
22+
#include <cstdint>
23+
#include <unordered_set>
24+
25+
namespace Ltg {
26+
27+
// Common debugger contract shared by the host and every scripting plugin.
28+
//
29+
// Line-number convention: every line number here (DebugFrame::line,
30+
// DebugState::line, and the entries of BreakpointLines) is 1-based, i.e. the
31+
// number Lua reports through lua_getinfo("l") and the number the user sees in
32+
// the editor gutter. The 0-based <-> 1-based conversion to the TextEditor
33+
// widget happens in the CodeEditor, not here.
34+
35+
// The control command the host hands back to the paused plugin.
36+
enum class DebugCommand {
37+
Continue, // resume until the next breakpoint
38+
StepInto, // stop on the next executed line, entering called functions
39+
StepOver, // stop on the next line at the same call depth
40+
StepOut, // stop after the current function returns
41+
Stop // abort the current script execution
42+
};
43+
44+
// One inspected value: a stack local/upvalue, a global, or a table entry.
45+
// Values are stringified by the plugin (the host cannot read a Lua TValue). A
46+
// table exposes a non-negative `ref` (a Lua registry reference) so the UI can
47+
// expand it lazily; scalars/functions/userdata stay leaves with ref == -1.
48+
struct DebugVar {
49+
std::string name;
50+
std::string keyType; // type of the key ("none" for stack locals/upvalues)
51+
std::string typeName; // type of the value
52+
std::string value; // stringified value (address for table/function)
53+
int32_t ref = -1; // Lua registry ref when expandable, else -1
54+
};
55+
56+
// One call-stack frame; carries its own locals and upvalues (roots only, lazy).
57+
struct DebugFrame {
58+
std::string function;
59+
std::string source;
60+
int32_t line = 0;
61+
std::vector<DebugVar> locals;
62+
std::vector<DebugVar> upvalues;
63+
};
64+
65+
// Immutable snapshot of the paused state. Only roots are captured up front;
66+
// tables are expanded on demand through their `ref`. It holds no pointer into
67+
// the runtime, so it is safe to read from the UI thread.
68+
struct DebugState {
69+
std::string sourceFile;
70+
int32_t line = 0;
71+
int32_t logRowIndex = 0;
72+
std::vector<DebugFrame> callStack; // innermost frame first; each frame holds its vars
73+
std::vector<DebugVar> globals; // top-level _G entries (no filter)
74+
};
75+
76+
// Set of breakpoint lines (1-based) for the active script.
77+
using BreakpointLines = std::unordered_set<int32_t>;
78+
79+
// What the paused plugin should do next: resume with a command, or read the
80+
// children of an expandable node before resuming.
81+
struct DebugAction {
82+
enum class Kind { Command, Expand };
83+
Kind kind = Kind::Command;
84+
DebugCommand command = DebugCommand::Continue; // when kind == Command
85+
int32_t expandRef = -1; // when kind == Expand (a registry ref)
86+
};
87+
88+
// Implemented by the host (ScriptDebugger), called by the plugin from the worker
89+
// thread. The plugin loops:
90+
// action = onPause(state)
91+
// while action is Expand: publishExpansion(ref, children); action = waitAction()
92+
// apply action.command
93+
struct IScriptDebugHost {
94+
virtual ~IScriptDebugHost() = default;
95+
// publish the paused snapshot (roots) and block until the first action
96+
virtual DebugAction onPause(const DebugState& aState) = 0;
97+
// block until the next action (after an expansion has been handled)
98+
virtual DebugAction waitAction() = 0;
99+
// publish the lazily-read children of an expandable node (non-blocking)
100+
virtual void publishExpansion(int32_t aRef, const std::vector<DebugVar>& aChildren) = 0;
101+
// queried by the plugin hook on each line: is there a breakpoint on this line ?
102+
// live + thread-safe, so add/remove during a session takes effect immediately
103+
virtual bool isBreakpoint(int32_t aLine) = 0;
104+
};
105+
106+
// Implemented by the plugin (extended by ScriptingModule), called by the host from
107+
// the UI thread. Default no-ops so a scripting plugin that does not support
108+
// debugging compiles unchanged (e.g. PythonScripting); the Lua plugin overrides them.
109+
struct IScriptDebugger {
110+
virtual ~IScriptDebugger() = default;
111+
virtual void enableDebug(IScriptDebugHost* /*apHost*/) {}
112+
virtual void disableDebug() {}
113+
virtual void setBreakpoints(const BreakpointLines& /*aLines*/) {}
114+
virtual void requestPause() {}
115+
virtual void requestStop() {}
116+
};
117+
118+
} // namespace Ltg

apis/LtgPluginApi.h

Lines changed: 17 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,13 @@ limitations under the License.
2424
#include <array>
2525
#include <map>
2626

27-
#include "ILayoutPane.h"
28-
#include <ezlibs/ezXml.hpp>
27+
// The plugin API is deliberately ImGui-free: plugins are pure modules (scripting + data) and link
28+
// no imguipack/glad/glfw. The host owns all UI. The only host objects a plugin borrows are
29+
// forwarded by pointer/interface at instantiation (ez::Log via init(), IDatasModel via load(),
30+
// IScriptDebugHost via enableDebug()). This is what lets LogToGraph build fully static. The host
31+
// settings-dialog interface (ISettings) is NOT here anymore — it moved to src/systems/ISettings.h
32+
// since plugins no longer provide settings.
33+
#include "IScriptDebugger.h"
2934

3035
namespace ez {
3136
class Log;
@@ -44,46 +49,6 @@ class IProject {
4449
typedef std::shared_ptr<IProject> IProjectPtr;
4550
typedef std::weak_ptr<IProject> IProjectWeak;
4651

47-
struct PluginPane : public virtual ILayoutPane {
48-
bool init() override = 0; // return false if the init was failed
49-
void unit() override = 0;
50-
51-
// the return, is a user side use case here
52-
bool drawPanes(bool* apOpened, LayoutPaneUserDatas apUserDatas) override = 0;
53-
bool drawWidgets(LayoutPaneUserDatas /*apUserDatas*/) override { return false; }
54-
bool drawOverlays(const ImRect& /*aRect*/, LayoutPaneUserDatas /*apUserDatas*/) override { return false; }
55-
bool drawDialogsAndPopups(const ImRect& /*aRect*/, LayoutPaneUserDatas /*apUserDatas*/) override { return false; }
56-
57-
// if for any reason the pane must be hidden temporary, the user can control this here
58-
virtual bool canBeDisplayed() override = 0;
59-
60-
virtual void SetProjectInstance(IProjectWeak vProjectInstance) = 0;
61-
};
62-
63-
struct PluginPaneConfig {
64-
ILayoutPaneWeak pane;
65-
std::string name;
66-
std::string category;
67-
std::string disposal = "CENTRAL";
68-
float disposalRatio = 0.0f;
69-
bool openedDefault = false;
70-
bool focusedDefault = false;
71-
};
72-
73-
typedef std::string SettingsCategoryPath;
74-
enum class ISettingsType {
75-
NONE = 0,
76-
APP, // common for all users
77-
PROJECT // user specific
78-
};
79-
80-
struct IXmlSettings {
81-
// will be called by the saver
82-
virtual ez::xml::Nodes getXmlSettings(const ISettingsType& vType) const = 0;
83-
// will be called by the loader
84-
virtual void setXmlSettings(const ez::xml::Node& vName, const ez::xml::Node& vParent, const std::string& vValue, const ISettingsType& vType) = 0;
85-
};
86-
8752
struct PluginParam {
8853
std::string name;
8954
enum class Type { NUM, STRING } type = Type::NUM;
@@ -117,21 +82,6 @@ struct PluginModuleInfos {
11782
: path(vPath), label(vLabel), type(vType), color(vColor) {}
11883
};
11984

120-
struct ISettings : public IXmlSettings {
121-
virtual ~ISettings() = default;
122-
// get the category path of the settings for the mebnu display. ex: "plugins/apis"
123-
virtual SettingsCategoryPath getCategory() const = 0;
124-
// will be called by the loader for inform the pluign than he must load somethings if any
125-
virtual bool loadSettings() = 0;
126-
// will be called by the saver for inform the pluign than he must save somethings if any, by ex: temporary vars
127-
virtual bool saveSettings() = 0;
128-
// will draw custom settings via imgui
129-
virtual bool drawSettings() = 0;
130-
};
131-
132-
typedef std::shared_ptr<ISettings> ISettingsPtr;
133-
typedef std::weak_ptr<ISettings> ISettingsWeak;
134-
13585
typedef std::string ScriptFilePathName;
13686

13787
struct ScriptingError {
@@ -163,14 +113,21 @@ struct ScriptingDatas {
163113
std::string buffer;
164114
};
165115
typedef std::string ScriptingModuleName;
166-
struct ScriptingModule : public PluginModule {
116+
struct ScriptingModule : public PluginModule, public IScriptDebugger {
167117
virtual ~ScriptingModule() = default;
168118
// will load the related scripting engine
169119
virtual bool load(IDatasModelWeak vDatasModel) = 0;
170120
// will unload the related scripting engine
171121
virtual void unload() = 0;
172-
// will compile the script and return errors
122+
// will compile the script from a file path and return errors
173123
virtual bool compileScript(const ScriptFilePathName& vFilePathName, ErrorContainer& vOutErrors) = 0;
124+
// will compile the script from in-memory code (project script stored in the .ltg db).
125+
// default no-op so plugins that only support file-based scripts compile unchanged.
126+
virtual bool compileScriptCode(const std::string& aCode, ErrorContainer& aOutErrors) {
127+
(void)aCode;
128+
(void)aOutErrors;
129+
return false;
130+
}
174131
// will call the start function from script and return errors
175132
virtual bool callScriptStart(ErrorContainer& vOutErrors) = 0;
176133
// will call the exec function from script with a buffer and return errors
@@ -186,11 +143,6 @@ struct ScriptingModule : public PluginModule {
186143
typedef std::shared_ptr<ScriptingModule> ScriptingModulePtr;
187144
typedef std::weak_ptr<ScriptingModule> ScriptingModuleWeak;
188145

189-
struct PluginSettingsConfig {
190-
ISettingsWeak settings;
191-
PluginSettingsConfig(ISettingsWeak vSertings) : settings(vSertings) {}
192-
};
193-
194146
struct PluginInterface {
195147
virtual ~PluginInterface() = default;
196148
virtual bool init(ez::Log* vLoggerInstancePtr) = 0;
@@ -206,8 +158,6 @@ struct PluginInterface {
206158
virtual std::string getDescription() const = 0;
207159
virtual std::vector<PluginModuleInfos> getModulesInfos() const = 0;
208160
virtual PluginModulePtr createModule(const std::string& vPluginModuleName, Ltg::PluginBridge* vBridgePtr) = 0;
209-
virtual std::vector<PluginPaneConfig> getPanes() const = 0;
210-
virtual std::vector<PluginSettingsConfig> getSettings() const = 0;
211161
};
212162

213-
} // namespace Ltg
163+
} // namespace Ltg

plugins/LuaScripting/CMakeLists.txt

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ set(CMAKE_CXX_STANDARD 17)
2020
set(CMAKE_CXX_STANDARD_REQUIRED ON)
2121
set(CMAKE_CXX_EXTENSIONS OFF)
2222

23-
add_definitions(-DUSE_DECORATIONS_FOR_RESIZE_CHILD_WINDOWS) ## for the resize imgui issue when we have child glfw windows
2423

2524
if (uninstall)
2625
set_target_properties(uninstall PROPERTIES FOLDER "CmakeTargets")
@@ -75,13 +74,8 @@ else()
7574
endif()
7675

7776
set_target_properties(${PROJECT} PROPERTIES OUTPUT_NAME "${PROJECT}")
78-
## these defines mirror USE_SHARED_LIBS from the root CMake — only emit them when
79-
## imguipack is actually built as a DLL, otherwise IMGUI_API resolves to dllimport
80-
## against a static lib and ImGui::Header (and friends) end up unresolved.
81-
if (USE_SHARED_LIBS)
82-
target_compile_definitions(${PROJECT} PRIVATE BUILD_CTOOLS_SHARED_LIBS)
83-
target_compile_definitions(${PROJECT} PRIVATE BUILD_IMGUI_PACK_SHARED_LIBS)
84-
endif()
77+
## the plugin links no imguipack/glad/glfw anymore (pure Lua module), so the root
78+
## BUILD_*_SHARED_LIBS / IMGUI_API mirror is no longer needed here.
8579

8680
## sol2 config — MUST be visible to every TU before the first <sol/sol.hpp>:
8781
## - SOL_ALL_SAFETIES_ON=1 : full runtime safety checks (arg counts, types, …)
@@ -125,16 +119,12 @@ target_include_directories(${PROJECT} PRIVATE
125119
${CMAKE_CURRENT_SOURCE_DIR}/src
126120
${CMAKE_CURRENT_SOURCE_DIR}
127121
${LUA_JIT_INCLUDE_DIR}/src
128-
${IMGUIPACK_INCLUDE_DIRS}
129122
${EZLIBS_INCLUDE_DIR}
130-
${GLAD_INCLUDE_DIR} ## CustomInAppGpuProfiler.h (consumed via add_definitions) pulls glad+glfw
131-
${GLFW_INCLUDE_DIR}
132123
${CMAKE_SOURCE_DIR}
133124
${SOL2_INCLUDE_DIR}
134125
)
135126

136127
target_link_libraries(${PROJECT}
137-
${IMGUIPACK_LIBRARIES}
138128
${LUA_JIT_LIBRARIES}
139129
${SOL2_LIBRARIES}
140130
)

plugins/LuaScripting/src/LuaScripting.cpp

Lines changed: 1 addition & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -29,15 +29,13 @@ PLUGIN_PREFIX void deleter(LuaScripting* ptr) {
2929
LuaScripting::LuaScripting() = default;
3030

3131
bool LuaScripting::init(ez::Log* vLoggerInstancePtr) {
32-
m_SettingsPtr = std::make_shared<Settings>();
3332
// borrow the host's ez::Log so every LogVar* call from this DLL routes through
3433
// the host's standardLogFunctor (which pushes into the Messaging pane)
3534
ez::Log::initSingleton(vLoggerInstancePtr);
3635
return true;
3736
}
3837

3938
void LuaScripting::unit() {
40-
m_SettingsPtr.reset();
4139
ez::Log::unitSingleton(); // only releases the borrow — does NOT delete the host instance
4240
}
4341

@@ -85,18 +83,7 @@ std::vector<Ltg::PluginModuleInfos> LuaScripting::getModulesInfos() const {
8583

8684
Ltg::PluginModulePtr LuaScripting::createModule(const std::string& vPluginModuleName, Ltg::PluginBridge* vBridgePtr) {
8785
if (vPluginModuleName == "Lua") {
88-
return Module::create(m_SettingsPtr);
86+
return Module::create();
8987
}
9088
return nullptr;
9189
}
92-
93-
std::vector<Ltg::PluginPaneConfig> LuaScripting::getPanes() const {
94-
std::vector<Ltg::PluginPaneConfig> res;
95-
return res;
96-
}
97-
98-
std::vector<Ltg::PluginSettingsConfig> LuaScripting::getSettings() const {
99-
std::vector<Ltg::PluginSettingsConfig> res;
100-
res.push_back(Ltg::PluginSettingsConfig(m_SettingsPtr));
101-
return res;
102-
}

plugins/LuaScripting/src/LuaScripting.h

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,8 @@
11
#pragma once
22

33
#include <apis/LtgPluginApi.h>
4-
#include <Settings/Settings.h>
54

65
class LuaScripting : public Ltg::PluginInterface {
7-
private:
8-
SettingsPtr m_SettingsPtr = nullptr; // common eettings for whole module
9-
106
public:
117
LuaScripting();
128
virtual ~LuaScripting() = default;
@@ -23,6 +19,4 @@ class LuaScripting : public Ltg::PluginInterface {
2319
std::string getDescription() const override;
2420
std::vector<Ltg::PluginModuleInfos> getModulesInfos() const override;
2521
Ltg::PluginModulePtr createModule(const std::string& vPluginModuleName, Ltg::PluginBridge* vBridgePtr) override;
26-
std::vector<Ltg::PluginPaneConfig> getPanes() const override;
27-
std::vector<Ltg::PluginSettingsConfig> getSettings() const override;
28-
};
22+
};

0 commit comments

Comments
 (0)