Merge pull request 'feat/editor-refinements' (#6) from feat/editor-refinements into main
All checks were successful
CI / build-and-test (push) Successful in 2m18s
All checks were successful
CI / build-and-test (push) Successful in 2m18s
Reviewed-on: #6
This commit was merged in pull request #6.
This commit is contained in:
@@ -34,3 +34,6 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
cd build
|
cd build
|
||||||
ctest --output-on-failure -j $(nproc)
|
ctest --output-on-failure -j $(nproc)
|
||||||
|
|
||||||
|
- name: Build application
|
||||||
|
run: cmake --build build --target simian -j $(nproc)
|
||||||
|
|||||||
20
.vscode/settings.json
vendored
20
.vscode/settings.json
vendored
@@ -72,6 +72,24 @@
|
|||||||
"typeinfo": "cpp",
|
"typeinfo": "cpp",
|
||||||
"variant": "cpp",
|
"variant": "cpp",
|
||||||
"format": "cpp",
|
"format": "cpp",
|
||||||
"*.m": "cpp"
|
"*.m": "cpp",
|
||||||
|
"filesystem": "cpp",
|
||||||
|
"forward_list": "cpp",
|
||||||
|
"ios": "cpp",
|
||||||
|
"locale": "cpp",
|
||||||
|
"xfacet": "cpp",
|
||||||
|
"xhash": "cpp",
|
||||||
|
"xiosbase": "cpp",
|
||||||
|
"xlocale": "cpp",
|
||||||
|
"xlocbuf": "cpp",
|
||||||
|
"xlocinfo": "cpp",
|
||||||
|
"xlocmes": "cpp",
|
||||||
|
"xlocmon": "cpp",
|
||||||
|
"xlocnum": "cpp",
|
||||||
|
"xloctime": "cpp",
|
||||||
|
"xmemory": "cpp",
|
||||||
|
"xtr1common": "cpp",
|
||||||
|
"xtree": "cpp",
|
||||||
|
"xutility": "cpp"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -78,6 +78,7 @@ add_executable(simian
|
|||||||
src/ScriptBindings.cpp
|
src/ScriptBindings.cpp
|
||||||
src/HotReload.cpp
|
src/HotReload.cpp
|
||||||
src/GuiManager.cpp
|
src/GuiManager.cpp
|
||||||
|
src/LogWindow.cpp
|
||||||
src/log/log.c
|
src/log/log.c
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
96
imgui.ini
96
imgui.ini
@@ -1,78 +1,42 @@
|
|||||||
[Window][Debug##Default]
|
|
||||||
Pos=60,60
|
|
||||||
Size=400,400
|
|
||||||
Collapsed=0
|
|
||||||
|
|
||||||
[Window][Simian ImGui Demo]
|
|
||||||
Pos=141,224
|
|
||||||
Size=516,224
|
|
||||||
Collapsed=0
|
|
||||||
|
|
||||||
[Window][DockSpaceHost]
|
[Window][DockSpaceHost]
|
||||||
Pos=0,0
|
Pos=0,0
|
||||||
Size=1280,720
|
Size=1280,720
|
||||||
Collapsed=0
|
Collapsed=0
|
||||||
|
|
||||||
[Window][Left Panel]
|
[Window][Debug##Default]
|
||||||
Pos=292,567
|
Pos=384,193
|
||||||
Size=980,145
|
Size=400,400
|
||||||
Collapsed=0
|
Collapsed=0
|
||||||
DockId=0x00000002,0
|
|
||||||
|
|
||||||
[Window][Right Panel]
|
|
||||||
Pos=8,27
|
|
||||||
Size=282,685
|
|
||||||
Collapsed=0
|
|
||||||
DockId=0x00000003,0
|
|
||||||
|
|
||||||
[Window][##TOAST2]
|
|
||||||
Pos=548,314
|
|
||||||
Size=232,82
|
|
||||||
Collapsed=0
|
|
||||||
|
|
||||||
[Window][##TOAST1]
|
|
||||||
Pos=548,406
|
|
||||||
Size=232,82
|
|
||||||
Collapsed=0
|
|
||||||
|
|
||||||
[Window][##TOAST0]
|
|
||||||
Pos=548,498
|
|
||||||
Size=232,82
|
|
||||||
Collapsed=0
|
|
||||||
|
|
||||||
[Window][##TOAST4]
|
|
||||||
Pos=548,130
|
|
||||||
Size=232,82
|
|
||||||
Collapsed=0
|
|
||||||
|
|
||||||
[Window][##TOAST3]
|
|
||||||
Pos=548,222
|
|
||||||
Size=232,82
|
|
||||||
Collapsed=0
|
|
||||||
|
|
||||||
[Window][##TOAST5]
|
|
||||||
Pos=548,38
|
|
||||||
Size=232,82
|
|
||||||
Collapsed=0
|
|
||||||
|
|
||||||
[Window][Log Viewer]
|
|
||||||
Pos=8,580
|
|
||||||
Size=1264,132
|
|
||||||
Collapsed=0
|
|
||||||
DockId=0x00000006,0
|
|
||||||
|
|
||||||
[Window][Game Window]
|
[Window][Game Window]
|
||||||
Pos=8,27
|
Pos=8,29
|
||||||
Size=1264,551
|
Size=1264,513
|
||||||
Collapsed=0
|
Collapsed=0
|
||||||
DockId=0x00000001,0
|
DockId=0x00000001,0
|
||||||
|
|
||||||
[Docking][Data]
|
[Window][Log Viewer]
|
||||||
DockSpace ID=0x9076BACA Window=0x34F970D7 Pos=8,27 Size=1264,685 Split=Y Selected=0x6D1308E5
|
Pos=8,544
|
||||||
DockNode ID=0x00000005 Parent=0x9076BACA SizeRef=1264,551 Split=X
|
Size=1264,168
|
||||||
DockNode ID=0x00000003 Parent=0x00000005 SizeRef=282,685 Selected=0x6D1308E5
|
Collapsed=0
|
||||||
DockNode ID=0x00000004 Parent=0x00000005 SizeRef=980,685 Split=Y
|
DockId=0x00000002,0
|
||||||
DockNode ID=0x00000001 Parent=0x00000004 SizeRef=1264,538 CentralNode=1 Selected=0x27A02DAA
|
|
||||||
DockNode ID=0x00000002 Parent=0x00000004 SizeRef=1264,145 Selected=0x995FC207
|
[Window][##TOAST0]
|
||||||
DockNode ID=0x00000006 Parent=0x9076BACA SizeRef=1264,132 Selected=0xBEDDA0C1
|
Pos=1010,635
|
||||||
|
Size=250,65
|
||||||
|
Collapsed=0
|
||||||
|
|
||||||
|
[Window][##TOAST1]
|
||||||
|
Pos=1010,543
|
||||||
|
Size=250,65
|
||||||
|
Collapsed=0
|
||||||
|
|
||||||
|
[Window][##TOAST2]
|
||||||
|
Pos=982,485
|
||||||
|
Size=278,65
|
||||||
|
Collapsed=0
|
||||||
|
|
||||||
|
[Docking][Data]
|
||||||
|
DockSpace ID=0x9076BACA Window=0x34F970D7 Pos=8,29 Size=1264,683 Split=Y Selected=0x27A02DAA
|
||||||
|
DockNode ID=0x00000001 Parent=0x9076BACA SizeRef=1264,513 CentralNode=1 Selected=0x27A02DAA
|
||||||
|
DockNode ID=0x00000002 Parent=0x9076BACA SizeRef=1264,168 Selected=0xBEDDA0C1
|
||||||
|
|
||||||
|
|||||||
@@ -13,6 +13,9 @@ public:
|
|||||||
void Run();
|
void Run();
|
||||||
void Shutdown();
|
void Shutdown();
|
||||||
|
|
||||||
|
bool IsEditorEnabled() const { return enableEditor; }
|
||||||
|
bool HasScriptCompilationError() const { return scriptCompilationError; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ScriptEngine scriptEngine;
|
ScriptEngine scriptEngine;
|
||||||
HotReload* hotReload;
|
HotReload* hotReload;
|
||||||
@@ -20,7 +23,7 @@ private:
|
|||||||
FILE* logFile;
|
FILE* logFile;
|
||||||
GuiManager guiManager;
|
GuiManager guiManager;
|
||||||
bool enableEditor;
|
bool enableEditor;
|
||||||
RenderTexture2D renderTexture; // Declare renderTexture for Raylib rendering
|
RenderTexture2D renderTexture; // renderTexture for Raylib rendering
|
||||||
|
|
||||||
static const int WINDOW_WIDTH = 1280;
|
static const int WINDOW_WIDTH = 1280;
|
||||||
static const int WINDOW_HEIGHT = 720;
|
static const int WINDOW_HEIGHT = 720;
|
||||||
|
|||||||
@@ -4,17 +4,26 @@
|
|||||||
#include "extras/IconsFontAwesome6.h"
|
#include "extras/IconsFontAwesome6.h"
|
||||||
#include "gui/fa-solid-900.h"
|
#include "gui/fa-solid-900.h"
|
||||||
#include "gui/ImGuiNotify.hpp"
|
#include "gui/ImGuiNotify.hpp"
|
||||||
|
#include "LogWindow.h" // Include the new LogWindow class
|
||||||
|
|
||||||
|
class Application;
|
||||||
|
|
||||||
class GuiManager {
|
class GuiManager {
|
||||||
public:
|
public:
|
||||||
GuiManager();
|
GuiManager();
|
||||||
~GuiManager();
|
~GuiManager();
|
||||||
|
|
||||||
void Initialize();
|
void Initialize(Application* application);
|
||||||
void Render(RenderTexture2D& renderTexture);
|
void Render(RenderTexture2D& renderTexture);
|
||||||
void Shutdown();
|
void Shutdown();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void SetupDockspace(RenderTexture2D& renderTexture);
|
void SetupDockspace(RenderTexture2D& renderTexture);
|
||||||
void RenderNotifications();
|
void RenderNotifications();
|
||||||
|
void RenderErrorBanner();
|
||||||
|
void SetTheme();
|
||||||
|
|
||||||
|
bool showLogWindow = true;
|
||||||
|
Application *app;
|
||||||
|
LogWindow logWindow; // Add LogWindow as a member
|
||||||
};
|
};
|
||||||
20
include/LogWindow.h
Normal file
20
include/LogWindow.h
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "imgui.h"
|
||||||
|
#include "log.h"
|
||||||
|
#include <vector>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
struct LogEntry {
|
||||||
|
std::string message;
|
||||||
|
ImVec4 color;
|
||||||
|
};
|
||||||
|
|
||||||
|
class LogWindow {
|
||||||
|
public:
|
||||||
|
void Initialize();
|
||||||
|
void Render(bool& showLogWindow);
|
||||||
|
static void LogCallback(log_Event* ev);
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::vector<LogEntry> logEntries;
|
||||||
|
};
|
||||||
@@ -155,10 +155,10 @@ public:
|
|||||||
*
|
*
|
||||||
* @param type The type of the toast notification.
|
* @param type The type of the toast notification.
|
||||||
*/
|
*/
|
||||||
inline void setType(const ImGuiToastType &type)
|
inline void setType(const ImGuiToastType &typ)
|
||||||
{
|
{
|
||||||
IM_ASSERT(type < ImGuiToastType::COUNT);
|
IM_ASSERT(typ < ImGuiToastType::COUNT);
|
||||||
this->type = type;
|
this->type = typ;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -166,9 +166,9 @@ public:
|
|||||||
*
|
*
|
||||||
* @param flags ImGui window flags to set.
|
* @param flags ImGui window flags to set.
|
||||||
*/
|
*/
|
||||||
inline void setWindowFlags(const ImGuiWindowFlags &flags)
|
inline void setWindowFlags(const ImGuiWindowFlags &flgs)
|
||||||
{
|
{
|
||||||
this->flags = flags;
|
this->flags = flgs;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -176,9 +176,9 @@ public:
|
|||||||
*
|
*
|
||||||
* @param onButtonPress std::fuction or lambda expression, which contains the code for execution.
|
* @param onButtonPress std::fuction or lambda expression, which contains the code for execution.
|
||||||
*/
|
*/
|
||||||
inline void setOnButtonPress(const std::function<void()> &onButtonPress)
|
inline void setOnButtonPress(const std::function<void()> &onBtnPress)
|
||||||
{
|
{
|
||||||
this->onButtonPress = onButtonPress;
|
this->onButtonPress = onBtnPress;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -564,7 +564,7 @@ namespace ImGui
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Set notification window flags
|
// Set notification window flags
|
||||||
if (!NOTIFY_USE_DISMISS_BUTTON && currentToast->getOnButtonPress() == nullptr)
|
if constexpr (!NOTIFY_USE_DISMISS_BUTTON && currentToast->getOnButtonPress() == nullptr)
|
||||||
{
|
{
|
||||||
currentToast->setWindowFlags(NOTIFY_DEFAULT_TOAST_FLAGS | ImGuiWindowFlags_NoInputs);
|
currentToast->setWindowFlags(NOTIFY_DEFAULT_TOAST_FLAGS | ImGuiWindowFlags_NoInputs);
|
||||||
}
|
}
|
||||||
@@ -630,7 +630,7 @@ namespace ImGui
|
|||||||
// If the button is pressed, we want to remove the notification
|
// If the button is pressed, we want to remove the notification
|
||||||
if (Button(ICON_FA_XMARK))
|
if (Button(ICON_FA_XMARK))
|
||||||
{
|
{
|
||||||
RemoveNotification(i);
|
RemoveNotification(static_cast<int>(i));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
57
include/gui/Toast.h
Normal file
57
include/gui/Toast.h
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "gui/ImGuiNotify.hpp"
|
||||||
|
#include <string>
|
||||||
|
#include <string_view>
|
||||||
|
#include <vector>
|
||||||
|
#include <cstdio>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
class Toast
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
template <typename... Args>
|
||||||
|
static void Info(std::string_view fmt, Args&&... args)
|
||||||
|
{
|
||||||
|
ImGui::InsertNotification({ImGuiToastType::Info, 3000, Format(fmt, std::forward<Args>(args)...).c_str()});
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename... Args>
|
||||||
|
static void Warning(std::string_view fmt, Args&&... args)
|
||||||
|
{
|
||||||
|
ImGui::InsertNotification({ImGuiToastType::Warning, 4000, Format(fmt, std::forward<Args>(args)...).c_str()});
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename... Args>
|
||||||
|
static void Error(std::string_view fmt, Args&&... args)
|
||||||
|
{
|
||||||
|
ImGui::InsertNotification({ImGuiToastType::Error, 5000, Format(fmt, std::forward<Args>(args)...).c_str()});
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename... Args>
|
||||||
|
static void Success(std::string_view fmt, Args&&... args)
|
||||||
|
{
|
||||||
|
ImGui::InsertNotification({ImGuiToastType::Success, 2500, Format(fmt, std::forward<Args>(args)...).c_str()});
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
template <typename... Args>
|
||||||
|
static std::string Format(std::string_view fmt, Args&&... args)
|
||||||
|
{
|
||||||
|
if constexpr (sizeof...(Args) == 0)
|
||||||
|
{
|
||||||
|
return std::string(fmt);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::string format(fmt);
|
||||||
|
int size = std::snprintf(nullptr, 0, format.c_str(), std::forward<Args>(args)...) + 1;
|
||||||
|
if (size <= 0)
|
||||||
|
return std::string(fmt);
|
||||||
|
|
||||||
|
std::vector<char> buffer(static_cast<size_t>(size));
|
||||||
|
std::snprintf(buffer.data(), static_cast<size_t>(size), format.c_str(), std::forward<Args>(args)...);
|
||||||
|
return std::string(buffer.data());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -1,11 +1,17 @@
|
|||||||
|
|
||||||
typedef void string;
|
typedef void string;
|
||||||
void Print(const string &in);
|
void Print(const string&in);
|
||||||
void Log(int level, const string &in);
|
void Log(int level, const string&in);
|
||||||
void DrawText(const string &in, int x, int y, int fontSize, int color);
|
void DrawText(const string&in, int x, int y, int fontSize, int color);
|
||||||
int LOG_TRACE;
|
int LOG_TRACE;
|
||||||
int LOG_DEBUG;
|
int LOG_DEBUG;
|
||||||
int LOG_INFO;
|
int LOG_INFO;
|
||||||
int LOG_WARN;
|
int LOG_WARNING;
|
||||||
int LOG_ERROR;
|
int LOG_ERROR;
|
||||||
int LOG_FATAL;
|
int LOG_FATAL;
|
||||||
|
|
||||||
|
namespace Toast {
|
||||||
|
void Info(const string&in);
|
||||||
|
void Warning(const string&in);
|
||||||
|
void Error(const string&in);
|
||||||
|
void Success(const string&in);
|
||||||
|
}
|
||||||
|
|||||||
@@ -2,10 +2,11 @@ float x = 50;
|
|||||||
float y = 100;
|
float y = 100;
|
||||||
|
|
||||||
void Update(float dt) {
|
void Update(float dt) {
|
||||||
x += 50 * dt;
|
x += 64 * dt;
|
||||||
if (x > 800) {
|
if (x > 800) {
|
||||||
x = 0;
|
x = 0;
|
||||||
Print("X position reset!");
|
Print("X position reset!");
|
||||||
Log(LOG_INFO, "Log INFO: reset happened");
|
Log(LOG_INFO, "Log INFO: reset happened");
|
||||||
|
Toast::Info("X position has been reset.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,6 +11,7 @@
|
|||||||
#include "extras/IconsFontAwesome6.h"
|
#include "extras/IconsFontAwesome6.h"
|
||||||
#include "gui/ImGuiNotify.hpp"
|
#include "gui/ImGuiNotify.hpp"
|
||||||
#include "GuiManager.h"
|
#include "GuiManager.h"
|
||||||
|
#include "gui/Toast.h"
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
// On Windows, fopen_s is already available, so no need to define it.
|
// On Windows, fopen_s is already available, so no need to define it.
|
||||||
@@ -19,7 +20,7 @@
|
|||||||
#define fopen_s(pFile, filename, mode) ((*(pFile) = fopen((filename), (mode))) == NULL)
|
#define fopen_s(pFile, filename, mode) ((*(pFile) = fopen((filename), (mode))) == NULL)
|
||||||
#endif
|
#endif
|
||||||
const char *Application::WINDOW_TITLE = "Simian";
|
const char *Application::WINDOW_TITLE = "Simian";
|
||||||
const char *Application::SCRIPT_FILE = "scripts/test.as";
|
const char *Application::SCRIPT_FILE = "scripts/game.as";
|
||||||
|
|
||||||
Application::Application() : hotReload(nullptr), scriptCompilationError(false), logFile(nullptr), renderTexture{} // Initialize renderTexture
|
Application::Application() : hotReload(nullptr), scriptCompilationError(false), logFile(nullptr), renderTexture{} // Initialize renderTexture
|
||||||
{
|
{
|
||||||
@@ -27,7 +28,7 @@ Application::Application() : hotReload(nullptr), scriptCompilationError(false),
|
|||||||
|
|
||||||
Application::~Application()
|
Application::~Application()
|
||||||
{
|
{
|
||||||
// Reminder in case the change main.cpp, but we do not want to close the
|
// Reminder in case we change main.cpp, but we do not want to close the
|
||||||
// window more than once
|
// window more than once
|
||||||
// Shutdown();
|
// Shutdown();
|
||||||
}
|
}
|
||||||
@@ -68,7 +69,7 @@ bool Application::Initialize(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Initialize hot reload to watch the scripts directory so any script change
|
// Initialize hot reload to watch the scripts directory so any script change
|
||||||
// (not just the main file) triggers a reload.
|
// triggers a reload.
|
||||||
{
|
{
|
||||||
std::filesystem::path p(SCRIPT_FILE);
|
std::filesystem::path p(SCRIPT_FILE);
|
||||||
std::string watchPath = p.parent_path().string();
|
std::string watchPath = p.parent_path().string();
|
||||||
@@ -83,7 +84,7 @@ bool Application::Initialize(int argc, char *argv[])
|
|||||||
if (enableEditor)
|
if (enableEditor)
|
||||||
{
|
{
|
||||||
|
|
||||||
guiManager.Initialize();
|
guiManager.Initialize(this);
|
||||||
|
|
||||||
renderTexture = LoadRenderTexture(WINDOW_WIDTH, WINDOW_HEIGHT);
|
renderTexture = LoadRenderTexture(WINDOW_WIDTH, WINDOW_HEIGHT);
|
||||||
}
|
}
|
||||||
@@ -116,6 +117,9 @@ void Application::Update(float deltaTime)
|
|||||||
if (!success)
|
if (!success)
|
||||||
{
|
{
|
||||||
log_warn("Script compilation failed - keeping previous version");
|
log_warn("Script compilation failed - keeping previous version");
|
||||||
|
Toast::Warning("Script compilation failed - check console for details.");
|
||||||
|
} else {
|
||||||
|
Toast::Success("Script reloaded successfully.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -144,12 +148,6 @@ void Application::Draw()
|
|||||||
BeginTextureMode(renderTexture);
|
BeginTextureMode(renderTexture);
|
||||||
ClearBackground(RAYWHITE);
|
ClearBackground(RAYWHITE);
|
||||||
|
|
||||||
// Show script error status in top left if there's an error, otherwise show normal message
|
|
||||||
if (scriptCompilationError)
|
|
||||||
{
|
|
||||||
DrawText("SCRIPT ERROR - Check console for details", 10, 10, 16, RED);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Call script Draw function
|
// Call script Draw function
|
||||||
scriptEngine.CallScriptFunction(scriptEngine.GetDrawFunction());
|
scriptEngine.CallScriptFunction(scriptEngine.GetDrawFunction());
|
||||||
|
|
||||||
|
|||||||
@@ -4,12 +4,16 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
|
#include "Application.h"
|
||||||
|
#include <filesystem> // Add this for cross-platform file handling
|
||||||
|
|
||||||
GuiManager::GuiManager() {}
|
GuiManager::GuiManager() {}
|
||||||
|
|
||||||
GuiManager::~GuiManager() {}
|
GuiManager::~GuiManager() {}
|
||||||
|
|
||||||
void GuiManager::Initialize()
|
void GuiManager::Initialize(Application *application)
|
||||||
{
|
{
|
||||||
|
app = application;
|
||||||
rlImGuiSetup(true);
|
rlImGuiSetup(true);
|
||||||
ImGuiIO &io = ImGui::GetIO();
|
ImGuiIO &io = ImGui::GetIO();
|
||||||
io.ConfigFlags |= ImGuiConfigFlags_DockingEnable;
|
io.ConfigFlags |= ImGuiConfigFlags_DockingEnable;
|
||||||
@@ -25,14 +29,20 @@ void GuiManager::Initialize()
|
|||||||
iconsConfig.PixelSnapH = true;
|
iconsConfig.PixelSnapH = true;
|
||||||
iconsConfig.GlyphMinAdvanceX = iconFontSize;
|
iconsConfig.GlyphMinAdvanceX = iconFontSize;
|
||||||
io.Fonts->AddFontFromMemoryCompressedTTF(fa_solid_900_compressed_data, fa_solid_900_compressed_size, iconFontSize, &iconsConfig, iconsRanges);
|
io.Fonts->AddFontFromMemoryCompressedTTF(fa_solid_900_compressed_data, fa_solid_900_compressed_size, iconFontSize, &iconsConfig, iconsRanges);
|
||||||
|
SetTheme();
|
||||||
|
|
||||||
|
logWindow.Initialize(); // Initialize the LogWindow
|
||||||
log_trace("GuiManager::Initialize - Started");
|
log_trace("GuiManager::Initialize - Started");
|
||||||
}
|
}
|
||||||
|
|
||||||
void GuiManager::Render(RenderTexture2D &renderTexture)
|
void GuiManager::Render(RenderTexture2D &renderTexture)
|
||||||
{
|
{
|
||||||
rlImGuiBegin();
|
rlImGuiBegin();
|
||||||
SetupDockspace(renderTexture); // Pass the renderTexture parameter
|
SetupDockspace(renderTexture);
|
||||||
|
|
||||||
|
RenderErrorBanner();
|
||||||
RenderNotifications();
|
RenderNotifications();
|
||||||
|
logWindow.Render(showLogWindow); // Render the LogWindow
|
||||||
rlImGuiEnd();
|
rlImGuiEnd();
|
||||||
|
|
||||||
ImGui::UpdatePlatformWindows();
|
ImGui::UpdatePlatformWindows();
|
||||||
@@ -66,7 +76,32 @@ void GuiManager::SetupDockspace(RenderTexture2D &renderTexture)
|
|||||||
ImGui::Begin("DockSpaceHost", &dockspaceOpen, window_flags);
|
ImGui::Begin("DockSpaceHost", &dockspaceOpen, window_flags);
|
||||||
if (opt_fullscreen)
|
if (opt_fullscreen)
|
||||||
ImGui::PopStyleVar(2);
|
ImGui::PopStyleVar(2);
|
||||||
|
if (ImGui::BeginMenuBar())
|
||||||
|
{
|
||||||
|
if (ImGui::BeginMenu("Game"))
|
||||||
|
{
|
||||||
|
if (ImGui::MenuItem("Quit", "Ctrl + Q")) {
|
||||||
|
// Handle quit here
|
||||||
|
app->Shutdown();
|
||||||
|
}
|
||||||
|
ImGui::EndMenu();
|
||||||
|
}
|
||||||
|
if (ImGui::BeginMenu("View"))
|
||||||
|
{
|
||||||
|
ImGui::MenuItem("Log Viewer", "Ctrl + L", &showLogWindow);
|
||||||
|
ImGui::EndMenu();
|
||||||
|
}
|
||||||
|
ImGui::EndMenuBar();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ImGui::GetIO().KeyCtrl && ImGui::IsKeyPressed(ImGuiKey_L))
|
||||||
|
{
|
||||||
|
showLogWindow = !showLogWindow;
|
||||||
|
}
|
||||||
|
if (ImGui::GetIO().KeyCtrl && ImGui::IsKeyPressed(ImGuiKey_Q))
|
||||||
|
{
|
||||||
|
app->Shutdown();
|
||||||
|
}
|
||||||
ImGuiID dockspace_id = ImGui::GetID("MyDockSpace");
|
ImGuiID dockspace_id = ImGui::GetID("MyDockSpace");
|
||||||
ImGui::DockSpace(dockspace_id, ImVec2(0.0f, 0.0f), dockspace_flags);
|
ImGui::DockSpace(dockspace_id, ImVec2(0.0f, 0.0f), dockspace_flags);
|
||||||
|
|
||||||
@@ -77,35 +112,21 @@ void GuiManager::SetupDockspace(RenderTexture2D &renderTexture)
|
|||||||
rlImGuiImageRenderTexture(&renderTexture);
|
rlImGuiImageRenderTexture(&renderTexture);
|
||||||
|
|
||||||
ImGui::End();
|
ImGui::End();
|
||||||
|
|
||||||
// Log Viewer Window
|
|
||||||
ImGui::Begin("Log Viewer");
|
|
||||||
static std::string logContent;
|
|
||||||
static size_t lastFileSize = 0;
|
|
||||||
|
|
||||||
// Read the log file if it has changed
|
|
||||||
std::ifstream logFile("log.txt", std::ios::ate); // Open at the end to get the file size
|
|
||||||
if (logFile.is_open())
|
|
||||||
{
|
|
||||||
size_t fileSize = logFile.tellg();
|
|
||||||
if (fileSize != lastFileSize)
|
|
||||||
{
|
|
||||||
lastFileSize = fileSize;
|
|
||||||
logFile.seekg(0, std::ios::beg); // Go back to the beginning
|
|
||||||
logContent.assign((std::istreambuf_iterator<char>(logFile)),
|
|
||||||
std::istreambuf_iterator<char>());
|
|
||||||
}
|
|
||||||
logFile.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Display the log content in a scrollable text area
|
|
||||||
ImGui::BeginChild("LogText", ImVec2(0, 0), true, ImGuiWindowFlags_HorizontalScrollbar);
|
|
||||||
ImGui::TextUnformatted(logContent.c_str());
|
|
||||||
if (ImGui::GetScrollY() >= ImGui::GetScrollMaxY())
|
|
||||||
ImGui::SetScrollHereY(1.0f); // Auto-scroll to the bottom
|
|
||||||
ImGui::EndChild();
|
|
||||||
ImGui::End();
|
ImGui::End();
|
||||||
|
}
|
||||||
|
|
||||||
|
void GuiManager::RenderErrorBanner()
|
||||||
|
{
|
||||||
|
if (!app || !app->HasScriptCompilationError())
|
||||||
|
return;
|
||||||
|
|
||||||
|
ImGui::SetNextWindowPos(ImVec2(0.0f, 0.0f));
|
||||||
|
ImGui::SetNextWindowSize(ImVec2(ImGui::GetIO().DisplaySize.x, 0.0f));
|
||||||
|
ImGuiWindowFlags flags = ImGuiWindowFlags_NoDecoration |
|
||||||
|
ImGuiWindowFlags_NoMove |
|
||||||
|
ImGuiWindowFlags_NoSavedSettings;
|
||||||
|
ImGui::Begin("PersistentBanner", nullptr, flags);
|
||||||
|
ImGui::TextColored(ImVec4(1, 0.4f, 0.4f, 1), ICON_FA_TRIANGLE_EXCLAMATION " Script Compilation Error - running last working version");
|
||||||
ImGui::End();
|
ImGui::End();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -119,4 +140,90 @@ void GuiManager::RenderNotifications()
|
|||||||
|
|
||||||
ImGui::PopStyleVar(2);
|
ImGui::PopStyleVar(2);
|
||||||
ImGui::PopStyleColor(1);
|
ImGui::PopStyleColor(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GuiManager::SetTheme()
|
||||||
|
{
|
||||||
|
|
||||||
|
ImVec4 *colors = ImGui::GetStyle().Colors;
|
||||||
|
colors[ImGuiCol_Text] = ImVec4(1.00f, 1.00f, 1.00f, 1.00f);
|
||||||
|
colors[ImGuiCol_TextDisabled] = ImVec4(0.50f, 0.50f, 0.50f, 1.00f);
|
||||||
|
colors[ImGuiCol_WindowBg] = ImVec4(0.10f, 0.10f, 0.10f, 1.00f);
|
||||||
|
colors[ImGuiCol_ChildBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f);
|
||||||
|
colors[ImGuiCol_PopupBg] = ImVec4(0.19f, 0.19f, 0.19f, 0.92f);
|
||||||
|
colors[ImGuiCol_Border] = ImVec4(0.19f, 0.19f, 0.19f, 0.29f);
|
||||||
|
colors[ImGuiCol_BorderShadow] = ImVec4(0.00f, 0.00f, 0.00f, 0.24f);
|
||||||
|
colors[ImGuiCol_FrameBg] = ImVec4(0.05f, 0.05f, 0.05f, 0.54f);
|
||||||
|
colors[ImGuiCol_FrameBgHovered] = ImVec4(0.19f, 0.19f, 0.19f, 0.54f);
|
||||||
|
colors[ImGuiCol_FrameBgActive] = ImVec4(0.20f, 0.22f, 0.23f, 1.00f);
|
||||||
|
colors[ImGuiCol_TitleBg] = ImVec4(0.00f, 0.00f, 0.00f, 1.00f);
|
||||||
|
colors[ImGuiCol_TitleBgActive] = ImVec4(0.06f, 0.06f, 0.06f, 1.00f);
|
||||||
|
colors[ImGuiCol_TitleBgCollapsed] = ImVec4(0.00f, 0.00f, 0.00f, 1.00f);
|
||||||
|
colors[ImGuiCol_MenuBarBg] = ImVec4(0.14f, 0.14f, 0.14f, 1.00f);
|
||||||
|
colors[ImGuiCol_ScrollbarBg] = ImVec4(0.05f, 0.05f, 0.05f, 0.54f);
|
||||||
|
colors[ImGuiCol_ScrollbarGrab] = ImVec4(0.34f, 0.34f, 0.34f, 0.54f);
|
||||||
|
colors[ImGuiCol_ScrollbarGrabHovered] = ImVec4(0.40f, 0.40f, 0.40f, 0.54f);
|
||||||
|
colors[ImGuiCol_ScrollbarGrabActive] = ImVec4(0.56f, 0.56f, 0.56f, 0.54f);
|
||||||
|
colors[ImGuiCol_CheckMark] = ImVec4(0.33f, 0.67f, 0.86f, 1.00f);
|
||||||
|
colors[ImGuiCol_SliderGrab] = ImVec4(0.34f, 0.34f, 0.34f, 0.54f);
|
||||||
|
colors[ImGuiCol_SliderGrabActive] = ImVec4(0.56f, 0.56f, 0.56f, 0.54f);
|
||||||
|
colors[ImGuiCol_Button] = ImVec4(0.05f, 0.05f, 0.05f, 0.54f);
|
||||||
|
colors[ImGuiCol_ButtonHovered] = ImVec4(0.19f, 0.19f, 0.19f, 0.54f);
|
||||||
|
colors[ImGuiCol_ButtonActive] = ImVec4(0.20f, 0.22f, 0.23f, 1.00f);
|
||||||
|
colors[ImGuiCol_Header] = ImVec4(0.00f, 0.00f, 0.00f, 0.52f);
|
||||||
|
colors[ImGuiCol_HeaderHovered] = ImVec4(0.00f, 0.00f, 0.00f, 0.36f);
|
||||||
|
colors[ImGuiCol_HeaderActive] = ImVec4(0.20f, 0.22f, 0.23f, 0.33f);
|
||||||
|
colors[ImGuiCol_Separator] = ImVec4(0.28f, 0.28f, 0.28f, 0.29f);
|
||||||
|
colors[ImGuiCol_SeparatorHovered] = ImVec4(0.44f, 0.44f, 0.44f, 0.29f);
|
||||||
|
colors[ImGuiCol_SeparatorActive] = ImVec4(0.40f, 0.44f, 0.47f, 1.00f);
|
||||||
|
colors[ImGuiCol_ResizeGrip] = ImVec4(0.28f, 0.28f, 0.28f, 0.29f);
|
||||||
|
colors[ImGuiCol_ResizeGripHovered] = ImVec4(0.44f, 0.44f, 0.44f, 0.29f);
|
||||||
|
colors[ImGuiCol_ResizeGripActive] = ImVec4(0.40f, 0.44f, 0.47f, 1.00f);
|
||||||
|
colors[ImGuiCol_Tab] = ImVec4(0.00f, 0.00f, 0.00f, 0.52f);
|
||||||
|
colors[ImGuiCol_TabHovered] = ImVec4(0.14f, 0.14f, 0.14f, 1.00f);
|
||||||
|
colors[ImGuiCol_TabActive] = ImVec4(0.20f, 0.20f, 0.20f, 0.36f);
|
||||||
|
colors[ImGuiCol_TabUnfocused] = ImVec4(0.00f, 0.00f, 0.00f, 0.52f);
|
||||||
|
colors[ImGuiCol_TabUnfocusedActive] = ImVec4(0.14f, 0.14f, 0.14f, 1.00f);
|
||||||
|
// colors[ImGuiCol_DockingPreview] = ImVec4(0.33f, 0.67f, 0.86f, 1.00f);
|
||||||
|
// colors[ImGuiCol_DockingEmptyBg] = ImVec4(1.00f, 0.00f, 0.00f, 1.00f);
|
||||||
|
colors[ImGuiCol_PlotLines] = ImVec4(1.00f, 0.00f, 0.00f, 1.00f);
|
||||||
|
colors[ImGuiCol_PlotLinesHovered] = ImVec4(1.00f, 0.00f, 0.00f, 1.00f);
|
||||||
|
colors[ImGuiCol_PlotHistogram] = ImVec4(1.00f, 0.00f, 0.00f, 1.00f);
|
||||||
|
colors[ImGuiCol_PlotHistogramHovered] = ImVec4(1.00f, 0.00f, 0.00f, 1.00f);
|
||||||
|
colors[ImGuiCol_TableHeaderBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.52f);
|
||||||
|
colors[ImGuiCol_TableBorderStrong] = ImVec4(0.00f, 0.00f, 0.00f, 0.52f);
|
||||||
|
colors[ImGuiCol_TableBorderLight] = ImVec4(0.28f, 0.28f, 0.28f, 0.29f);
|
||||||
|
colors[ImGuiCol_TableRowBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f);
|
||||||
|
colors[ImGuiCol_TableRowBgAlt] = ImVec4(1.00f, 1.00f, 1.00f, 0.06f);
|
||||||
|
colors[ImGuiCol_TextSelectedBg] = ImVec4(0.20f, 0.22f, 0.23f, 1.00f);
|
||||||
|
colors[ImGuiCol_DragDropTarget] = ImVec4(0.33f, 0.67f, 0.86f, 1.00f);
|
||||||
|
colors[ImGuiCol_NavHighlight] = ImVec4(1.00f, 0.00f, 0.00f, 1.00f);
|
||||||
|
colors[ImGuiCol_NavWindowingHighlight] = ImVec4(1.00f, 0.00f, 0.00f, 0.70f);
|
||||||
|
colors[ImGuiCol_NavWindowingDimBg] = ImVec4(1.00f, 0.00f, 0.00f, 0.20f);
|
||||||
|
colors[ImGuiCol_ModalWindowDimBg] = ImVec4(1.00f, 0.00f, 0.00f, 0.35f);
|
||||||
|
colors[ImGuiCol_CheckMark] = ImVec4(0.33f, 0.67f, 0.86f, 1.00f);
|
||||||
|
|
||||||
|
ImGuiStyle &style = ImGui::GetStyle();
|
||||||
|
style.WindowPadding = ImVec2(8.00f, 8.00f);
|
||||||
|
style.FramePadding = ImVec2(5.00f, 2.00f);
|
||||||
|
style.CellPadding = ImVec2(6.00f, 6.00f);
|
||||||
|
style.ItemSpacing = ImVec2(6.00f, 6.00f);
|
||||||
|
style.ItemInnerSpacing = ImVec2(6.00f, 6.00f);
|
||||||
|
style.TouchExtraPadding = ImVec2(0.00f, 0.00f);
|
||||||
|
style.IndentSpacing = 25;
|
||||||
|
style.ScrollbarSize = 15;
|
||||||
|
style.GrabMinSize = 10;
|
||||||
|
style.WindowBorderSize = 1;
|
||||||
|
style.ChildBorderSize = 1;
|
||||||
|
style.PopupBorderSize = 1;
|
||||||
|
style.FrameBorderSize = 1;
|
||||||
|
style.TabBorderSize = 1;
|
||||||
|
style.WindowRounding = 7;
|
||||||
|
style.ChildRounding = 4;
|
||||||
|
style.FrameRounding = 3;
|
||||||
|
style.PopupRounding = 4;
|
||||||
|
style.ScrollbarRounding = 9;
|
||||||
|
style.GrabRounding = 3;
|
||||||
|
style.LogSliderDeadzone = 4;
|
||||||
|
style.TabRounding = 4;
|
||||||
|
}
|
||||||
|
|||||||
50
src/LogWindow.cpp
Normal file
50
src/LogWindow.cpp
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
#include "LogWindow.h"
|
||||||
|
#include "log.h"
|
||||||
|
|
||||||
|
void LogWindow::Initialize()
|
||||||
|
{
|
||||||
|
logEntries.clear();
|
||||||
|
log_add_callback(LogCallback, this, LOG_ALL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LogWindow::Render(bool& showLogWindow)
|
||||||
|
{
|
||||||
|
if (!showLogWindow)
|
||||||
|
return;
|
||||||
|
|
||||||
|
ImGui::Begin("Log Viewer");
|
||||||
|
ImGui::BeginChild("LogText", ImVec2(0, 0), true, ImGuiWindowFlags_HorizontalScrollbar);
|
||||||
|
|
||||||
|
for (const auto& entry : logEntries)
|
||||||
|
{
|
||||||
|
ImGui::TextColored(entry.color, "%s", entry.message.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ImGui::GetScrollY() >= ImGui::GetScrollMaxY())
|
||||||
|
ImGui::SetScrollHereY(1.0f);
|
||||||
|
|
||||||
|
ImGui::EndChild();
|
||||||
|
ImGui::End();
|
||||||
|
}
|
||||||
|
|
||||||
|
void LogWindow::LogCallback(log_Event* ev)
|
||||||
|
{
|
||||||
|
LogWindow* logWindow = static_cast<LogWindow*>(ev->udata);
|
||||||
|
|
||||||
|
char buffer[1024];
|
||||||
|
vsnprintf(buffer, sizeof(buffer), ev->fmt, ev->ap);
|
||||||
|
|
||||||
|
ImVec4 color;
|
||||||
|
switch (ev->level)
|
||||||
|
{
|
||||||
|
case LOG_TRACE: color = ImVec4(0.5f, 0.5f, 0.5f, 1.0f); break;
|
||||||
|
case LOG_DEBUG: color = ImVec4(0.0f, 0.5f, 1.0f, 1.0f); break;
|
||||||
|
case LOG_INFO: color = ImVec4(0.0f, 1.0f, 0.0f, 1.0f); break;
|
||||||
|
case LOG_WARNING: color = ImVec4(1.0f, 1.0f, 0.0f, 1.0f); break;
|
||||||
|
case LOG_ERROR: color = ImVec4(1.0f, 0.0f, 0.0f, 1.0f); break;
|
||||||
|
case LOG_FATAL: color = ImVec4(1.0f, 0.0f, 1.0f, 1.0f); break;
|
||||||
|
default: color = ImVec4(1.0f, 1.0f, 1.0f, 1.0f); break;
|
||||||
|
}
|
||||||
|
|
||||||
|
logWindow->logEntries.push_back({buffer, color});
|
||||||
|
}
|
||||||
@@ -3,6 +3,7 @@
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include "log/log.h"
|
#include "log/log.h"
|
||||||
|
#include "gui/Toast.h"
|
||||||
|
|
||||||
// Expose log level constants to AngelScript
|
// Expose log level constants to AngelScript
|
||||||
static int AS_LOG_TRACE = 1;
|
static int AS_LOG_TRACE = 1;
|
||||||
@@ -12,76 +13,123 @@ static int AS_LOG_WARNING = 4;
|
|||||||
static int AS_LOG_ERROR = 5;
|
static int AS_LOG_ERROR = 5;
|
||||||
static int AS_LOG_FATAL = 6;
|
static int AS_LOG_FATAL = 6;
|
||||||
|
|
||||||
void ScriptBindings::RegisterAll(asIScriptEngine* engine) {
|
static void AS_ToastInfo(const std::string& message)
|
||||||
|
{
|
||||||
|
Toast::Info(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void AS_ToastWarning(const std::string& message)
|
||||||
|
{
|
||||||
|
Toast::Warning(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void AS_ToastError(const std::string& message)
|
||||||
|
{
|
||||||
|
Toast::Error(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void AS_ToastSuccess(const std::string& message)
|
||||||
|
{
|
||||||
|
Toast::Success(message);
|
||||||
|
}
|
||||||
|
void ScriptBindings::RegisterAll(asIScriptEngine *engine)
|
||||||
|
{
|
||||||
// Register Print function with generic calling convention to access context
|
// Register Print function with generic calling convention to access context
|
||||||
int r = engine->RegisterGlobalFunction("void Print(const string &in)",
|
[[maybe_unused]] int r = engine->RegisterGlobalFunction("void Print(const string &in)",
|
||||||
asFUNCTION(Print), asCALL_GENERIC);
|
asFUNCTION(Print), asCALL_GENERIC);
|
||||||
assert(r >= 0);
|
assert(r >= 0);
|
||||||
|
|
||||||
// Register log level constants so scripts can refer to LOG_INFO, LOG_ERROR, etc.
|
// Register log level constants so scripts can refer to LOG_INFO, LOG_ERROR, etc.
|
||||||
r = engine->RegisterGlobalProperty("int LOG_TRACE", (void*)&AS_LOG_TRACE);
|
r = engine->RegisterGlobalProperty("int LOG_TRACE", (void *)&AS_LOG_TRACE);
|
||||||
assert(r >= 0);
|
assert(r >= 0);
|
||||||
r = engine->RegisterGlobalProperty("int LOG_DEBUG", (void*)&AS_LOG_DEBUG);
|
r = engine->RegisterGlobalProperty("int LOG_DEBUG", (void *)&AS_LOG_DEBUG);
|
||||||
assert(r >= 0);
|
assert(r >= 0);
|
||||||
r = engine->RegisterGlobalProperty("int LOG_INFO", (void*)&AS_LOG_INFO);
|
r = engine->RegisterGlobalProperty("int LOG_INFO", (void *)&AS_LOG_INFO);
|
||||||
assert(r >= 0);
|
assert(r >= 0);
|
||||||
r = engine->RegisterGlobalProperty("int LOG_WARNING", (void*)&AS_LOG_WARNING);
|
r = engine->RegisterGlobalProperty("int LOG_WARNING", (void *)&AS_LOG_WARNING);
|
||||||
assert(r >= 0);
|
assert(r >= 0);
|
||||||
r = engine->RegisterGlobalProperty("int LOG_ERROR", (void*)&AS_LOG_ERROR);
|
r = engine->RegisterGlobalProperty("int LOG_ERROR", (void *)&AS_LOG_ERROR);
|
||||||
assert(r >= 0);
|
assert(r >= 0);
|
||||||
r = engine->RegisterGlobalProperty("int LOG_FATAL", (void*)&AS_LOG_FATAL);
|
r = engine->RegisterGlobalProperty("int LOG_FATAL", (void *)&AS_LOG_FATAL);
|
||||||
assert(r >= 0);
|
assert(r >= 0);
|
||||||
|
|
||||||
// Register Log(level, message) to allow scripts to log at different levels
|
// Register Log(level, message) to allow scripts to log at different levels
|
||||||
r = engine->RegisterGlobalFunction("void Log(int, const string &in)",
|
r = engine->RegisterGlobalFunction("void Log(int, const string &in)",
|
||||||
asFUNCTION(Log), asCALL_GENERIC);
|
asFUNCTION(Log), asCALL_GENERIC);
|
||||||
assert(r >= 0);
|
assert(r >= 0);
|
||||||
|
|
||||||
|
// Toast functions
|
||||||
|
engine->SetDefaultNamespace("Toast");
|
||||||
|
r = engine->RegisterGlobalFunction("void Info(const string &in)",
|
||||||
|
asFUNCTION(AS_ToastInfo), asCALL_CDECL);
|
||||||
|
assert(r >= 0);
|
||||||
|
r = engine->RegisterGlobalFunction("void Warning(const string &in)",
|
||||||
|
asFUNCTION(AS_ToastWarning), asCALL_CDECL);
|
||||||
|
assert(r >= 0);
|
||||||
|
r = engine->RegisterGlobalFunction("void Error(const string &in)",
|
||||||
|
asFUNCTION(AS_ToastError), asCALL_CDECL);
|
||||||
|
assert(r >= 0);
|
||||||
|
r = engine->RegisterGlobalFunction("void Success(const string &in)",
|
||||||
|
asFUNCTION(AS_ToastSuccess), asCALL_CDECL);
|
||||||
|
assert(r >= 0);
|
||||||
|
engine->SetDefaultNamespace("");
|
||||||
|
|
||||||
|
|
||||||
// Register DrawText function
|
// Register DrawText function
|
||||||
r = engine->RegisterGlobalFunction("void DrawText(const string &in, int, int, int, uint)",
|
r = engine->RegisterGlobalFunction("void DrawText(const string &in, int, int, int, uint)",
|
||||||
asFUNCTION(AS_DrawText), asCALL_CDECL);
|
asFUNCTION(AS_DrawText), asCALL_CDECL);
|
||||||
assert(r >= 0);
|
assert(r >= 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ScriptBindings::Print(asIScriptGeneric* gen) {
|
void ScriptBindings::Print(asIScriptGeneric *gen)
|
||||||
|
{
|
||||||
// Get the message parameter
|
// Get the message parameter
|
||||||
std::string* msg = static_cast<std::string*>(gen->GetArgObject(0));
|
std::string *msg = static_cast<std::string *>(gen->GetArgObject(0));
|
||||||
|
|
||||||
// Get the active context to retrieve script file and line number
|
// Get the active context to retrieve script file and line number
|
||||||
asIScriptContext* ctx = asGetActiveContext();
|
asIScriptContext *ctx = asGetActiveContext();
|
||||||
|
|
||||||
if (ctx) {
|
if (ctx)
|
||||||
const char* section = nullptr;
|
{
|
||||||
|
const char *section = nullptr;
|
||||||
int line = 0;
|
int line = 0;
|
||||||
|
|
||||||
// Get the current line number and script section
|
// Get the current line number and script section
|
||||||
line = ctx->GetLineNumber(0, nullptr, §ion);
|
line = ctx->GetLineNumber(0, nullptr, §ion);
|
||||||
|
|
||||||
if (section && line > 0) {
|
if (section && line > 0)
|
||||||
|
{
|
||||||
// Log with script file and line number
|
// Log with script file and line number
|
||||||
log_log(LOG_INFO, section, line, "%s", msg->c_str());
|
log_log(LOG_INFO, section, line, "%s", msg->c_str());
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
// Fallback if we can't get the info
|
// Fallback if we can't get the info
|
||||||
log_info("%s", msg->c_str());
|
log_info("%s", msg->c_str());
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
// No context available, just log normally
|
// No context available, just log normally
|
||||||
log_info("%s", msg->c_str());
|
log_info("%s", msg->c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ScriptBindings::Log(asIScriptGeneric* gen) {
|
void ScriptBindings::Log(asIScriptGeneric *gen)
|
||||||
|
{
|
||||||
// arg0: int level, arg1: string message
|
// arg0: int level, arg1: string message
|
||||||
int level = gen->GetArgDWord(0);
|
int level = gen->GetArgDWord(0);
|
||||||
std::string* msg = static_cast<std::string*>(gen->GetArgObject(1));
|
std::string *msg = static_cast<std::string *>(gen->GetArgObject(1));
|
||||||
|
|
||||||
// Obtain script context to fetch file/line
|
// Obtain script context to fetch file/line
|
||||||
asIScriptContext* ctx = asGetActiveContext();
|
asIScriptContext *ctx = asGetActiveContext();
|
||||||
if (ctx) {
|
if (ctx)
|
||||||
const char* section = nullptr;
|
{
|
||||||
|
const char *section = nullptr;
|
||||||
int line = 0;
|
int line = 0;
|
||||||
line = ctx->GetLineNumber(0, nullptr, §ion);
|
line = ctx->GetLineNumber(0, nullptr, §ion);
|
||||||
if (section && line > 0) {
|
if (section && line > 0)
|
||||||
|
{
|
||||||
// Use the library's log_log to preserve filename/line info
|
// Use the library's log_log to preserve filename/line info
|
||||||
log_log(level, section, line, "%s", msg ? msg->c_str() : "");
|
log_log(level, section, line, "%s", msg ? msg->c_str() : "");
|
||||||
return;
|
return;
|
||||||
@@ -89,20 +137,32 @@ void ScriptBindings::Log(asIScriptGeneric* gen) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Fallback: log without script location
|
// Fallback: log without script location
|
||||||
switch (level) {
|
switch (level)
|
||||||
case LOG_TRACE: log_trace("%s", msg ? msg->c_str() : ""); break;
|
{
|
||||||
case LOG_DEBUG: log_debug("%s", msg ? msg->c_str() : ""); break;
|
case LOG_TRACE:
|
||||||
case LOG_WARNING: log_warn("%s", msg ? msg->c_str() : ""); break;
|
log_trace("%s", msg ? msg->c_str() : "");
|
||||||
case LOG_ERROR: log_error("%s", msg ? msg->c_str() : ""); break;
|
break;
|
||||||
case LOG_FATAL: log_fatal("%s", msg ? msg->c_str() : ""); break;
|
case LOG_DEBUG:
|
||||||
case LOG_INFO:
|
log_debug("%s", msg ? msg->c_str() : "");
|
||||||
default:
|
break;
|
||||||
log_info("%s", msg ? msg->c_str() : "");
|
case LOG_WARNING:
|
||||||
break;
|
log_warn("%s", msg ? msg->c_str() : "");
|
||||||
|
break;
|
||||||
|
case LOG_ERROR:
|
||||||
|
log_error("%s", msg ? msg->c_str() : "");
|
||||||
|
break;
|
||||||
|
case LOG_FATAL:
|
||||||
|
log_fatal("%s", msg ? msg->c_str() : "");
|
||||||
|
break;
|
||||||
|
case LOG_INFO:
|
||||||
|
default:
|
||||||
|
log_info("%s", msg ? msg->c_str() : "");
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Color ColorFromUInt(unsigned int c) {
|
Color ColorFromUInt(unsigned int c)
|
||||||
|
{
|
||||||
Color col;
|
Color col;
|
||||||
col.r = (c >> 24) & 0xFF;
|
col.r = (c >> 24) & 0xFF;
|
||||||
col.g = (c >> 16) & 0xFF;
|
col.g = (c >> 16) & 0xFF;
|
||||||
@@ -111,6 +171,7 @@ Color ColorFromUInt(unsigned int c) {
|
|||||||
return col;
|
return col;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ScriptBindings::AS_DrawText(const std::string &text, int x, int y, int fontSize, unsigned int color) {
|
void ScriptBindings::AS_DrawText(const std::string &text, int x, int y, int fontSize, unsigned int color)
|
||||||
|
{
|
||||||
DrawText(text.c_str(), x, y, fontSize, ColorFromUInt(color));
|
DrawText(text.c_str(), x, y, fontSize, ColorFromUInt(color));
|
||||||
}
|
}
|
||||||
@@ -215,7 +215,7 @@ void ScriptEngine::MessageCallback(const asSMessageInfo* msg, void*) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int ScriptEngine::IncludeCallback(const char* include, const char* from, CScriptBuilder* builder, void* userParam) {
|
int ScriptEngine::IncludeCallback(const char* include, const char* from, CScriptBuilder* builder, [[maybe_unused]] void* userParam) {
|
||||||
// Extract just the filename from the from path for cleaner logging
|
// Extract just the filename from the from path for cleaner logging
|
||||||
const char* fromFile = from;
|
const char* fromFile = from;
|
||||||
if (from) {
|
if (from) {
|
||||||
|
|||||||
@@ -182,7 +182,15 @@ static void init_event(log_Event *ev, void *udata)
|
|||||||
if (!ev->time)
|
if (!ev->time)
|
||||||
{
|
{
|
||||||
time_t t = time(NULL);
|
time_t t = time(NULL);
|
||||||
ev->time = localtime(&t);
|
static struct tm tm_buf; // Thread-safe buffer for time struct
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
localtime_s(&tm_buf, &t); // Use localtime_s on Windows
|
||||||
|
#else
|
||||||
|
localtime_r(&t, &tm_buf); // Use localtime_r on Linux/Unix
|
||||||
|
#endif
|
||||||
|
|
||||||
|
ev->time = &tm_buf;
|
||||||
}
|
}
|
||||||
ev->udata = udata;
|
ev->udata = udata;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,6 +17,9 @@ target_include_directories(unit_tests PRIVATE
|
|||||||
${CMAKE_SOURCE_DIR}/external/angelscript/sdk/add_on/scriptstdstring
|
${CMAKE_SOURCE_DIR}/external/angelscript/sdk/add_on/scriptstdstring
|
||||||
${CMAKE_SOURCE_DIR}/external/angelscript/sdk/add_on/scriptbuilder
|
${CMAKE_SOURCE_DIR}/external/angelscript/sdk/add_on/scriptbuilder
|
||||||
${CMAKE_SOURCE_DIR}/external/raylib/src
|
${CMAKE_SOURCE_DIR}/external/raylib/src
|
||||||
|
${CMAKE_SOURCE_DIR}/external/imgui
|
||||||
|
${CMAKE_SOURCE_DIR}/external/rlImGui
|
||||||
|
|
||||||
)
|
)
|
||||||
|
|
||||||
# Link AngelScript and its add-ons needed by ScriptEngine
|
# Link AngelScript and its add-ons needed by ScriptEngine
|
||||||
@@ -25,6 +28,7 @@ target_link_libraries(unit_tests PRIVATE
|
|||||||
scriptstdstring
|
scriptstdstring
|
||||||
scriptbuilder
|
scriptbuilder
|
||||||
raylib
|
raylib
|
||||||
|
imgui
|
||||||
)
|
)
|
||||||
|
|
||||||
add_test(NAME unit_tests COMMAND unit_tests)
|
add_test(NAME unit_tests COMMAND unit_tests)
|
||||||
Reference in New Issue
Block a user