87 lines
2.4 KiB
C#
87 lines
2.4 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Numerics;
|
|
using System.Runtime.InteropServices;
|
|
|
|
namespace Ougge;
|
|
|
|
[StructLayout(LayoutKind.Sequential)]
|
|
public struct Transform
|
|
{
|
|
Vector2 scale;
|
|
Vector2 position;
|
|
float rotation;
|
|
}
|
|
|
|
public class GameObject
|
|
{
|
|
// index in GameObjectPool
|
|
private ulong _id;
|
|
private uint _index;
|
|
private bool _isDestroyed;
|
|
|
|
public ulong Id => _id;
|
|
public bool IsDestroyed => _isDestroyed;
|
|
|
|
public Transform Transform { get; }
|
|
public GameObject? Parent;
|
|
|
|
public Dictionary<Type, Component> Components;
|
|
|
|
private GameObject(ulong id, uint nativePoolIndex)
|
|
{
|
|
_id = id;
|
|
_index = nativePoolIndex;
|
|
// Do not move this line or mono runtime will throw SEGFAULT.
|
|
// Mono runtime can't set values in field declaration, but initializing everything in constructor is OK.
|
|
Components = new();
|
|
}
|
|
|
|
static public GameObject Create()
|
|
{
|
|
NativeMethods.createGameObject(out ulong id, out uint index);
|
|
var o = new GameObject(id, index);
|
|
return o;
|
|
}
|
|
|
|
public void Destroy()
|
|
{
|
|
if(_isDestroyed)
|
|
return;
|
|
|
|
_isDestroyed = NativeMethods.destroyGameObject(_index);
|
|
if(!_isDestroyed)
|
|
throw new Exception($"Can't destroy GameObject({_id})");
|
|
}
|
|
|
|
/// <param name="t">type derived from Component</param>
|
|
/// <returns>true if new component instance was created, false if component of the same tipe is already added to GameObject</returns>
|
|
/// <exception cref="Exception"></exception>
|
|
public bool TryCreateComponent(Type t)
|
|
{
|
|
if(!t.IsSubclassOf(typeof(Component)))
|
|
throw new Exception($"type {t.FullName} is not a derived class of {typeof(Component).FullName}");
|
|
|
|
if(Components.ContainsKey(t))
|
|
return false;
|
|
|
|
Component component = (Component?)Activator.CreateInstance(t, this)
|
|
?? throw new Exception($"can't create instance of class {t.FullName}");
|
|
Components.Add(t, component);
|
|
return true;
|
|
}
|
|
private bool TryCreateComponent_internal(string fullName)
|
|
{
|
|
Type t = Type.GetType(fullName) ?? throw new Exception($"type not found '{fullName}'");
|
|
return TryCreateComponent(t);
|
|
}
|
|
|
|
private void InvokeUpdate(double deltaTime)
|
|
{
|
|
foreach(var p in Components)
|
|
{
|
|
p.Value.Update(deltaTime);
|
|
}
|
|
}
|
|
}
|