Skip to content

Commit 91791b1

Browse files
committed
Added C# debugging support & Added Buffer and ScopedBuffer classes
1 parent 9c3aea3 commit 91791b1

File tree

5 files changed

+201
-44
lines changed

5 files changed

+201
-44
lines changed

StarEditor/src/EditorLayer.cpp

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -379,7 +379,7 @@ namespace StarEngine {
379379
if (hasPlayButton)
380380
{
381381
Ref<Texture2D> icon = (m_SceneState == SceneState::Edit || m_SceneState == SceneState::Simulate) ? m_IconPlay : m_IconStop;
382-
if (ImGui::ImageButton("##play", (ImTextureID)icon->GetRendererID(), ImVec2(size, size), ImVec2(0, 0), ImVec2(1, 1))) {
382+
if (ImGui::ImageButton("##play", (ImTextureID)(uint64_t)icon->GetRendererID(), ImVec2(size, size), ImVec2(0, 0), ImVec2(1, 1))) {
383383
if (m_SceneState == SceneState::Edit || m_SceneState == SceneState::Simulate)
384384
OnScenePlay();
385385
else if (m_SceneState == SceneState::Play)
@@ -395,7 +395,7 @@ namespace StarEngine {
395395
Ref<Texture2D> icon = (m_SceneState == SceneState::Edit || m_SceneState == SceneState::Play) ? m_IconSimulate : m_IconStop; //ImGui::SetCursorPosX((ImGui::GetWindowContentRegionMax().x * 0.5f) - (size * 0.5f));
396396

397397

398-
if (ImGui::ImageButton("##simulate", (ImTextureID)icon->GetRendererID(), ImVec2(size, size), ImVec2(0, 0), ImVec2(1, 1)))
398+
if (ImGui::ImageButton("##simulate", (ImTextureID)(uint64_t)icon->GetRendererID(), ImVec2(size, size), ImVec2(0, 0), ImVec2(1, 1)))
399399
{
400400
if (m_SceneState == SceneState::Edit || m_SceneState == SceneState::Play)
401401
OnSceneSimulate();
@@ -410,7 +410,7 @@ namespace StarEngine {
410410
ImGui::SameLine();
411411
{
412412
Ref<Texture2D> icon = m_IconPause;
413-
if (ImGui::ImageButton("##pause", (ImTextureID)icon->GetRendererID(), ImVec2(size, size), ImVec2(0, 0), ImVec2(1, 1)) && toolbarEnabled)
413+
if (ImGui::ImageButton("##pause", (ImTextureID)(uint64_t)icon->GetRendererID(), ImVec2(size, size), ImVec2(0, 0), ImVec2(1, 1)) && toolbarEnabled)
414414
{
415415
m_ActiveScene->SetPaused(!isPaused);
416416
}
@@ -424,7 +424,7 @@ namespace StarEngine {
424424
{
425425
Ref<Texture2D> icon = m_IconStep;
426426
bool isPaused = m_ActiveScene->IsPaused();
427-
if (ImGui::ImageButton("##step", (ImTextureID)icon->GetRendererID(), ImVec2(size, size), ImVec2(0, 0), ImVec2(1, 1)) && toolbarEnabled)
427+
if (ImGui::ImageButton("##step", (ImTextureID)(uint64_t)icon->GetRendererID(), ImVec2(size, size), ImVec2(0, 0), ImVec2(1, 1)) && toolbarEnabled)
428428

429429
{
430430
m_ActiveScene->Step();
@@ -539,6 +539,8 @@ namespace StarEngine {
539539
default:
540540
break;
541541
}
542+
543+
return false;
542544
}
543545

544546
bool EditorLayer::OnMouseButtonPressed(MouseButtonPressedEvent& e)
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
#pragma once
2+
3+
#include <cstdint>
4+
#include <cstring>
5+
6+
namespace StarEngine {
7+
8+
struct Buffer
9+
{
10+
uint8_t* Data = nullptr;
11+
uint64_t Size = 0;
12+
13+
Buffer() = default;
14+
15+
Buffer(uint64_t size)
16+
{
17+
Allocate(size);
18+
}
19+
20+
Buffer(const Buffer&) = default;
21+
22+
static Buffer Copy(Buffer other)
23+
{
24+
Buffer result(other.Size);
25+
memcpy(result.Data, other.Data, other.Size);
26+
return result;
27+
}
28+
29+
void Allocate(uint64_t size)
30+
{
31+
Release();
32+
33+
Data = new uint8_t[size];
34+
Size = size;
35+
}
36+
37+
void Release()
38+
{
39+
delete[] Data;
40+
Data = nullptr;
41+
Size = 0;
42+
}
43+
44+
template<typename T>
45+
T* As()
46+
{
47+
return (T*)Data;
48+
}
49+
50+
operator bool() const
51+
{
52+
return (bool)Data;
53+
}
54+
55+
};
56+
57+
struct ScopedBuffer
58+
{
59+
ScopedBuffer(Buffer buffer)
60+
: m_Buffer(buffer)
61+
{
62+
}
63+
64+
ScopedBuffer(uint64_t size)
65+
: m_Buffer(size)
66+
{
67+
}
68+
69+
~ScopedBuffer()
70+
{
71+
m_Buffer.Release();
72+
}
73+
74+
uint8_t* Data() { return m_Buffer.Data; }
75+
uint64_t Size() { return m_Buffer.Size; }
76+
77+
template<typename T>
78+
T* As()
79+
{
80+
return m_Buffer.As<T>();
81+
}
82+
83+
operator bool() const { return m_Buffer; }
84+
private:
85+
Buffer m_Buffer;
86+
};
87+
88+
89+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
#include "sepch.h"
2+
#include "FileSystem.h"
3+
4+
namespace StarEngine {
5+
6+
Buffer FileSystem::ReadFileBinary(const std::filesystem::path& filepath)
7+
{
8+
std::ifstream stream(filepath, std::ios::binary | std::ios::ate);
9+
10+
if (!stream)
11+
{
12+
// Failed to open the file
13+
return {};
14+
}
15+
16+
17+
std::streampos end = stream.tellg();
18+
stream.seekg(0, std::ios::beg);
19+
uint64_t size = end - stream.tellg();
20+
21+
if (size == 0)
22+
{
23+
// File is empty
24+
return {};
25+
}
26+
27+
Buffer buffer(size);
28+
stream.read(buffer.As<char>(), size);
29+
stream.close();
30+
return buffer;
31+
}
32+
33+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
#pragma once
2+
3+
#include "StarEngine/Core/Buffer.h"
4+
5+
namespace StarEngine {
6+
7+
class FileSystem
8+
{
9+
public:
10+
// TODO: move to FileSystem class
11+
static Buffer ReadFileBinary(const std::filesystem::path& filepath);
12+
};
13+
14+
}

StarEngine/src/StarEngine/Scripting/ScriptEngine.cpp

Lines changed: 59 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,25 @@
77
#include "mono/metadata/assembly.h"
88
#include "mono/metadata/object.h"
99
#include "mono/metadata/tabledefs.h"
10+
#include "mono/metadata/mono-debug.h"
11+
#include "mono/metadata/threads.h"
1012

1113
#include "FileWatch.h"
1214

1315
#include "StarEngine/Core/Application.h"
1416
#include "StarEngine/Core/Timer.h"
17+
#include "StarEngine/Core/Buffer.h"
18+
#include "StarEngine/Core/FileSystem.h"
19+
20+
namespace fmt {
21+
template <>
22+
struct formatter<std::filesystem::path> : formatter<std::string> {
23+
template <typename FormatContext>
24+
auto format(const std::filesystem::path& path, FormatContext& ctx) const {
25+
return formatter<std::string>::format(path.string(), ctx);
26+
}
27+
};
28+
} // namespace fmt
1529

1630
namespace StarEngine {
1731

@@ -38,43 +52,13 @@ namespace StarEngine {
3852

3953
namespace Utils {
4054

41-
// TODO: move to FileSystem class
42-
static char* ReadBytes(const std::filesystem::path& filepath, uint32_t* outSize)
43-
{
44-
std::ifstream stream(filepath, std::ios::binary | std::ios::ate);
45-
46-
if (!stream)
47-
{
48-
// Failed to open the file
49-
return nullptr;
50-
}
51-
52-
std::streampos end = stream.tellg();
53-
stream.seekg(0, std::ios::beg);
54-
uint64_t size = end - stream.tellg();
55-
56-
if (size == 0)
57-
{
58-
// File is empty
59-
return nullptr;
60-
}
61-
62-
char* buffer = new char[size];
63-
stream.read((char*)buffer, size);
64-
stream.close();
65-
66-
*outSize = (uint32_t)size;
67-
return buffer;
68-
}
69-
70-
static MonoAssembly* LoadMonoAssembly(const std::filesystem::path& assemblyPath)
55+
static MonoAssembly* LoadMonoAssembly(const std::filesystem::path& assemblyPath, bool loadPDB = false)
7156
{
72-
uint32_t fileSize = 0;
73-
char* fileData = ReadBytes(assemblyPath, &fileSize);
57+
ScopedBuffer fileData = FileSystem::ReadFileBinary(assemblyPath);
7458

7559
// NOTE: We can't use this image for anything other than loading the assembly because this image doesn't have a reference to the assembly
7660
MonoImageOpenStatus status;
77-
MonoImage* image = mono_image_open_from_data_full(fileData, fileSize, 1, &status, 0);
61+
MonoImage* image = mono_image_open_from_data_full(fileData.As<char>(), fileData.Size(), 1, &status, 0);
7862

7963
if (status != MONO_IMAGE_OK)
8064
{
@@ -83,13 +67,23 @@ namespace StarEngine {
8367
return nullptr;
8468
}
8569

70+
if (loadPDB)
71+
{
72+
std::filesystem::path pdbPath = assemblyPath;
73+
pdbPath.replace_extension(".pdb");
74+
75+
if (std::filesystem::exists(pdbPath))
76+
{
77+
ScopedBuffer pdbFileData = FileSystem::ReadFileBinary(pdbPath);
78+
mono_debug_open_image_from_memory(image, pdbFileData.As<const mono_byte>(), pdbFileData.Size());
79+
SE_CORE_INFO("Loaded PDB {}", pdbPath);
80+
}
81+
}
82+
8683
std::string pathString = assemblyPath.string();
8784
MonoAssembly* assembly = mono_assembly_load_from_full(image, pathString.c_str(), &status, 0);
8885
mono_image_close(image);
8986

90-
// Don't forget to free the file data
91-
delete[] fileData;
92-
9387
return assembly;
9488
}
9589

@@ -115,7 +109,8 @@ namespace StarEngine {
115109
std::string typeName = mono_type_get_name(monoType);
116110

117111
auto it = s_ScriptFieldTypeMap.find(typeName);
118-
if (it == s_ScriptFieldTypeMap.end()) {
112+
if (it == s_ScriptFieldTypeMap.end())
113+
{
119114
SE_CORE_ERROR("Unknown type: {}", typeName);
120115
return ScriptFieldType::None;
121116
}
@@ -125,6 +120,7 @@ namespace StarEngine {
125120

126121
}
127122

123+
128124
struct ScriptEngineData
129125
{
130126
MonoDomain* RootDomain = nullptr;
@@ -148,6 +144,12 @@ namespace StarEngine {
148144
Scope<filewatch::FileWatch<std::string>> AppAssemblyFileWatcher;
149145
bool AssemblyReloadPending = false;
150146

147+
#if SE_DEBUG
148+
bool EnableDebugging = true;
149+
#else
150+
bool EnableDebugging = false;
151+
#endif // SE_DEBUG
152+
151153
// Runtime
152154
Scene* SceneContext = nullptr;
153155
};
@@ -227,11 +229,27 @@ namespace StarEngine {
227229
{
228230
mono_set_assemblies_path("mono/lib");
229231

232+
if (s_Data->EnableDebugging)
233+
{
234+
const char* argv[2] = {
235+
"--debugger-agent=transport=dt_socket,address=127.0.0.1:2550,server=y,suspend=n,loglevel=3,logfile=MonoDebugger.log",
236+
"--soft-breakpoints"
237+
};
238+
239+
mono_jit_parse_options(2, (char**)argv);
240+
mono_debug_init(MONO_DEBUG_FORMAT_MONO);
241+
}
242+
230243
MonoDomain* rootDomain = mono_jit_init("StarEngineJITRuntime");
231244
SE_CORE_ASSERT(rootDomain);
232245

233246
// Store the root domain pointer
234247
s_Data->RootDomain = rootDomain;
248+
249+
if (s_Data->EnableDebugging)
250+
mono_debug_domain_create(s_Data->RootDomain);
251+
252+
mono_thread_set_main(mono_thread_current());
235253
}
236254

237255

@@ -255,7 +273,7 @@ namespace StarEngine {
255273

256274
// Move this maybe
257275
s_Data->CoreAssemblyFilepath = filepath;
258-
s_Data->CoreAssembly = Utils::LoadMonoAssembly(filepath);
276+
s_Data->CoreAssembly = Utils::LoadMonoAssembly(filepath, s_Data->EnableDebugging);
259277
s_Data->CoreAssemblyImage = mono_assembly_get_image(s_Data->CoreAssembly);
260278
// Utils::PrintAssemblyTypes(s_Data->CoreAssembly);
261279
}
@@ -265,7 +283,7 @@ namespace StarEngine {
265283
{
266284
// Move this maybe
267285
s_Data->AppAssemblyFilepath = filepath;
268-
s_Data->AppAssembly = Utils::LoadMonoAssembly(filepath);
286+
s_Data->AppAssembly = Utils::LoadMonoAssembly(filepath, s_Data->EnableDebugging);
269287
auto assemb = s_Data->AppAssembly;
270288
s_Data->AppAssemblyImage = mono_assembly_get_image(s_Data->AppAssembly);
271289
auto assembi = s_Data->AppAssemblyImage;
@@ -472,7 +490,8 @@ namespace StarEngine {
472490

473491
MonoObject* ScriptClass::InvokeMethod(MonoObject* instance, MonoMethod* method, void** params)
474492
{
475-
return mono_runtime_invoke(method, instance, params, nullptr);
493+
MonoObject* exception = nullptr;
494+
return mono_runtime_invoke(method, instance, params, &exception);
476495
}
477496

478497
ScriptInstance::ScriptInstance(Ref<ScriptClass> scriptClass, Entity entity)

0 commit comments

Comments
 (0)