7
7
#include " mono/metadata/assembly.h"
8
8
#include " mono/metadata/object.h"
9
9
#include " mono/metadata/tabledefs.h"
10
+ #include " mono/metadata/mono-debug.h"
11
+ #include " mono/metadata/threads.h"
10
12
11
13
#include " FileWatch.h"
12
14
13
15
#include " StarEngine/Core/Application.h"
14
16
#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
15
29
16
30
namespace StarEngine {
17
31
@@ -38,43 +52,13 @@ namespace StarEngine {
38
52
39
53
namespace Utils {
40
54
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 )
71
56
{
72
- uint32_t fileSize = 0 ;
73
- char * fileData = ReadBytes (assemblyPath, &fileSize);
57
+ ScopedBuffer fileData = FileSystem::ReadFileBinary (assemblyPath);
74
58
75
59
// 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
76
60
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 );
78
62
79
63
if (status != MONO_IMAGE_OK)
80
64
{
@@ -83,13 +67,23 @@ namespace StarEngine {
83
67
return nullptr ;
84
68
}
85
69
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
+
86
83
std::string pathString = assemblyPath.string ();
87
84
MonoAssembly* assembly = mono_assembly_load_from_full (image, pathString.c_str (), &status, 0 );
88
85
mono_image_close (image);
89
86
90
- // Don't forget to free the file data
91
- delete[] fileData;
92
-
93
87
return assembly;
94
88
}
95
89
@@ -115,7 +109,8 @@ namespace StarEngine {
115
109
std::string typeName = mono_type_get_name (monoType);
116
110
117
111
auto it = s_ScriptFieldTypeMap.find (typeName);
118
- if (it == s_ScriptFieldTypeMap.end ()) {
112
+ if (it == s_ScriptFieldTypeMap.end ())
113
+ {
119
114
SE_CORE_ERROR (" Unknown type: {}" , typeName);
120
115
return ScriptFieldType::None;
121
116
}
@@ -125,6 +120,7 @@ namespace StarEngine {
125
120
126
121
}
127
122
123
+
128
124
struct ScriptEngineData
129
125
{
130
126
MonoDomain* RootDomain = nullptr ;
@@ -148,6 +144,12 @@ namespace StarEngine {
148
144
Scope<filewatch::FileWatch<std::string>> AppAssemblyFileWatcher;
149
145
bool AssemblyReloadPending = false ;
150
146
147
+ #if SE_DEBUG
148
+ bool EnableDebugging = true ;
149
+ #else
150
+ bool EnableDebugging = false ;
151
+ #endif // SE_DEBUG
152
+
151
153
// Runtime
152
154
Scene* SceneContext = nullptr ;
153
155
};
@@ -227,11 +229,27 @@ namespace StarEngine {
227
229
{
228
230
mono_set_assemblies_path (" mono/lib" );
229
231
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
+
230
243
MonoDomain* rootDomain = mono_jit_init (" StarEngineJITRuntime" );
231
244
SE_CORE_ASSERT (rootDomain);
232
245
233
246
// Store the root domain pointer
234
247
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 ());
235
253
}
236
254
237
255
@@ -255,7 +273,7 @@ namespace StarEngine {
255
273
256
274
// Move this maybe
257
275
s_Data->CoreAssemblyFilepath = filepath;
258
- s_Data->CoreAssembly = Utils::LoadMonoAssembly (filepath);
276
+ s_Data->CoreAssembly = Utils::LoadMonoAssembly (filepath, s_Data-> EnableDebugging );
259
277
s_Data->CoreAssemblyImage = mono_assembly_get_image (s_Data->CoreAssembly );
260
278
// Utils::PrintAssemblyTypes(s_Data->CoreAssembly);
261
279
}
@@ -265,7 +283,7 @@ namespace StarEngine {
265
283
{
266
284
// Move this maybe
267
285
s_Data->AppAssemblyFilepath = filepath;
268
- s_Data->AppAssembly = Utils::LoadMonoAssembly (filepath);
286
+ s_Data->AppAssembly = Utils::LoadMonoAssembly (filepath, s_Data-> EnableDebugging );
269
287
auto assemb = s_Data->AppAssembly ;
270
288
s_Data->AppAssemblyImage = mono_assembly_get_image (s_Data->AppAssembly );
271
289
auto assembi = s_Data->AppAssemblyImage ;
@@ -472,7 +490,8 @@ namespace StarEngine {
472
490
473
491
MonoObject* ScriptClass::InvokeMethod (MonoObject* instance, MonoMethod* method, void ** params)
474
492
{
475
- return mono_runtime_invoke (method, instance, params, nullptr );
493
+ MonoObject* exception = nullptr ;
494
+ return mono_runtime_invoke (method, instance, params, &exception);
476
495
}
477
496
478
497
ScriptInstance::ScriptInstance (Ref<ScriptClass> scriptClass, Entity entity)
0 commit comments