Added various method to the .Net API

- IsKeyDown
- GetMousePosition
- GetEntity
- HasComponent
- GetComponent
- Added InputKeyCode to C#
This commit is contained in:
Antoine Pilote
2023-10-16 23:41:22 -04:00
parent c3da3fb8f1
commit 1ccd338fc6
7 changed files with 487 additions and 132 deletions

View File

@@ -9,7 +9,7 @@ namespace Nuake {
void EngineNetAPI::RegisterMethods()
{
RegisterMethod("LoggerLogIcall", (void*)(&Log));
RegisterMethod("Engine.LoggerLogIcall", (void*)(&Log));
}
}

View File

@@ -0,0 +1,28 @@
#include "InputNetAPI.h"
#include "src/Core/Input.h"
#include <Coral/NativeArray.hpp>
namespace Nuake {
bool IsKeyDown(int keyCode)
{
return Input::IsKeyDown(keyCode);
}
Coral::NativeArray<float> GetMousePosition()
{
Vector2 mousePosition = Input::GetMousePosition();
return { mousePosition.x, mousePosition.y};
}
void InputNetAPI::RegisterMethods()
{
RegisterMethod("Input.IsKeyDownIcall", &IsKeyDown);
RegisterMethod("Input.GetMousePositionIcall", &GetMousePosition);
}
}

View File

@@ -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;
};
}

View File

@@ -0,0 +1,108 @@
#include "SceneNetAPI.h"
#include "Engine.h"
#include "src/Scene/Entities/Entity.h"
#include <src/Scene/Components/ParentComponent.h>
#include <src/Scene/Components/PrefabComponent.h>
#include <src/Scene/Components/CameraComponent.h>
#include <src/Scene/Components/AudioEmitterComponent.h>
#include <src/Scene/Components/ModelComponent.h>
#include <src/Scene/Components/SkinnedModelComponent.h>
#include <src/Scene/Components/BoneComponent.h>
#include <src/Scene/Components/BoxCollider.h>
#include <src/Scene/Components/SphereCollider.h>
#include <src/Scene/Components/CapsuleColliderComponent.h>
#include <src/Scene/Components/CylinderColliderComponent.h>
#include <src/Scene/Components/MeshCollider.h>
#include <src/Scene/Components/CharacterControllerComponent.h>
#include <src/Scene/Components/ParticleEmitterComponent.h>
#include <src/Scene/Components/BSPBrushComponent.h>
#include <src/Scene/Components/SpriteComponent.h>
#include <src/Scene/Components/QuakeMap.h>
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<ComponentTypes>(componentEnumValue))
{
case PARENT: return entity.HasComponent<ParentComponent>();
case NAME: return entity.HasComponent<NameComponent>();
case PREFAB: return entity.HasComponent<PrefabComponent>();
case TRANSFORM: return entity.HasComponent<TransformComponent>();
case LIGHT: return entity.HasComponent<LightComponent>();
case CAMERA: return entity.HasComponent<CameraComponent>();
case AUDIO_EMITTER: return entity.HasComponent<AudioEmitterComponent>();
case MODEL: return entity.HasComponent<ModelComponent>();
case SKINNED_MODEL: return entity.HasComponent<SkinnedModelComponent>();
case BONE: return entity.HasComponent<BoneComponent>();
case BOX_COLLIDER: return entity.HasComponent<BoxColliderComponent>();
case SPHERE_COLLIDER: return entity.HasComponent<SphereColliderComponent>();
case CAPSULE_COLLIDER: return entity.HasComponent<CapsuleColliderComponent>();
case CYLINDER_COLLIDER: return entity.HasComponent<CylinderColliderComponent>();
case MESH_COLLIDER: return entity.HasComponent<MeshColliderComponent>();
case CHARACTER_CONTROLLER: return entity.HasComponent<CharacterControllerComponent>();
case PARTICLE_EMITTER: return entity.HasComponent<ParticleEmitterComponent>();
case QUAKE_MAP: return entity.HasComponent<QuakeMapComponent>();
case BSP_BRUSH: return entity.HasComponent<BSPBrushComponent>();
case SPRITE: return entity.HasComponent<SpriteComponent>();
default:
return false;
}
}
void Nuake::SceneNetAPI::RegisterMethods()
{
RegisterMethod("Entity.EntityHasComponentIcall", &EntityHasComponent);
RegisterMethod("Scene.GetEntityIcall", &GetEntity);
}
}

View File

@@ -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;
};
}

View File

@@ -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 <Coral/HostInstance.hpp>
#include <Coral/GC.hpp>
#include <Coral/NativeArray.hpp>
#include <Coral/Attribute.hpp>
#include <src/Scene/Components/NetScriptComponent.h>
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<EngineNetAPI>()
CreateRef<EngineNetAPI>(),
CreateRef<InputNetAPI>(),
CreateRef<SceneNetAPI>()
};
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> project)

View File

@@ -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*<int, bool> IsKeyDownIcall;
internal static unsafe delegate*<NativeArray<float>> GetMousePositionIcall;
public static bool IsKeyDown(Key keys)
{
unsafe { return IsKeyDownIcall((int)keys); }
}
public static Vector2 GetMousePosition()
{
NativeArray<float> result;
unsafe { result = GetMousePositionIcall(); }
return new Vector2(result[0], result[1]);
}
}
public class Scene
{
internal static unsafe delegate*<NativeString, UInt32> 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<Entity> 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<Entity> 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*<UInt32, NativeString, bool> EntityHasComponentIcall;
internal static unsafe delegate*<UInt32, UInt32, bool> 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<T>()
protected static Dictionary<Type, ComponentTypes> MappingTypeEnum = new Dictionary<Type, ComponentTypes>()
{
{ 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<T>() 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<T>()
public T? GetComponent<T>() where T : IComponent
{
if (typeof(T) == typeof(TransformComponent))
if(HasComponent<T>())
{
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;
}
}
}