重新封装二进制文件读取
This commit is contained in:
103
Hazel/src/Hazel/Core/Buffer.h
Normal file
103
Hazel/src/Hazel/Core/Buffer.h
Normal file
@ -0,0 +1,103 @@
|
||||
//
|
||||
// Created by sfd on 25-10-26.
|
||||
//
|
||||
|
||||
#ifndef BUFFER_H
|
||||
#define BUFFER_H
|
||||
#include <cstdint>
|
||||
|
||||
namespace Hazel
|
||||
{
|
||||
struct Buffer
|
||||
{
|
||||
uint8_t* Data = nullptr;
|
||||
uint64_t Size = 0;
|
||||
|
||||
Buffer() = default;
|
||||
|
||||
Buffer(const uint64_t size)
|
||||
{
|
||||
Allocate(size);
|
||||
}
|
||||
|
||||
Buffer(const Buffer&) = default;
|
||||
|
||||
static Buffer Copy(const Buffer other)
|
||||
{
|
||||
const Buffer result(other.Size);
|
||||
memcpy(result.Data, other.Data, other.Size);
|
||||
return result;
|
||||
}
|
||||
|
||||
void Allocate(uint64_t size)
|
||||
{
|
||||
Release();
|
||||
|
||||
Data = new uint8_t[size];
|
||||
Size = size;
|
||||
}
|
||||
|
||||
void Release()
|
||||
{
|
||||
if (Data != nullptr)
|
||||
delete[] Data;
|
||||
Data = nullptr;
|
||||
Size = 0;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T* As()
|
||||
{
|
||||
return reinterpret_cast<T*>(Data);
|
||||
}
|
||||
|
||||
explicit operator bool() const
|
||||
{
|
||||
return static_cast<bool>(Data);
|
||||
}
|
||||
};
|
||||
|
||||
struct ScopedBuffer
|
||||
{
|
||||
ScopedBuffer(Buffer buffer)
|
||||
: m_Buffer(buffer)
|
||||
{
|
||||
}
|
||||
|
||||
ScopedBuffer(uint64_t size)
|
||||
: m_Buffer(size)
|
||||
{
|
||||
}
|
||||
|
||||
~ScopedBuffer()
|
||||
{
|
||||
m_Buffer.Release();
|
||||
}
|
||||
|
||||
uint8_t* Data() const
|
||||
{
|
||||
return m_Buffer.Data;
|
||||
}
|
||||
|
||||
uint64_t Size() const
|
||||
{
|
||||
return m_Buffer.Size;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T* As()
|
||||
{
|
||||
return m_Buffer.As<T>();
|
||||
}
|
||||
|
||||
explicit operator bool() const
|
||||
{
|
||||
return static_cast<bool>(m_Buffer);
|
||||
}
|
||||
|
||||
private:
|
||||
Buffer m_Buffer;
|
||||
};
|
||||
}
|
||||
|
||||
#endif //BUFFER_H
|
||||
39
Hazel/src/Hazel/Core/FileSystem.cpp
Normal file
39
Hazel/src/Hazel/Core/FileSystem.cpp
Normal file
@ -0,0 +1,39 @@
|
||||
//
|
||||
// Created by sfd on 25-10-26.
|
||||
//
|
||||
|
||||
#include "FileSystem.h"
|
||||
|
||||
#include <fstream>
|
||||
|
||||
#include "Log.h"
|
||||
|
||||
namespace Hazel
|
||||
{
|
||||
Buffer FileSystem::ReadFileBinary(const std::filesystem::path& filePath)
|
||||
{
|
||||
std::ifstream file(filePath, std::ios::binary | std::ios::ate);
|
||||
|
||||
if (!file)
|
||||
{
|
||||
HZ_CORE_WARN("could not open file '{0}'", filePath.string());
|
||||
return {};
|
||||
}
|
||||
|
||||
std::streampos end = file.tellg();
|
||||
file.seekg(0, std::ios::beg);
|
||||
uint64_t size = end - file.tellg();
|
||||
|
||||
if (size == 0)
|
||||
{
|
||||
HZ_CORE_WARN("file is empty");
|
||||
return {};
|
||||
}
|
||||
|
||||
Buffer buffer(size);
|
||||
file.read(buffer.As<char>(), size);
|
||||
file.close();
|
||||
return buffer;
|
||||
}
|
||||
|
||||
}
|
||||
22
Hazel/src/Hazel/Core/FileSystem.h
Normal file
22
Hazel/src/Hazel/Core/FileSystem.h
Normal file
@ -0,0 +1,22 @@
|
||||
//
|
||||
// Created by sfd on 25-10-26.
|
||||
//
|
||||
|
||||
#ifndef FILESYSTEM_H
|
||||
#define FILESYSTEM_H
|
||||
#include <filesystem>
|
||||
|
||||
#include "Buffer.h"
|
||||
#include "Core.h"
|
||||
|
||||
|
||||
namespace Hazel
|
||||
{
|
||||
class HAZEL_API FileSystem
|
||||
{
|
||||
public:
|
||||
static Buffer ReadFileBinary(const std::filesystem::path& filePath);
|
||||
};
|
||||
}
|
||||
|
||||
#endif //FILESYSTEM_H
|
||||
@ -148,6 +148,18 @@ namespace YAML
|
||||
|
||||
namespace Hazel
|
||||
{
|
||||
#define WRITE_FIELD_TYPE(FieldType, Type) \
|
||||
case ScriptFieldType::FieldType: \
|
||||
out << scriptField.GetValue<Type>();break
|
||||
|
||||
|
||||
#define READ_FIELD_TYPE(FieldType, Type) \
|
||||
case ScriptFieldType::FieldType: \
|
||||
{ \
|
||||
Type valueData = scriptField["Data"].as<Type>(); \
|
||||
fieldInstance.SetValue(valueData); \
|
||||
break; \
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -252,9 +264,7 @@ namespace Hazel
|
||||
out << YAML::Key << "Data" << YAML::Value;
|
||||
|
||||
ScriptFieldInstance& scriptField = entityFields.at(name);
|
||||
#define WRITE_FIELD_TYPE(FieldType, Type) case ScriptFieldType::FieldType:\
|
||||
out << scriptField.GetValue<Type>();\
|
||||
break
|
||||
|
||||
|
||||
switch (field.Type)
|
||||
{
|
||||
@ -279,7 +289,6 @@ namespace Hazel
|
||||
}
|
||||
|
||||
out << YAML::EndMap;
|
||||
#undef WRITE_FIELD_TYPE
|
||||
}
|
||||
out << YAML::EndSeq;
|
||||
|
||||
@ -483,51 +492,44 @@ namespace Hazel
|
||||
if (scriptFields)
|
||||
{
|
||||
Ref<ScriptClass> entityClass = ScriptEngine::GetEntityClass(sc.ClassName);
|
||||
const auto& fields = entityClass->GetFields();
|
||||
auto& entityFields = ScriptEngine::GetScriptFieldMap(deserializedEntity);
|
||||
|
||||
for (auto scriptField: scriptFields)
|
||||
if (entityClass)
|
||||
{
|
||||
std::string name = scriptField["Name"].as<std::string>();
|
||||
std::string typeName = scriptField["Type"].as<std::string>();
|
||||
ScriptFieldType type = Utils::ScriptFieldTypeFromString(typeName);
|
||||
ScriptFieldInstance& fieldInstance = entityFields[name];
|
||||
const auto& fields = entityClass->GetFields();
|
||||
auto& entityFields = ScriptEngine::GetScriptFieldMap(deserializedEntity);
|
||||
|
||||
fieldInstance.Field = fields.at(name);
|
||||
|
||||
|
||||
#define READ_FIELD_TYPE(FieldType, Type) \
|
||||
case ScriptFieldType::FieldType: \
|
||||
{ \
|
||||
Type valueData = scriptField["Data"].as<Type>(); \
|
||||
fieldInstance.SetValue(valueData); \
|
||||
break; \
|
||||
}
|
||||
|
||||
|
||||
switch (type)
|
||||
for (auto scriptField: scriptFields)
|
||||
{
|
||||
READ_FIELD_TYPE(Float, float);
|
||||
READ_FIELD_TYPE(Double, double);
|
||||
READ_FIELD_TYPE(Boolean, bool);
|
||||
READ_FIELD_TYPE(Char, char);
|
||||
READ_FIELD_TYPE(Byte, int8_t);
|
||||
READ_FIELD_TYPE(Short, int16_t);
|
||||
READ_FIELD_TYPE(Int, int32_t);
|
||||
READ_FIELD_TYPE(Long, int64_t);
|
||||
READ_FIELD_TYPE(UByte, uint8_t);
|
||||
READ_FIELD_TYPE(UShort, uint16_t);
|
||||
READ_FIELD_TYPE(UInt, uint32_t);
|
||||
READ_FIELD_TYPE(ULong, uint64_t);
|
||||
std::string name = scriptField["Name"].as<std::string>();
|
||||
std::string typeName = scriptField["Type"].as<std::string>();
|
||||
ScriptFieldType type = Utils::ScriptFieldTypeFromString(typeName);
|
||||
ScriptFieldInstance& fieldInstance = entityFields[name];
|
||||
|
||||
READ_FIELD_TYPE(Vector2, glm::vec2);
|
||||
READ_FIELD_TYPE(Vector3, glm::vec3);
|
||||
READ_FIELD_TYPE(Vector4, glm::vec4);
|
||||
fieldInstance.Field = fields.at(name);
|
||||
|
||||
READ_FIELD_TYPE(Entity, UUID);
|
||||
|
||||
|
||||
switch (type)
|
||||
{
|
||||
READ_FIELD_TYPE(Float, float);
|
||||
READ_FIELD_TYPE(Double, double);
|
||||
READ_FIELD_TYPE(Boolean, bool);
|
||||
READ_FIELD_TYPE(Char, char);
|
||||
READ_FIELD_TYPE(Byte, int8_t);
|
||||
READ_FIELD_TYPE(Short, int16_t);
|
||||
READ_FIELD_TYPE(Int, int32_t);
|
||||
READ_FIELD_TYPE(Long, int64_t);
|
||||
READ_FIELD_TYPE(UByte, uint8_t);
|
||||
READ_FIELD_TYPE(UShort, uint16_t);
|
||||
READ_FIELD_TYPE(UInt, uint32_t);
|
||||
READ_FIELD_TYPE(ULong, uint64_t);
|
||||
|
||||
READ_FIELD_TYPE(Vector2, glm::vec2);
|
||||
READ_FIELD_TYPE(Vector3, glm::vec3);
|
||||
READ_FIELD_TYPE(Vector4, glm::vec4);
|
||||
|
||||
READ_FIELD_TYPE(Entity, UUID);
|
||||
}
|
||||
}
|
||||
|
||||
#undef READ_FIELD_TYPE
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -10,6 +10,8 @@
|
||||
#include "FileWatch.h"
|
||||
#include "ScriptGlue.h"
|
||||
#include "Hazel/Core/Application.h"
|
||||
#include "Hazel/Core/Buffer.h"
|
||||
#include "Hazel/Core/FileSystem.h"
|
||||
#include "mono/jit/jit.h"
|
||||
#include "mono/metadata/assembly.h"
|
||||
#include "mono/metadata/attrdefs.h"
|
||||
@ -46,6 +48,7 @@ namespace Hazel
|
||||
namespace Utils
|
||||
{
|
||||
|
||||
/*
|
||||
char* ReadBytes(const std::filesystem::path& filePath, uint32_t* outSize)
|
||||
{
|
||||
std::ifstream stream(filePath, std::ios::binary | std::ios::ate);
|
||||
@ -73,16 +76,15 @@ namespace Hazel
|
||||
*outSize = (uint32_t)size;
|
||||
return buffer;
|
||||
}
|
||||
*/
|
||||
|
||||
MonoAssembly* LoadMonoAssembly(const std::filesystem::path& assemblyPath, bool loadPDB = false)
|
||||
{
|
||||
HZ_CORE_DEBUG("Load Assemble: {0}", assemblyPath.string().c_str());
|
||||
uint32_t fileSize = 0;
|
||||
|
||||
char* fileData = ReadBytes(assemblyPath, &fileSize);
|
||||
ScopedBuffer fileData = FileSystem::ReadFileBinary(assemblyPath);
|
||||
|
||||
MonoImageOpenStatus status;
|
||||
MonoImage* image = mono_image_open_from_data_full(fileData, fileSize, 1, &status, 0);
|
||||
MonoImage* image = mono_image_open_from_data_full(fileData.As<char>(), fileData.Size(), 1, &status, 0);
|
||||
if (status != MONO_IMAGE_OK)
|
||||
{
|
||||
const char* errorMessage = mono_image_strerror(status);
|
||||
@ -98,13 +100,10 @@ namespace Hazel
|
||||
|
||||
if (std::filesystem::exists(pdbPath))
|
||||
{
|
||||
uint32_t pdbFileSize = 0;
|
||||
char* pdbFileData = ReadBytes(pdbPath, &pdbFileSize);
|
||||
mono_debug_open_image_from_memory(image, (const mono_byte*)pdbFileData, fileSize);
|
||||
ScopedBuffer pdbFileData = FileSystem::ReadFileBinary(pdbPath);
|
||||
mono_debug_open_image_from_memory(image, pdbFileData.As<mono_byte>(), fileData.Size());
|
||||
HZ_CORE_INFO("loaded pdb file: {0}", pdbPath.string());
|
||||
HZ_CORE_INFO(" size: {0}", pdbFileSize);
|
||||
|
||||
delete[] pdbFileData;
|
||||
HZ_CORE_INFO(" size: {0}", pdbFileData.Size());
|
||||
}
|
||||
}
|
||||
|
||||
@ -112,8 +111,6 @@ namespace Hazel
|
||||
MonoAssembly* assembly = mono_assembly_load_from_full(image, string.c_str(), &status, 0);
|
||||
mono_image_close(image);
|
||||
|
||||
delete[] fileData;
|
||||
|
||||
return assembly;
|
||||
}
|
||||
|
||||
@ -200,8 +197,20 @@ namespace Hazel
|
||||
InitMono();
|
||||
ScriptGlue::RegisterFunctions();
|
||||
|
||||
LoadAssemble("Resources/Scripts/Hazel-ScriptCore.dll");
|
||||
LoadAppAssemble("Resources/Scripts/Sandbox.dll");
|
||||
bool status = LoadAssemble("Resources/Scripts/Hazel-ScriptCore.dll");
|
||||
if (!status)
|
||||
{
|
||||
HZ_CORE_ERROR("[ScriptEngine] Could not load Hazel-ScriptCore assembly.");
|
||||
return;
|
||||
}
|
||||
|
||||
status = LoadAppAssemble("Resources/Scripts/Sandbox.dll");
|
||||
if (!status)
|
||||
{
|
||||
HZ_CORE_ERROR("[ScriptEngine] Could not load app assembly.");
|
||||
return;
|
||||
}
|
||||
|
||||
LoadAssemblyClass();
|
||||
Utils::PrintAssemblyTypes(s_Data->CoreAssembly);
|
||||
ScriptGlue::RegisterComponents();
|
||||
@ -249,32 +258,36 @@ namespace Hazel
|
||||
delete s_Data;
|
||||
}
|
||||
|
||||
void ScriptEngine::LoadAssemble(const std::filesystem::path& assemblePath)
|
||||
bool ScriptEngine::LoadAssemble(const std::filesystem::path& assemblePath)
|
||||
{
|
||||
// Create an Domain App
|
||||
char monoDomainName[] = "HazelScriptRuntime";
|
||||
s_Data->AppDomain = mono_domain_create_appdomain(monoDomainName, nullptr);
|
||||
mono_domain_set(s_Data->AppDomain, true);
|
||||
|
||||
// TODO: move this later
|
||||
s_Data->CoreAssemblyFilePath = assemblePath;
|
||||
s_Data->CoreAssembly = Utils::LoadMonoAssembly(assemblePath, s_Data->EnableDebugging);
|
||||
s_Data->CoreAssemblyImage = mono_assembly_get_image(s_Data->CoreAssembly);
|
||||
if (s_Data->CoreAssembly == nullptr)
|
||||
return false;
|
||||
|
||||
// Utils::PrintAssemblyTypes(s_Data->CoreAssembly);
|
||||
s_Data->CoreAssemblyImage = mono_assembly_get_image(s_Data->CoreAssembly);
|
||||
return true;
|
||||
}
|
||||
|
||||
void ScriptEngine::LoadAppAssemble(const std::filesystem::path& assemblePath)
|
||||
bool ScriptEngine::LoadAppAssemble(const std::filesystem::path& assemblePath)
|
||||
{
|
||||
// TODO: move this later
|
||||
s_Data->AppAssemblyFilePath = assemblePath;
|
||||
s_Data->AppAssembly = Utils::LoadMonoAssembly(assemblePath, s_Data->EnableDebugging);
|
||||
if (s_Data->AppAssembly == nullptr)
|
||||
return false;
|
||||
|
||||
s_Data->AppAssemblyImage = mono_assembly_get_image(s_Data->AppAssembly);
|
||||
|
||||
s_Data->AppAssemblyFileWatcher = CreateScope<filewatch::FileWatch<std::string>>(assemblePath.string(), OnAssemblyFileSystemEvent);
|
||||
auto& b = s_Data;
|
||||
s_Data->AssemblyReloading = false;
|
||||
// Utils::PrintAssemblyTypes(s_Data->CoreAssembly);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ScriptEngine::ReloadAssemble()
|
||||
@ -402,8 +415,7 @@ namespace Hazel
|
||||
UUID entityUUID = entity.GetUUID();
|
||||
if (!s_Data->EntityInstances.contains(entityUUID))
|
||||
{
|
||||
HZ_CORE_FATAL("script cannot get");
|
||||
assert(1);
|
||||
HZ_CORE_ERROR("Could not find ScriptInstance for entity {}", (uint64_t)entityUUID);
|
||||
}
|
||||
|
||||
const Ref<ScriptInstance> instance = s_Data->EntityInstances[entityUUID];
|
||||
|
||||
@ -145,8 +145,8 @@ namespace Hazel
|
||||
static void Init();
|
||||
static void Shutdown();
|
||||
|
||||
static void LoadAssemble(const std::filesystem::path& assemblePath);
|
||||
static void LoadAppAssemble(const std::filesystem::path& assemblePath);
|
||||
static bool LoadAssemble(const std::filesystem::path& assemblePath);
|
||||
static bool LoadAppAssemble(const std::filesystem::path& assemblePath);
|
||||
|
||||
static void ReloadAssemble();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user