You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
82 lines
2.8 KiB
82 lines
2.8 KiB
1 year ago
|
using System.Runtime.CompilerServices;
|
||
|
using System.Runtime.InteropServices;
|
||
|
using gaemstone.ECS;
|
||
|
using gaemstone.Utility;
|
||
|
using static flecs_hub.flecs;
|
||
|
|
||
|
namespace gaemstone.Flecs;
|
||
|
|
||
|
[Module, Path("/flecs/doc")]
|
||
|
public static class Doc
|
||
|
{
|
||
|
[Tag] public struct Brief { }
|
||
|
[Tag] public struct Detail { }
|
||
|
[Tag] public struct Link { }
|
||
|
[Tag] public struct Color { }
|
||
|
|
||
|
[Relation, Component]
|
||
|
public struct Description
|
||
|
{
|
||
|
internal unsafe void* Value;
|
||
|
|
||
|
public override string? ToString()
|
||
|
{ unsafe { return Marshal.PtrToStringUTF8((nint)Value); } }
|
||
|
public static implicit operator string?(Description desc)
|
||
|
=> desc.ToString();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public static unsafe class DocExtensions
|
||
|
{
|
||
|
private static EntityRef Set<T>(EntityRef entity, string? value)
|
||
|
{
|
||
|
var world = entity.World;
|
||
|
var descEntity = world.LookupByTypeOrThrow<Doc.Description>();
|
||
|
var docEntity = world.LookupByTypeOrThrow<T>();
|
||
|
var id = Identifier.Pair(descEntity, docEntity);
|
||
|
|
||
|
var has = entity.Has(id);
|
||
|
var alloc = GlobalHeapAllocator.Instance;
|
||
|
if (value != null) {
|
||
|
var ptr = ecs_get_mut_id(world, entity, id);
|
||
|
ref var desc = ref Unsafe.AsRef<Doc.Description>(ptr);
|
||
|
// FIXME: Why does freeing these cause crashes?
|
||
|
// if (has) alloc.Free((nint)desc.Value); // Free previous value.
|
||
|
desc.Value = (void*)(nint)alloc.AllocateCString(value);
|
||
|
} else if (has) {
|
||
|
// var @ref = ecs_ref_init_id(world, entity, id);
|
||
|
// var ptr = ecs_ref_get_id(world, &@ref, id);
|
||
|
// var desc = Unsafe.AsRef<Doc.Description>(ptr);
|
||
|
// alloc.Free((nint)desc.Value); // Free previous value.
|
||
|
entity.Remove(id);
|
||
|
}
|
||
|
return entity;
|
||
|
}
|
||
|
|
||
|
public static string? GetDocName(this EntityRef entity, bool fallbackToEntityName = true)
|
||
|
=> fallbackToEntityName || entity.Has<Doc.Description, Core.Name>()
|
||
|
? ecs_doc_get_name(entity.World, entity).FlecsToString() : null;
|
||
|
public static EntityRef SetDocName(this EntityRef entity, string? value)
|
||
|
=> Set<Core.Name>(entity, value);
|
||
|
|
||
|
public static string? GetDocBrief(this EntityRef entity)
|
||
|
=> ecs_doc_get_brief(entity.World, entity).FlecsToString()!;
|
||
|
public static EntityRef SetDocBrief(this EntityRef entity, string? value)
|
||
|
=> Set<Doc.Brief>(entity, value);
|
||
|
|
||
|
public static string? GetDocDetail(this EntityRef entity)
|
||
|
=> ecs_doc_get_detail(entity.World, entity).FlecsToString()!;
|
||
|
public static EntityRef SetDocDetail(this EntityRef entity, string? value)
|
||
|
=> Set<Doc.Detail>(entity, value);
|
||
|
|
||
|
public static string? GetDocLink(this EntityRef entity)
|
||
|
=> ecs_doc_get_link(entity.World, entity).FlecsToString()!;
|
||
|
public static EntityRef SetDocLink(this EntityRef entity, string? value)
|
||
|
=> Set<Doc.Link>(entity, value);
|
||
|
|
||
|
public static string? GetDocColor(this EntityRef entity)
|
||
|
=> ecs_doc_get_color(entity.World, entity).FlecsToString()!;
|
||
|
public static EntityRef SetDocColor(this EntityRef entity, string? value)
|
||
|
=> Set<Doc.Color>(entity, value);
|
||
|
}
|