diff --git a/Nuake/src/Scripting/NetModules/EngineNetAPI.cpp b/Nuake/src/Scripting/NetModules/EngineNetAPI.cpp index 247bc844..4b9725aa 100644 --- a/Nuake/src/Scripting/NetModules/EngineNetAPI.cpp +++ b/Nuake/src/Scripting/NetModules/EngineNetAPI.cpp @@ -9,7 +9,7 @@ namespace Nuake { void EngineNetAPI::RegisterMethods() { - RegisterMethod("LoggerLogIcall", (void*)(&Log)); + RegisterMethod("Engine.LoggerLogIcall", (void*)(&Log)); } } diff --git a/Nuake/src/Scripting/NetModules/InputNetAPI.cpp b/Nuake/src/Scripting/NetModules/InputNetAPI.cpp new file mode 100644 index 00000000..44e0d214 --- /dev/null +++ b/Nuake/src/Scripting/NetModules/InputNetAPI.cpp @@ -0,0 +1,28 @@ +#include "InputNetAPI.h" + +#include "src/Core/Input.h" + +#include + +namespace Nuake { + + bool IsKeyDown(int keyCode) + { + return Input::IsKeyDown(keyCode); + } + + Coral::NativeArray GetMousePosition() + { + Vector2 mousePosition = Input::GetMousePosition(); + return { mousePosition.x, mousePosition.y}; + } + + + void InputNetAPI::RegisterMethods() + { + RegisterMethod("Input.IsKeyDownIcall", &IsKeyDown); + RegisterMethod("Input.GetMousePositionIcall", &GetMousePosition); + } + +} + diff --git a/Nuake/src/Scripting/NetModules/InputNetAPI.h b/Nuake/src/Scripting/NetModules/InputNetAPI.h new file mode 100644 index 00000000..f63c89e6 --- /dev/null +++ b/Nuake/src/Scripting/NetModules/InputNetAPI.h @@ -0,0 +1,14 @@ +#pragma once +#include "NetAPIModule.h" + +namespace Nuake { + + class InputNetAPI : public NetAPIModule + { + public: + virtual const std::string GetModuleName() const override { return "Input"; } + + virtual void RegisterMethods() override; + + }; +} \ No newline at end of file diff --git a/Nuake/src/Scripting/NetModules/SceneNetAPI.cpp b/Nuake/src/Scripting/NetModules/SceneNetAPI.cpp new file mode 100644 index 00000000..5307bfa6 --- /dev/null +++ b/Nuake/src/Scripting/NetModules/SceneNetAPI.cpp @@ -0,0 +1,108 @@ +#include "SceneNetAPI.h" + +#include "Engine.h" +#include "src/Scene/Entities/Entity.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +namespace Nuake { + + uint32_t GetEntity(Coral::NativeString entityName) + { + auto scene = Engine::GetCurrentScene(); + + std::string entityNameString = entityName.ToString(); + if (!scene->EntityExists(entityNameString)) + { + return UINT32_MAX; // Error code: entity not found. + } + + return scene->GetEntity(entityNameString).GetHandle(); + } + + static enum ComponentTypes + { + Unknown = -1, + PARENT = 0, + NAME, + PREFAB, + TRANSFORM, + LIGHT, + CAMERA, + AUDIO_EMITTER, + MODEL, + SKINNED_MODEL, + BONE, + RIGIDBODY, + BOX_COLLIDER, + SPHERE_COLLIDER, + CAPSULE_COLLIDER, + CYLINDER_COLLIDER, + MESH_COLLIDER, + CHARACTER_CONTROLLER, + PARTICLE_EMITTER, + QUAKE_MAP, + BSP_BRUSH, + SPRITE + }; + + bool EntityHasComponent(uint32_t handle, uint32_t componentEnumValue) + { + Entity entity = { (entt::entity)handle, Engine::GetCurrentScene().get()}; + + if (entity.IsValid()) + { + return false; + } + + switch (static_cast(componentEnumValue)) + { + case PARENT: return entity.HasComponent(); + case NAME: return entity.HasComponent(); + case PREFAB: return entity.HasComponent(); + case TRANSFORM: return entity.HasComponent(); + case LIGHT: return entity.HasComponent(); + case CAMERA: return entity.HasComponent(); + case AUDIO_EMITTER: return entity.HasComponent(); + case MODEL: return entity.HasComponent(); + case SKINNED_MODEL: return entity.HasComponent(); + case BONE: return entity.HasComponent(); + case BOX_COLLIDER: return entity.HasComponent(); + case SPHERE_COLLIDER: return entity.HasComponent(); + case CAPSULE_COLLIDER: return entity.HasComponent(); + case CYLINDER_COLLIDER: return entity.HasComponent(); + case MESH_COLLIDER: return entity.HasComponent(); + case CHARACTER_CONTROLLER: return entity.HasComponent(); + case PARTICLE_EMITTER: return entity.HasComponent(); + case QUAKE_MAP: return entity.HasComponent(); + case BSP_BRUSH: return entity.HasComponent(); + case SPRITE: return entity.HasComponent(); + default: + return false; + } + } + + void Nuake::SceneNetAPI::RegisterMethods() + { + RegisterMethod("Entity.EntityHasComponentIcall", &EntityHasComponent); + RegisterMethod("Scene.GetEntityIcall", &GetEntity); + } + +} + diff --git a/Nuake/src/Scripting/NetModules/SceneNetAPI.h b/Nuake/src/Scripting/NetModules/SceneNetAPI.h new file mode 100644 index 00000000..c9e7de32 --- /dev/null +++ b/Nuake/src/Scripting/NetModules/SceneNetAPI.h @@ -0,0 +1,14 @@ +#pragma once +#include "NetAPIModule.h" + +namespace Nuake { + + class SceneNetAPI : public NetAPIModule + { + public: + virtual const std::string GetModuleName() const override { return "Scene"; } + + virtual void RegisterMethods() override; + + }; +} \ No newline at end of file diff --git a/Nuake/src/Scripting/ScriptingEngineNet.cpp b/Nuake/src/Scripting/ScriptingEngineNet.cpp index e6f1a542..d24fcb8d 100644 --- a/Nuake/src/Scripting/ScriptingEngineNet.cpp +++ b/Nuake/src/Scripting/ScriptingEngineNet.cpp @@ -4,14 +4,16 @@ #include "src/Core/FileSystem.h" #include "src/Core/OS.h" #include "src/Resource/Project.h" +#include "src/Scene/Components/NetScriptComponent.h" #include "NetModules/EngineNetAPI.h" +#include "NetModules/InputNetAPI.h" +#include "NetModules/SceneNetAPI.h" #include #include #include #include -#include void ExceptionCallback(std::string_view InMessage) @@ -20,19 +22,29 @@ void ExceptionCallback(std::string_view InMessage) Nuake::Logger::Log(message, ".net", Nuake::CRITICAL); } + namespace Nuake { ScriptingEngineNet::ScriptingEngineNet() { // Initialize Coral // ---------------------------------- - + Coral::HostSettings settings = + { + .CoralDirectory = "", + .ExceptionCallback = ExceptionCallback + }; + + m_HostInstance = new Coral::HostInstance(); + m_HostInstance->Initialize(settings); // Initialize API modules // ---------------------------------- m_Modules = { - CreateRef() + CreateRef(), + CreateRef(), + CreateRef() }; for (auto& m : m_Modules) @@ -54,16 +66,7 @@ namespace Nuake void ScriptingEngineNet::Initialize() { - Coral::HostSettings settings = - { - .CoralDirectory = "", - .ExceptionCallback = ExceptionCallback - }; - - m_HostInstance = new Coral::HostInstance(); - m_HostInstance->Initialize(settings); - - m_LoadContext = std::move(m_HostInstance->CreateAssemblyLoadContext(m_ContextName)); + m_LoadContext = m_HostInstance->CreateAssemblyLoadContext(m_ContextName); // Load Nuake assembly DLL const std::string absoluteAssemblyPath = FileSystem::Root + m_NetDirectory + "/" + m_EngineAssemblyName; @@ -73,10 +76,10 @@ namespace Nuake // -------------------------------------------------- for (const auto& netModule : m_Modules) { - const std::string inClassName = m_Scope + '.' + netModule->GetModuleName(); for (const auto& [methodName, methodPtr] : netModule->GetMethods()) { - m_NuakeAssembly.AddInternalCall(inClassName, methodName, methodPtr); + auto namespaceClassSplit = String::Split(methodName, '.'); + m_NuakeAssembly.AddInternalCall(m_Scope + '.' + namespaceClassSplit[0], namespaceClassSplit[1], methodPtr); } } @@ -85,19 +88,17 @@ namespace Nuake void ScriptingEngineNet::Uninitialize() { - // We have to manually destroy every managed object we have created for (auto& [entity, managedObject] : m_EntityToManagedObjects) { managedObject.Destroy(); } - Coral::GC::Collect(1, Coral::GCCollectionMode::Forced); - Coral::GC::WaitForPendingFinalizers(); + m_GameEntityTypes.clear(); + Coral::GC::Collect(); m_HostInstance->UnloadAssemblyLoadContext(m_LoadContext); m_EntityToManagedObjects.clear(); - m_GameEntityTypes.clear(); } void ScriptingEngineNet::LoadProjectAssembly(Ref project) diff --git a/NuakeNet/src/main.cs b/NuakeNet/src/main.cs index b6839ff7..9de901ba 100644 --- a/NuakeNet/src/main.cs +++ b/NuakeNet/src/main.cs @@ -3,6 +3,8 @@ using Coral.Managed.Interop; using System; using System.Collections.Generic; using System.Drawing; +using System.Numerics; +using System.Runtime.InteropServices; namespace Nuake.Net { @@ -58,13 +60,197 @@ namespace Nuake.Net } } + // Input + public enum Key + { + SPACE = 32, + APOSTROPHE = 39, + COMMA = 44, + MINUS = 45, + PERIOD = 46, + SLASH = 47, + NUM0 = 48, + NUM1 = 49, + NUM2 = 50, + NUM3 = 51, + NUM4 = 52, + NUM5 = 53, + NUM6 = 54, + NUM7 = 55, + NUM8 = 56, + NUM9 = 57, + SEMICOLON = 59, + EQUAL = 61, + A = 65, + B = 66, + C = 67, + D = 68, + E = 69, + F = 70, + G = 71, + H = 72, + I = 73, + J = 74, + K = 75, + L = 76, + M = 77, + N = 78, + O = 79, + P = 80, + Q = 81, + R = 82, + S = 83, + T = 84, + U = 85, + V = 86, + W = 87, + X = 88, + Y = 89, + Z = 90, + LEFT_BRACKET = 91, + BACKSLASH = 92, + RIGHT_BRACKET = 93, + GRAVE_ACCENT = 96, + WORLD_1 = 161, + WORLD_2 = 162, + ESCAPE = 256, + ENTER = 257, + TAB = 258, + BACKSPACE = 259, + INSERT = 260, + DELETE = 261, + RIGHT = 262, + LEFT = 263, + DOWN = 264, + UP = 265, + PAGE_UP = 266, + PAGE_DOWN = 267, + HOME = 268, + END = 269, + CAPS_LOCK = 280, + SCROLL_LOCK = 281, + NUM_LOCK = 282, + PRINT_SCREEN = 283, + PAUSE = 284, + F1 = 290, + F2 = 291, + F3 = 292, + F4 = 293, + F5 = 294, + F6 = 295, + F7 = 296, + F8 = 297, + F9 = 298, + F10 = 299, + F11 = 300, + F12 = 301, + F13 = 302, + F14 = 303, + F15 = 304, + F16 = 305, + F17 = 306, + F18 = 307, + F19 = 308, + F20 = 309, + F21 = 310, + F22 = 311, + F23 = 312, + F24 = 313, + F25 = 314, + KP_0 = 320, + KP_1 = 321, + KP_2 = 322, + KP_3 = 323, + KP_4 = 324, + KP_5 = 325, + KP_6 = 326, + KP_7 = 327, + KP_8 = 328, + KP_9 = 329, + KP_DECIMAL = 330, + KP_DIVIDE = 331, + KP_MULTIPLY = 332, + KP_SUBTRACT = 333, + KP_ADD = 334, + KP_ENTER = 335, + KP_EQUAL = 336, + LEFT_SHIFT = 340, + LEFT_CONTROL = 341, + LEFT_ALT = 342, + LEFT_SUPER = 343, + RIGHT_SHIFT = 344, + RIGHT_CONTROL = 345, + RIGHT_ALT = 346, + RIGHT_SUPER = 347, + MENU = 348, + } + + public class Input + { + internal static unsafe delegate* IsKeyDownIcall; + internal static unsafe delegate*> GetMousePositionIcall; + + public static bool IsKeyDown(Key keys) + { + unsafe { return IsKeyDownIcall((int)keys); } + } + + public static Vector2 GetMousePosition() + { + NativeArray result; + unsafe { result = GetMousePositionIcall(); } + + return new Vector2(result[0], result[1]); + } + } + + public class Scene + { + internal static unsafe delegate* GetEntityIcall; + + public static Entity GetEntity(string entityName) + { + + uint handle; + unsafe { handle = GetEntityIcall(entityName); } + + if(handle == UInt32.MaxValue) + { + throw new Exception("Entity not found"); + } + + Entity entity = new Entity(); + entity.ECSHandle = handle; + return entity; + } + } + public class IComponent { public UInt32 EntityID { get; protected set; } } + public class ParentComponent : IComponent + { + public ParentComponent(UInt32 entityId) { } + public Entity Parent { get; set; } + public List Children { get; set; } + } + public class NameComponent : IComponent + { + public NameComponent(UInt32 entityId) + { + EntityID = entityId; + } + public string Name { get; set; } + } + public class PrefabComponent : IComponent + { + public PrefabComponent(UInt32 entityId) { } + public string Prefab { get; set; } + } public class TransformComponent : IComponent { public TransformComponent(UInt32 entityId) @@ -109,9 +295,9 @@ namespace Nuake.Net public float FOV { get; set; } } - public class AudioEmitter : IComponent + public class AudioEmitterComponent : IComponent { - public AudioEmitter(UInt32 entityId) + public AudioEmitterComponent(UInt32 entityId) { EntityID = entityId; } @@ -123,6 +309,24 @@ namespace Nuake.Net public bool Playing { get; set; } } + public class ModelComponent : IComponent + { + public ModelComponent(UInt32 entityId) + { + EntityID = entityId; + } + + public string Mesh { get; set; } + } + + public class SkinnedModelComponent : IComponent + { + public SkinnedModelComponent(UInt32 entityId) { } + + public bool Playing { get; set; } + public int CurrentAnimation { get; set; } + } + public class BoneComponent : IComponent { public BoneComponent(UInt32 entityId) @@ -132,6 +336,12 @@ namespace Nuake.Net public string Name { get; set; } } + public class RigidbodyComponent : IComponent + { + public RigidbodyComponent(UInt32 entityId) { } + + public float Mass { get; set; } + } public class BoxCollider : IComponent { @@ -143,14 +353,17 @@ namespace Nuake.Net public Vector3 Scale { get; set; } } - public class BSPBrushComponent : IComponent + public class SphereCollider : IComponent { - public BSPBrushComponent(UInt32 entityId) + public SphereCollider(UInt32 entityId) { EntityID = entityId; } + + public float Radius { get; set; } } + public class CapsuleColliderComponent : IComponent { public CapsuleColliderComponent(UInt32 entityId) @@ -161,6 +374,25 @@ namespace Nuake.Net public float Radius { get; set; } public float Height { get; set; } } + public class CylinderColliderComponent : IComponent + { + public CylinderColliderComponent(UInt32 entityId) + { + EntityID = entityId; + } + + public float Radius { get; set; } + public float Height { get; set; } + } + public class MeshColliderComponent : IComponent + { + public MeshColliderComponent(UInt32 entityId) + { + EntityID = entityId; + } + + public int Mesh { get; set; } + } public class CharacterControllerComponent : IComponent { @@ -180,55 +412,6 @@ namespace Nuake.Net } } - public class CylinderColliderComponent : IComponent - { - public CylinderColliderComponent(UInt32 entityId) - { - EntityID = entityId; - } - - public float Radius { get; set; } - public float Height { get; set; } - } - - public class MeshColliderComponent : IComponent - { - public MeshColliderComponent(UInt32 entityId) - { - EntityID = entityId; - } - - public int Mesh { get; set; } - } - - public class ModelComponent : IComponent - { - public ModelComponent(UInt32 entityId) - { - EntityID = entityId; - } - - public string Mesh { get; set; } - } - - public class NameComponent : IComponent - { - public NameComponent(UInt32 entityId) - { - EntityID = entityId; - } - - public string Name { get; set; } - } - - public class ParentComponent : IComponent - { - public ParentComponent(UInt32 entityId) { } - - public Entity Parent{ get; set; } - public List Children { get; set;} - } - public class ParticleEmitterComponent : IComponent { public ParticleEmitterComponent(UInt32 entityId) { } @@ -237,47 +420,23 @@ namespace Nuake.Net public float Life { get; set; } public Vector3 Gravity { get; set; } } - - public class PrefabComponent : IComponent - { - public PrefabComponent(UInt32 entityId) { } - - public string Prefab { get; set; } - } - public class QuakeMapComponent : IComponent { public QuakeMapComponent(UInt32 entityId) { } public string Map { get; set; } - public bool BuildCollisions { get; set; } + public bool BuildCollisions { get; set; } public void Build() { } } - - public class RigidbodyComponent : IComponent + public class BSPBrushComponent : IComponent { - public RigidbodyComponent(UInt32 entityId) { } - - public float Mass { get; set; } + public BSPBrushComponent(UInt32 entityId) + { + EntityID = entityId; + } } - - public class SkinnedModelComponent : IComponent - { - public SkinnedModelComponent(UInt32 entityId) { } - - public bool Playing { get; set; } - public int CurrentAnimation { get; set; } - } - - public class SphereColliderComponent : IComponent - { - public SphereColliderComponent(UInt32 entityId) { } - - public float Radius { get; set; } - } - public class SpriteComponent : IComponent { public SpriteComponent(UInt32 entityId) { } @@ -285,56 +444,87 @@ namespace Nuake.Net public string Sprite { get; set; } } - public class WrenScriptComponent : IComponent - { - public WrenScriptComponent(UInt32 entityId) { } - - public string Script { get; set; } - } public class Entity { - internal static unsafe delegate* EntityHasComponentIcall; + internal static unsafe delegate* EntityHasComponentIcall; + + public enum ComponentTypes + { + Unknown = -1, + PARENT = 0, + NAME, + PREFAB, + TRANSFORM, + LIGHT, + CAMERA, + AUDIO_EMITTER, + MODEL, + SKINNED_MODEL, + BONE, + RIGIDBODY, + BOX_COLLIDER, + SPHERE_COLLIDER, + CAPSULE_COLLIDER, + CYLINDER_COLLIDER, + MESH_COLLIDER, + CHARACTER_CONTROLLER, + PARTICLE_EMITTER, + QUAKE_MAP, + BSP_BRUSH, + SPRITE + } public UInt32 ID { get; private set; } - + public UInt32 ECSHandle { get; set; } public virtual void OnInit() { } public virtual void OnUpdate(float dt) { } public virtual void OnFixedUpdate(float dt) { } public virtual void OnDestroy() { } - public bool HasComponent() + protected static Dictionary MappingTypeEnum = new Dictionary() + { + { typeof(ParentComponent), ComponentTypes.PARENT }, + { typeof(NameComponent), ComponentTypes.NAME }, + { typeof(PrefabComponent), ComponentTypes.PREFAB }, + { typeof(TransformComponent), ComponentTypes.TRANSFORM}, + { typeof(LightComponent), ComponentTypes.LIGHT }, + { typeof(CameraComponent), ComponentTypes.CAMERA }, + { typeof(AudioEmitterComponent), ComponentTypes.AUDIO_EMITTER }, + { typeof(ModelComponent), ComponentTypes.MODEL }, + { typeof(SkinnedModelComponent), ComponentTypes.SKINNED_MODEL }, + { typeof(BoneComponent), ComponentTypes.BONE }, + { typeof(BoxCollider), ComponentTypes.BOX_COLLIDER }, + { typeof(SphereCollider), ComponentTypes.SPHERE_COLLIDER }, + { typeof(CapsuleColliderComponent), ComponentTypes.CAPSULE_COLLIDER }, + { typeof(CylinderColliderComponent), ComponentTypes.CYLINDER_COLLIDER }, + { typeof(MeshColliderComponent), ComponentTypes.MESH_COLLIDER }, + { typeof(CharacterControllerComponent), ComponentTypes.CHARACTER_CONTROLLER }, + { typeof(ParticleEmitterComponent), ComponentTypes.PARTICLE_EMITTER }, + { typeof(QuakeMapComponent), ComponentTypes.QUAKE_MAP }, + { typeof(BSPBrushComponent), ComponentTypes.BSP_BRUSH }, + { typeof(SpriteComponent), ComponentTypes.SPRITE } + }; + + public bool HasComponent() where T : IComponent { - if (typeof(T) == typeof(TransformComponent)) + if(MappingTypeEnum.ContainsKey(typeof(T))) { - unsafe { return EntityHasComponentIcall(ID, typeof(TransformComponent).GetType().Name); }; - } - else if (typeof(T) == typeof(LightComponent)) - { - return true; + unsafe { return EntityHasComponentIcall(ID, (UInt32)ComponentTypes.TRANSFORM); }; } return false; } - public T GetComponent() + public T? GetComponent() where T : IComponent { - if (typeof(T) == typeof(TransformComponent)) + if(HasComponent()) { - return (T)(object)new TransformComponent(ID); - } - else - { - throw new InvalidOperationException("Component not found"); + return (T)Activator.CreateInstance(typeof(T), ID); } + + return null; } } - public class Scene - { - public UInt32 GetEntityIDByName(string name) - { - return 0; - } - } } \ No newline at end of file