简单添加ScriptComponent序列化功能
This commit is contained in:
@ -8,7 +8,7 @@ namespace Sandbox {
|
|||||||
// private TransformComponent m_Transform;
|
// private TransformComponent m_Transform;
|
||||||
// private RigidBody2DComponent m_Rigidbody;
|
// private RigidBody2DComponent m_Rigidbody;
|
||||||
|
|
||||||
|
public float MoveSpeed;
|
||||||
/*
|
/*
|
||||||
void OnCreate()
|
void OnCreate()
|
||||||
{
|
{
|
||||||
@ -23,7 +23,7 @@ namespace Sandbox {
|
|||||||
{
|
{
|
||||||
// Console.WriteLine($"Player.OnUpdate: {ts}");
|
// Console.WriteLine($"Player.OnUpdate: {ts}");
|
||||||
|
|
||||||
float speed = 1.0f;
|
float speed = MoveSpeed;
|
||||||
Vector3 velocity = Vector3.Zero;
|
Vector3 velocity = Vector3.Zero;
|
||||||
|
|
||||||
if(Input.IsKeyDown(KeyCode.UP))
|
if(Input.IsKeyDown(KeyCode.UP))
|
||||||
|
|||||||
@ -8,7 +8,8 @@ namespace Sandbox {
|
|||||||
private TransformComponent m_Transform;
|
private TransformComponent m_Transform;
|
||||||
private RigidBody2DComponent m_Rigidbody;
|
private RigidBody2DComponent m_Rigidbody;
|
||||||
|
|
||||||
public float Speed = 1.0f;
|
public float Force;
|
||||||
|
public float Time;
|
||||||
|
|
||||||
void OnCreate()
|
void OnCreate()
|
||||||
{
|
{
|
||||||
@ -20,9 +21,9 @@ namespace Sandbox {
|
|||||||
|
|
||||||
void OnUpdate(float ts)
|
void OnUpdate(float ts)
|
||||||
{
|
{
|
||||||
// Console.WriteLine($"Player.OnUpdate: {ts}");
|
Time += ts;
|
||||||
|
|
||||||
float speed = Speed;
|
float speed = Force;
|
||||||
Vector3 velocity = Vector3.Zero;
|
Vector3 velocity = Vector3.Zero;
|
||||||
|
|
||||||
if(Input.IsKeyDown(KeyCode.W))
|
if(Input.IsKeyDown(KeyCode.W))
|
||||||
@ -36,14 +37,6 @@ namespace Sandbox {
|
|||||||
velocity.X = 1.0f;
|
velocity.X = 1.0f;
|
||||||
|
|
||||||
m_Rigidbody.ApplyLinearImpulseToCenter(velocity.XY * speed, true);
|
m_Rigidbody.ApplyLinearImpulseToCenter(velocity.XY * speed, true);
|
||||||
|
|
||||||
/*
|
|
||||||
velocity *= speed;
|
|
||||||
|
|
||||||
Vector3 translation = m_Transform.Translation;
|
|
||||||
translation += velocity * ts;
|
|
||||||
m_Transform.Translation = translation;
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -48,6 +48,7 @@ namespace Hazel
|
|||||||
if (ImGui::MenuItem("Create Empty Entity"))
|
if (ImGui::MenuItem("Create Empty Entity"))
|
||||||
{
|
{
|
||||||
m_SelectionContext = m_Context->CreateEntity("Empty Entity");
|
m_SelectionContext = m_Context->CreateEntity("Empty Entity");
|
||||||
|
m_LastSelectionContext = m_SelectionContext;
|
||||||
}
|
}
|
||||||
else if (ImGui::MenuItem("Create Camera"))
|
else if (ImGui::MenuItem("Create Camera"))
|
||||||
{
|
{
|
||||||
@ -61,9 +62,9 @@ namespace Hazel
|
|||||||
}
|
}
|
||||||
|
|
||||||
ImGui::Begin("Properties");
|
ImGui::Begin("Properties");
|
||||||
if (m_SelectionContext)
|
if (m_LastSelectionContext)
|
||||||
{
|
{
|
||||||
DrawComponents(m_SelectionContext);
|
DrawComponents(m_LastSelectionContext);
|
||||||
}
|
}
|
||||||
ImGui::End();
|
ImGui::End();
|
||||||
}
|
}
|
||||||
@ -80,6 +81,7 @@ namespace Hazel
|
|||||||
if (ImGui::IsItemClicked())
|
if (ImGui::IsItemClicked())
|
||||||
{
|
{
|
||||||
m_SelectionContext = entity;
|
m_SelectionContext = entity;
|
||||||
|
m_LastSelectionContext = m_SelectionContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ImGui::BeginPopupContextItem())
|
if (ImGui::BeginPopupContextItem())
|
||||||
@ -100,6 +102,7 @@ namespace Hazel
|
|||||||
if (m_SelectionContext == entity)
|
if (m_SelectionContext == entity)
|
||||||
{
|
{
|
||||||
m_SelectionContext = {};
|
m_SelectionContext = {};
|
||||||
|
m_LastSelectionContext = m_SelectionContext;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -358,27 +361,37 @@ namespace Hazel
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
DrawComponent<ScriptComponent>("Script", entity, [entity](auto& component) mutable
|
DrawComponent<ScriptComponent>("Script", entity, [entity, &scene = m_Context](auto& component) mutable
|
||||||
{
|
{
|
||||||
const bool scriptClassExists = ScriptEngine::ClassExists(component.ClassName);
|
bool scriptClassExists = ScriptEngine::ClassExists(component.ClassName);
|
||||||
|
bool setStyleFlag = false;
|
||||||
|
|
||||||
static char buffer[64] = {};
|
static char buffer[64] = {};
|
||||||
strcpy(buffer, component.ClassName.c_str());
|
strcpy(buffer, component.ClassName.c_str());
|
||||||
|
|
||||||
if (!scriptClassExists)
|
if (!scriptClassExists)
|
||||||
|
{
|
||||||
ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(0.9f, 0.2f, 0.3f, 1.0f));
|
ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(0.9f, 0.2f, 0.3f, 1.0f));
|
||||||
|
setStyleFlag = true;
|
||||||
|
}
|
||||||
|
|
||||||
if (ImGui::InputText("Script", buffer, sizeof(buffer)))
|
if (ImGui::InputText("Class", buffer, sizeof(buffer)))
|
||||||
|
{
|
||||||
component.ClassName = buffer;
|
component.ClassName = buffer;
|
||||||
|
scriptClassExists = ScriptEngine::ClassExists(component.ClassName);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Fields
|
// Fields
|
||||||
|
|
||||||
Ref<ScriptInstance> scriptInstance = ScriptEngine::GetEntityScriptInstance(entity.GetUUID());
|
Ref<ScriptInstance> scriptInstance = ScriptEngine::GetEntityScriptInstance(entity.GetUUID());
|
||||||
|
|
||||||
|
const bool sceneRunning = scene->IsRunning();
|
||||||
|
if (sceneRunning)
|
||||||
|
{
|
||||||
if (scriptInstance)
|
if (scriptInstance)
|
||||||
{
|
{
|
||||||
const auto& fields = scriptInstance->GetScriptClass()->GetFields();
|
const auto& fields = scriptInstance->GetScriptClass()->GetFields();
|
||||||
for (const auto&[name, field] : fields)
|
for (const auto& [name, field] : fields)
|
||||||
{
|
{
|
||||||
if (field.Type == ScriptFieldType::Float)
|
if (field.Type == ScriptFieldType::Float)
|
||||||
{
|
{
|
||||||
@ -390,8 +403,51 @@ namespace Hazel
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (scriptClassExists)
|
||||||
|
{
|
||||||
|
Ref<ScriptClass> entityClass = ScriptEngine::GetEntityClass(component.ClassName);
|
||||||
|
const auto& fields = entityClass->GetFields();
|
||||||
|
auto& entityFields = ScriptEngine::GetScriptFieldMap(entity);
|
||||||
|
|
||||||
if (!scriptClassExists)
|
|
||||||
|
for (const auto& [name, field] : fields)
|
||||||
|
{
|
||||||
|
// field has been set in Editor
|
||||||
|
if (entityFields.contains(name))
|
||||||
|
{
|
||||||
|
ScriptFieldInstance& scriptField = entityFields.at(name);
|
||||||
|
|
||||||
|
// display control to set
|
||||||
|
if (field.Type == ScriptFieldType::Float)
|
||||||
|
{
|
||||||
|
float data = scriptField.GetValue<float>();
|
||||||
|
if (ImGui::DragFloat(name.c_str(), &data))
|
||||||
|
scriptField.SetValue(data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// display control to set
|
||||||
|
if (field.Type == ScriptFieldType::Float)
|
||||||
|
{
|
||||||
|
float data = 0.0f;
|
||||||
|
if (ImGui::DragFloat(name.c_str(), &data))
|
||||||
|
{
|
||||||
|
ScriptFieldInstance& fieldInstance = entityFields[name];
|
||||||
|
fieldInstance.Field = field;
|
||||||
|
fieldInstance.SetValue(data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (setStyleFlag)
|
||||||
ImGui::PopStyleColor();
|
ImGui::PopStyleColor();
|
||||||
|
|
||||||
});
|
});
|
||||||
@ -478,5 +534,6 @@ namespace Hazel
|
|||||||
void SceneHierachyPanel::SetSelectedEntity(const Entity entity)
|
void SceneHierachyPanel::SetSelectedEntity(const Entity entity)
|
||||||
{
|
{
|
||||||
m_SelectionContext = entity;
|
m_SelectionContext = entity;
|
||||||
|
m_LastSelectionContext = m_SelectionContext;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -33,6 +33,7 @@ namespace Hazel
|
|||||||
|
|
||||||
Ref<Scene> m_Context;
|
Ref<Scene> m_Context;
|
||||||
Entity m_SelectionContext;
|
Entity m_SelectionContext;
|
||||||
|
Entity m_LastSelectionContext;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -242,6 +242,7 @@ namespace Hazel
|
|||||||
|
|
||||||
void Scene::OnRuntimeStart()
|
void Scene::OnRuntimeStart()
|
||||||
{
|
{
|
||||||
|
m_IsRunning = true;
|
||||||
OnPhysics2DStart();
|
OnPhysics2DStart();
|
||||||
|
|
||||||
// scripts
|
// scripts
|
||||||
@ -274,6 +275,7 @@ namespace Hazel
|
|||||||
|
|
||||||
void Scene::OnRuntimeStop()
|
void Scene::OnRuntimeStop()
|
||||||
{
|
{
|
||||||
|
m_IsRunning = false;
|
||||||
OnPhysics2DStop();
|
OnPhysics2DStop();
|
||||||
|
|
||||||
// script
|
// script
|
||||||
@ -293,7 +295,7 @@ namespace Hazel
|
|||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
m_Registry.view<NativeScriptComponent>().each([=](auto entity, auto& nsc)
|
m_Registry.view<NativeScriptComponent>().each([=, this](auto entity, auto& nsc)
|
||||||
{
|
{
|
||||||
// TODO: move to Scene::OnScenePlay
|
// TODO: move to Scene::OnScenePlay
|
||||||
if (!nsc.Instance)
|
if (!nsc.Instance)
|
||||||
|
|||||||
@ -47,6 +47,8 @@ namespace Hazel
|
|||||||
Entity GetPrimaryCameraEntity();
|
Entity GetPrimaryCameraEntity();
|
||||||
Entity GetEntityByUUID(UUID uuid);
|
Entity GetEntityByUUID(UUID uuid);
|
||||||
|
|
||||||
|
bool IsRunning() const {return m_IsRunning; }
|
||||||
|
|
||||||
template<typename... Components>
|
template<typename... Components>
|
||||||
auto GetAllEntitiesWith()
|
auto GetAllEntitiesWith()
|
||||||
{
|
{
|
||||||
@ -69,6 +71,8 @@ namespace Hazel
|
|||||||
|
|
||||||
b2WorldId* m_PhysicsWorld = nullptr;
|
b2WorldId* m_PhysicsWorld = nullptr;
|
||||||
|
|
||||||
|
bool m_IsRunning = false;
|
||||||
|
|
||||||
std::unordered_map<UUID, entt::entity> m_EnttMap;
|
std::unordered_map<UUID, entt::entity> m_EnttMap;
|
||||||
|
|
||||||
friend class Entity;
|
friend class Entity;
|
||||||
|
|||||||
@ -8,10 +8,29 @@
|
|||||||
|
|
||||||
#include "Components.h"
|
#include "Components.h"
|
||||||
#include "Entity.h"
|
#include "Entity.h"
|
||||||
|
#include "Hazel/Scripting/ScriptEngine.h"
|
||||||
#include "yaml-cpp/yaml.h"
|
#include "yaml-cpp/yaml.h"
|
||||||
|
|
||||||
namespace YAML
|
namespace YAML
|
||||||
{
|
{
|
||||||
|
template<>
|
||||||
|
struct convert<Hazel::UUID>
|
||||||
|
{
|
||||||
|
static Node encode(const Hazel::UUID& out)
|
||||||
|
{
|
||||||
|
Node node;
|
||||||
|
node.push_back((uint64_t)out);
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool decode(const Node& node, Hazel::UUID& uuid)
|
||||||
|
{
|
||||||
|
uuid = node.as<uint64_t>();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
struct convert<glm::vec2>
|
struct convert<glm::vec2>
|
||||||
{
|
{
|
||||||
@ -208,6 +227,64 @@ namespace Hazel
|
|||||||
|
|
||||||
out << YAML::BeginMap; // ScriptComponent
|
out << YAML::BeginMap; // ScriptComponent
|
||||||
out << YAML::Key << "ClassName" << YAML::Value << scriptComponent.ClassName;
|
out << YAML::Key << "ClassName" << YAML::Value << scriptComponent.ClassName;
|
||||||
|
|
||||||
|
// fields
|
||||||
|
Ref<ScriptClass> entityClass = ScriptEngine::GetEntityClass(scriptComponent.ClassName);
|
||||||
|
const auto& fields = entityClass->GetFields();
|
||||||
|
if (fields.size() > 0)
|
||||||
|
{
|
||||||
|
auto& entityFields = ScriptEngine::GetScriptFieldMap(entity);
|
||||||
|
out << YAML::Key << "ScriptFields" << YAML::Value;
|
||||||
|
|
||||||
|
out << YAML::BeginSeq;
|
||||||
|
for (const auto& [name, field] : fields)
|
||||||
|
{
|
||||||
|
if (!entityFields.contains(name))
|
||||||
|
continue;
|
||||||
|
// - Name: FieldName
|
||||||
|
// Type: Int
|
||||||
|
// Data: 5
|
||||||
|
|
||||||
|
|
||||||
|
out << YAML::BeginMap; // Script Field
|
||||||
|
out << YAML::Key << "Name" << YAML::Value << name;
|
||||||
|
out << YAML::Key << "Type" << YAML::Value << Utils::ScriptFieldTypeToString(field.Type);
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
WRITE_FIELD_TYPE(Float, float);
|
||||||
|
WRITE_FIELD_TYPE(Double, double);
|
||||||
|
WRITE_FIELD_TYPE(Boolean, bool);
|
||||||
|
WRITE_FIELD_TYPE(Char, char);
|
||||||
|
WRITE_FIELD_TYPE(Byte, int8_t);
|
||||||
|
WRITE_FIELD_TYPE(Short, int16_t);
|
||||||
|
WRITE_FIELD_TYPE(Int, int32_t);
|
||||||
|
WRITE_FIELD_TYPE(Long, int64_t);
|
||||||
|
WRITE_FIELD_TYPE(UByte, uint8_t);
|
||||||
|
WRITE_FIELD_TYPE(UShort, uint16_t);
|
||||||
|
WRITE_FIELD_TYPE(UInt, uint32_t);
|
||||||
|
WRITE_FIELD_TYPE(ULong, uint64_t);
|
||||||
|
|
||||||
|
WRITE_FIELD_TYPE(Vector2, glm::vec2);
|
||||||
|
WRITE_FIELD_TYPE(Vector3, glm::vec3);
|
||||||
|
WRITE_FIELD_TYPE(Vector4, glm::vec4);
|
||||||
|
|
||||||
|
WRITE_FIELD_TYPE(Entity, UUID);
|
||||||
|
}
|
||||||
|
|
||||||
|
out << YAML::EndMap;
|
||||||
|
#undef WRITE_FIELD_TYPE
|
||||||
|
}
|
||||||
|
out << YAML::EndSeq;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
out << YAML::EndMap; // ScriptComponent
|
out << YAML::EndMap; // ScriptComponent
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -401,6 +478,58 @@ namespace Hazel
|
|||||||
{
|
{
|
||||||
auto& sc = deserializedEntity.AddComponent<ScriptComponent>();
|
auto& sc = deserializedEntity.AddComponent<ScriptComponent>();
|
||||||
sc.ClassName = scriptComponent["ClassName"].as<std::string>();
|
sc.ClassName = scriptComponent["ClassName"].as<std::string>();
|
||||||
|
|
||||||
|
auto scriptFields = scriptComponent["ScriptFields"];
|
||||||
|
if (scriptFields)
|
||||||
|
{
|
||||||
|
Ref<ScriptClass> entityClass = ScriptEngine::GetEntityClass(sc.ClassName);
|
||||||
|
const auto& fields = entityClass->GetFields();
|
||||||
|
auto& entityFields = ScriptEngine::GetScriptFieldMap(deserializedEntity);
|
||||||
|
|
||||||
|
for (auto scriptField: scriptFields)
|
||||||
|
{
|
||||||
|
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];
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto spriteRendererComponent = entity["SpriteRendererComponent"];
|
auto spriteRendererComponent = entity["SpriteRendererComponent"];
|
||||||
|
|||||||
@ -122,34 +122,6 @@ namespace Hazel
|
|||||||
}
|
}
|
||||||
return s_ScriptFieldTypeMap.at(typeName);
|
return s_ScriptFieldTypeMap.at(typeName);
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* ScriptFieldTypeToString(ScriptFieldType type)
|
|
||||||
{
|
|
||||||
switch (type)
|
|
||||||
{
|
|
||||||
case ScriptFieldType::Float: return "Float";
|
|
||||||
case ScriptFieldType::Double: return "Double";
|
|
||||||
case ScriptFieldType::Boolean: return "Boolean";
|
|
||||||
case ScriptFieldType::Byte: return "Byte";
|
|
||||||
case ScriptFieldType::Char: return "Char";
|
|
||||||
case ScriptFieldType::Short: return "Short";
|
|
||||||
case ScriptFieldType::Int: return "Int";
|
|
||||||
case ScriptFieldType::Long: return "Long";
|
|
||||||
case ScriptFieldType::UByte: return "UByte";
|
|
||||||
case ScriptFieldType::UShort: return "UShort";
|
|
||||||
case ScriptFieldType::UInt: return "UInt";
|
|
||||||
case ScriptFieldType::ULong: return "ULong";
|
|
||||||
|
|
||||||
case ScriptFieldType::Entity: return "Entity";
|
|
||||||
|
|
||||||
case ScriptFieldType::Vector2: return "Vector2";
|
|
||||||
case ScriptFieldType::Vector3: return "Vector3";
|
|
||||||
case ScriptFieldType::Vector4: return "Vector4";
|
|
||||||
}
|
|
||||||
|
|
||||||
return "<Invalid>";
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ScriptEngineData
|
struct ScriptEngineData
|
||||||
@ -168,6 +140,8 @@ namespace Hazel
|
|||||||
std::unordered_map<std::string, Ref<ScriptClass>> EntityClasses;
|
std::unordered_map<std::string, Ref<ScriptClass>> EntityClasses;
|
||||||
std::unordered_map<UUID, Ref<ScriptInstance>> EntityInstances;
|
std::unordered_map<UUID, Ref<ScriptInstance>> EntityInstances;
|
||||||
|
|
||||||
|
std::unordered_map<UUID, ScriptFieldMap> EntityScriptFields;
|
||||||
|
|
||||||
// runtime
|
// runtime
|
||||||
Scene* SceneContext = nullptr;
|
Scene* SceneContext = nullptr;
|
||||||
};
|
};
|
||||||
@ -306,6 +280,18 @@ namespace Hazel
|
|||||||
return s_Data->EntityClasses;
|
return s_Data->EntityClasses;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Ref<ScriptClass> ScriptEngine::GetEntityClass(const std::string& name)
|
||||||
|
{
|
||||||
|
if (!s_Data->EntityClasses.contains(name))
|
||||||
|
return nullptr;
|
||||||
|
return s_Data->EntityClasses.at(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
ScriptFieldMap& ScriptEngine::GetScriptFieldMap(Entity entity)
|
||||||
|
{
|
||||||
|
return s_Data->EntityScriptFields[entity.GetUUID()];
|
||||||
|
}
|
||||||
|
|
||||||
void ScriptEngine::OnRuntimeStart(Scene* scene)
|
void ScriptEngine::OnRuntimeStart(Scene* scene)
|
||||||
{
|
{
|
||||||
s_Data->SceneContext = scene;
|
s_Data->SceneContext = scene;
|
||||||
@ -328,8 +314,18 @@ namespace Hazel
|
|||||||
const auto& sc = entity.GetComponent<ScriptComponent>();
|
const auto& sc = entity.GetComponent<ScriptComponent>();
|
||||||
if (ClassExists(sc.ClassName))
|
if (ClassExists(sc.ClassName))
|
||||||
{
|
{
|
||||||
|
UUID entityID = entity.GetUUID();
|
||||||
Ref<ScriptInstance> instance = CreateRef<ScriptInstance>(s_Data->EntityClasses[sc.ClassName], entity);
|
Ref<ScriptInstance> instance = CreateRef<ScriptInstance>(s_Data->EntityClasses[sc.ClassName], entity);
|
||||||
s_Data->EntityInstances[entity.GetUUID()] = instance;
|
s_Data->EntityInstances[entityID] = instance;
|
||||||
|
|
||||||
|
// copy Field value
|
||||||
|
if (s_Data->EntityScriptFields.contains(entityID))
|
||||||
|
{
|
||||||
|
const ScriptFieldMap& fieldMap = s_Data->EntityScriptFields.at(entityID);
|
||||||
|
|
||||||
|
for (const auto& [name, fieldInstance] : fieldMap)
|
||||||
|
instance->SetFieldValueInternal(name, fieldInstance.m_Buffer);
|
||||||
|
}
|
||||||
|
|
||||||
instance->InvokeOnCreate();
|
instance->InvokeOnCreate();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -41,6 +41,36 @@ namespace Hazel
|
|||||||
MonoClassField* ClassField;
|
MonoClassField* ClassField;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct ScriptFieldInstance
|
||||||
|
{
|
||||||
|
ScriptField Field;
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
T GetValue()
|
||||||
|
{
|
||||||
|
return *(T*)m_Buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
void SetValue(T data)
|
||||||
|
{
|
||||||
|
if constexpr (sizeof(T) <= 8)
|
||||||
|
memcpy(m_Buffer, &data, sizeof(T));
|
||||||
|
else
|
||||||
|
{
|
||||||
|
HZ_CLIENT_ERROR("Type to large: sizeof(data): {} bytes", sizeof(T));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
uint8_t m_Buffer[8] = {};
|
||||||
|
|
||||||
|
friend class ScriptEngine;
|
||||||
|
friend class ScriptInstance;
|
||||||
|
};
|
||||||
|
|
||||||
|
using ScriptFieldMap = std::unordered_map<std::string, ScriptFieldInstance>;
|
||||||
|
|
||||||
class ScriptClass
|
class ScriptClass
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -103,6 +133,9 @@ namespace Hazel
|
|||||||
MonoMethod* m_OnUpdateMethod = nullptr;
|
MonoMethod* m_OnUpdateMethod = nullptr;
|
||||||
|
|
||||||
inline static char s_FieldValueBuffer[8];
|
inline static char s_FieldValueBuffer[8];
|
||||||
|
|
||||||
|
friend class ScriptEngine;
|
||||||
|
friend struct ScriptFieldInstance;
|
||||||
};
|
};
|
||||||
|
|
||||||
class ScriptEngine
|
class ScriptEngine
|
||||||
@ -126,6 +159,8 @@ namespace Hazel
|
|||||||
static Ref<ScriptInstance> GetEntityScriptInstance(UUID entityID);
|
static Ref<ScriptInstance> GetEntityScriptInstance(UUID entityID);
|
||||||
|
|
||||||
static std::unordered_map<std::string, Ref<ScriptClass>> GetEntityClasses();
|
static std::unordered_map<std::string, Ref<ScriptClass>> GetEntityClasses();
|
||||||
|
static Ref<ScriptClass> GetEntityClass(const std::string& name);
|
||||||
|
static ScriptFieldMap& GetScriptFieldMap(Entity entity);
|
||||||
|
|
||||||
static MonoImage* GetCoreAssemblyImage();
|
static MonoImage* GetCoreAssemblyImage();
|
||||||
|
|
||||||
@ -139,6 +174,57 @@ namespace Hazel
|
|||||||
friend class ScriptClass;
|
friend class ScriptClass;
|
||||||
friend class ScriptGlue;
|
friend class ScriptGlue;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
namespace Utils
|
||||||
|
{
|
||||||
|
inline const char* ScriptFieldTypeToString(const ScriptFieldType fieldType)
|
||||||
|
{
|
||||||
|
switch (fieldType)
|
||||||
|
{
|
||||||
|
case ScriptFieldType::Char: return "Char";
|
||||||
|
case ScriptFieldType::Float: return "Float";
|
||||||
|
case ScriptFieldType::Double: return "Double";
|
||||||
|
case ScriptFieldType::Vector2: return "Vector2";
|
||||||
|
case ScriptFieldType::Vector3: return "Vector3";
|
||||||
|
case ScriptFieldType::Vector4: return "Vector4";
|
||||||
|
case ScriptFieldType::Byte: return "Byte";
|
||||||
|
case ScriptFieldType::Short: return "Short";
|
||||||
|
case ScriptFieldType::Int: return "Int";
|
||||||
|
case ScriptFieldType::Long: return "Long";
|
||||||
|
case ScriptFieldType::Boolean: return "Boolean";
|
||||||
|
case ScriptFieldType::UByte: return "UByte";
|
||||||
|
case ScriptFieldType::UShort: return "UShort";
|
||||||
|
case ScriptFieldType::UInt: return "UInt";
|
||||||
|
case ScriptFieldType::ULong: return "ULong";
|
||||||
|
case ScriptFieldType::Entity: return "Entity";
|
||||||
|
}
|
||||||
|
HZ_CORE_ERROR("Unknown scriptFieldType");
|
||||||
|
return "None";
|
||||||
|
}
|
||||||
|
|
||||||
|
inline ScriptFieldType ScriptFieldTypeFromString(const std::string& fieldType)
|
||||||
|
{
|
||||||
|
if(fieldType == "Char") return ScriptFieldType::Char;
|
||||||
|
if(fieldType == "Float") return ScriptFieldType::Float;
|
||||||
|
if(fieldType == "Double") return ScriptFieldType::Double;
|
||||||
|
if(fieldType == "Vector2") return ScriptFieldType::Vector2;
|
||||||
|
if(fieldType == "Vector3") return ScriptFieldType::Vector3;
|
||||||
|
if(fieldType == "Vector4") return ScriptFieldType::Vector4;
|
||||||
|
if(fieldType == "Byte") return ScriptFieldType::Byte;
|
||||||
|
if(fieldType == "Short") return ScriptFieldType::Short;
|
||||||
|
if(fieldType == "Int") return ScriptFieldType::Int;
|
||||||
|
if(fieldType == "Long") return ScriptFieldType::Long;
|
||||||
|
if(fieldType == "Boolean") return ScriptFieldType::Boolean;
|
||||||
|
if(fieldType == "UByte") return ScriptFieldType::UByte;
|
||||||
|
if(fieldType == "UShort") return ScriptFieldType::UShort;
|
||||||
|
if(fieldType == "UInt") return ScriptFieldType::UInt;
|
||||||
|
if(fieldType == "ULong") return ScriptFieldType::ULong;
|
||||||
|
if(fieldType == "Entity") return ScriptFieldType::Entity;
|
||||||
|
|
||||||
|
HZ_CORE_ERROR("Unknown scriptFieldType");
|
||||||
|
return ScriptFieldType::None;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -18,7 +18,7 @@ namespace Hazel
|
|||||||
|
|
||||||
static std::unordered_map<MonoType*, std::function<bool(Entity)>> s_EntityHasComponentFuncs;
|
static std::unordered_map<MonoType*, std::function<bool(Entity)>> s_EntityHasComponentFuncs;
|
||||||
|
|
||||||
#define HZ_ADD_INTERNAL_CALL(Name) mono_add_internal_call("Hazel.InternalCalls::" #Name, Name)
|
#define HZ_ADD_INTERNAL_CALL(Name) mono_add_internal_call("Hazel.InternalCalls::" #Name, reinterpret_cast<const void*>(Name))
|
||||||
|
|
||||||
static void NativeLog(MonoString* text, int param)
|
static void NativeLog(MonoString* text, int param)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user