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.
 
 

81 lines
2.8 KiB

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