Files
ougge/src-csharp/GameObject.cs
2026-01-09 11:57:24 +05:00

96 lines
2.7 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()
{
NativeFunctions.createGameObject(out ulong id, out uint index);
var o = new GameObject(id, index);
Console.WriteLine($"C# created object with id {id}, index {index}");
return o;
}
public void Destroy()
{
if(_isDestroyed)
return;
_isDestroyed = NativeFunctions.freeGameObject(_index);
if(!_isDestroyed)
throw new Exception($"Can't destroy GameObject({_id})");
}
~GameObject()
{
// destroys object native part when managed part is garbage-collected
Destroy();
}
/// <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)
{
Console.WriteLine("C# InvokeUpdate");
Console.WriteLine($"id {_id}, index {_index}, destroyed {_isDestroyed}");
foreach (var p in Components)
{
p.Value.Update(deltaTime);
}
}
}