- Split core ECS wrapper into gaemstone.ECS project - Module loading part of gaemstone, still - Remove ComponentHooks (for now) - Fix IL for nullable references in IterActionGenerator - Move from Silk.NET.Maths to System.Numerics - Add Flecs.Core.Component and .Identifier - Add Flecs.Doc module - Add gaemstone.Doc module - Add [Symbol] to register entities with symbols This decision will probably be reversed. - World generator picks random blocks, more color! Changes relating to ImGui: - Use custom ImGUI.NET version with local changes to get access to internal functions. Currently waiting for upstream to implement this functionality. - Add font support, and the fonts OpenSans and ForkAwesome - Add an entity inspector window to browse entities, see their contents and find references to other entities.wip/source-generators
parent
0c6d63af21
commit
5268d97828
84 changed files with 2818 additions and 2256 deletions
@ -1,6 +1,6 @@ |
||||
[submodule "src/flecs-cs"] |
||||
path = src/flecs-cs |
||||
url = https://github.com/flecs-hub/flecs-cs |
||||
[submodule "src/FastNoiseLite"] |
||||
path = src/FastNoiseLite |
||||
url = https://github.com/Auburn/FastNoiseLite.git |
||||
[submodule "src/gaemstone.ECS"] |
||||
path = src/gaemstone.ECS |
||||
url = https://git.mcft.net/copygirl/gaemstone.ECS.git |
||||
|
@ -1 +0,0 @@ |
||||
Subproject commit a2047983917aa462a8c2f34d5315aea48502f4d8 |
Binary file not shown.
@ -0,0 +1,95 @@ |
||||
Copyright (c) 2018, Fork Awesome (https://forkawesome.github.io), |
||||
with Reserved Font Name Fork Awesome. |
||||
|
||||
|
||||
This Font Software is licensed under the SIL Open Font License, Version 1.1. |
||||
This license is copied below, and is also available with a FAQ at: |
||||
http://scripts.sil.org/OFL |
||||
|
||||
|
||||
----------------------------------------------------------- |
||||
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 |
||||
----------------------------------------------------------- |
||||
|
||||
PREAMBLE |
||||
The goals of the Open Font License (OFL) are to stimulate worldwide |
||||
development of collaborative font projects, to support the font creation |
||||
efforts of academic and linguistic communities, and to provide a free and |
||||
open framework in which fonts may be shared and improved in partnership |
||||
with others. |
||||
|
||||
The OFL allows the licensed fonts to be used, studied, modified and |
||||
redistributed freely as long as they are not sold by themselves. The |
||||
fonts, including any derivative works, can be bundled, embedded, |
||||
redistributed and/or sold with any software provided that any reserved |
||||
names are not used by derivative works. The fonts and derivatives, |
||||
however, cannot be released under any other type of license. The |
||||
requirement for fonts to remain under this license does not apply |
||||
to any document created using the fonts or their derivatives. |
||||
|
||||
DEFINITIONS |
||||
"Font Software" refers to the set of files released by the Copyright |
||||
Holder(s) under this license and clearly marked as such. This may |
||||
include source files, build scripts and documentation. |
||||
|
||||
"Reserved Font Name" refers to any names specified as such after the |
||||
copyright statement(s). |
||||
|
||||
"Original Version" refers to the collection of Font Software components as |
||||
distributed by the Copyright Holder(s). |
||||
|
||||
"Modified Version" refers to any derivative made by adding to, deleting, |
||||
or substituting -- in part or in whole -- any of the components of the |
||||
Original Version, by changing formats or by porting the Font Software to a |
||||
new environment. |
||||
|
||||
"Author" refers to any designer, engineer, programmer, technical |
||||
writer or other person who contributed to the Font Software. |
||||
|
||||
PERMISSION & CONDITIONS |
||||
Permission is hereby granted, free of charge, to any person obtaining |
||||
a copy of the Font Software, to use, study, copy, merge, embed, modify, |
||||
redistribute, and sell modified and unmodified copies of the Font |
||||
Software, subject to the following conditions: |
||||
|
||||
1) Neither the Font Software nor any of its individual components, |
||||
in Original or Modified Versions, may be sold by itself. |
||||
|
||||
2) Original or Modified Versions of the Font Software may be bundled, |
||||
redistributed and/or sold with any software, provided that each copy |
||||
contains the above copyright notice and this license. These can be |
||||
included either as stand-alone text files, human-readable headers or |
||||
in the appropriate machine-readable metadata fields within text or |
||||
binary files as long as those fields can be easily viewed by the user. |
||||
|
||||
3) No Modified Version of the Font Software may use the Reserved Font |
||||
Name(s) unless explicit written permission is granted by the corresponding |
||||
Copyright Holder. This restriction only applies to the primary font name as |
||||
presented to the users. |
||||
|
||||
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font |
||||
Software shall not be used to promote, endorse or advertise any |
||||
Modified Version, except to acknowledge the contribution(s) of the |
||||
Copyright Holder(s) and the Author(s) or with their explicit written |
||||
permission. |
||||
|
||||
5) The Font Software, modified or unmodified, in part or in whole, |
||||
must be distributed entirely under this license, and must not be |
||||
distributed under any other license. The requirement for fonts to |
||||
remain under this license does not apply to any document created |
||||
using the Font Software. |
||||
|
||||
TERMINATION |
||||
This license becomes null and void if any of the above conditions are |
||||
not met. |
||||
|
||||
DISCLAIMER |
||||
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF |
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT |
||||
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE |
||||
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, |
||||
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL |
||||
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
||||
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM |
||||
OTHER DEALINGS IN THE FONT SOFTWARE. |
@ -0,0 +1,93 @@ |
||||
Copyright 2020 The Open Sans Project Authors (https://github.com/googlefonts/opensans) |
||||
|
||||
This Font Software is licensed under the SIL Open Font License, Version 1.1. |
||||
This license is copied below, and is also available with a FAQ at: |
||||
http://scripts.sil.org/OFL |
||||
|
||||
|
||||
----------------------------------------------------------- |
||||
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 |
||||
----------------------------------------------------------- |
||||
|
||||
PREAMBLE |
||||
The goals of the Open Font License (OFL) are to stimulate worldwide |
||||
development of collaborative font projects, to support the font creation |
||||
efforts of academic and linguistic communities, and to provide a free and |
||||
open framework in which fonts may be shared and improved in partnership |
||||
with others. |
||||
|
||||
The OFL allows the licensed fonts to be used, studied, modified and |
||||
redistributed freely as long as they are not sold by themselves. The |
||||
fonts, including any derivative works, can be bundled, embedded, |
||||
redistributed and/or sold with any software provided that any reserved |
||||
names are not used by derivative works. The fonts and derivatives, |
||||
however, cannot be released under any other type of license. The |
||||
requirement for fonts to remain under this license does not apply |
||||
to any document created using the fonts or their derivatives. |
||||
|
||||
DEFINITIONS |
||||
"Font Software" refers to the set of files released by the Copyright |
||||
Holder(s) under this license and clearly marked as such. This may |
||||
include source files, build scripts and documentation. |
||||
|
||||
"Reserved Font Name" refers to any names specified as such after the |
||||
copyright statement(s). |
||||
|
||||
"Original Version" refers to the collection of Font Software components as |
||||
distributed by the Copyright Holder(s). |
||||
|
||||
"Modified Version" refers to any derivative made by adding to, deleting, |
||||
or substituting -- in part or in whole -- any of the components of the |
||||
Original Version, by changing formats or by porting the Font Software to a |
||||
new environment. |
||||
|
||||
"Author" refers to any designer, engineer, programmer, technical |
||||
writer or other person who contributed to the Font Software. |
||||
|
||||
PERMISSION & CONDITIONS |
||||
Permission is hereby granted, free of charge, to any person obtaining |
||||
a copy of the Font Software, to use, study, copy, merge, embed, modify, |
||||
redistribute, and sell modified and unmodified copies of the Font |
||||
Software, subject to the following conditions: |
||||
|
||||
1) Neither the Font Software nor any of its individual components, |
||||
in Original or Modified Versions, may be sold by itself. |
||||
|
||||
2) Original or Modified Versions of the Font Software may be bundled, |
||||
redistributed and/or sold with any software, provided that each copy |
||||
contains the above copyright notice and this license. These can be |
||||
included either as stand-alone text files, human-readable headers or |
||||
in the appropriate machine-readable metadata fields within text or |
||||
binary files as long as those fields can be easily viewed by the user. |
||||
|
||||
3) No Modified Version of the Font Software may use the Reserved Font |
||||
Name(s) unless explicit written permission is granted by the corresponding |
||||
Copyright Holder. This restriction only applies to the primary font name as |
||||
presented to the users. |
||||
|
||||
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font |
||||
Software shall not be used to promote, endorse or advertise any |
||||
Modified Version, except to acknowledge the contribution(s) of the |
||||
Copyright Holder(s) and the Author(s) or with their explicit written |
||||
permission. |
||||
|
||||
5) The Font Software, modified or unmodified, in part or in whole, |
||||
must be distributed entirely under this license, and must not be |
||||
distributed under any other license. The requirement for fonts to |
||||
remain under this license does not apply to any document created |
||||
using the Font Software. |
||||
|
||||
TERMINATION |
||||
This license becomes null and void if any of the above conditions are |
||||
not met. |
||||
|
||||
DISCLAIMER |
||||
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF |
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT |
||||
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE |
||||
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, |
||||
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL |
||||
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
||||
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM |
||||
OTHER DEALINGS IN THE FONT SOFTWARE. |
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -0,0 +1,763 @@ |
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.Linq; |
||||
using System.Numerics; |
||||
using gaemstone.Client.Utility; |
||||
using gaemstone.ECS; |
||||
using gaemstone.Flecs; |
||||
using gaemstone.Utility; |
||||
using ImGuiNET; |
||||
using static gaemstone.Client.Systems.ImGuiManager; |
||||
using Icon = gaemstone.Client.Utility.ForkAwesome; |
||||
using ImGuiInternal = ImGuiNET.Internal.ImGui; |
||||
|
||||
namespace gaemstone.Client.Systems; |
||||
|
||||
[Module] |
||||
[DependsOn<gaemstone.Client.Systems.ImGuiManager>] |
||||
public class EntityInspector |
||||
: IModuleInitializer |
||||
{ |
||||
[Tag] |
||||
public struct InspectorWindow { } |
||||
|
||||
[Relation, Exclusive] |
||||
[Add<DeletionEvent.OnDeleteTarget, DeletionBehavior.Delete>] |
||||
public struct Selected { } |
||||
|
||||
[Tag] |
||||
public struct ScrollToSelected { } |
||||
|
||||
[Relation] |
||||
public struct Expanded { } |
||||
|
||||
[Component] |
||||
public class History |
||||
{ |
||||
public Entry? Current { get; set; } = null; |
||||
|
||||
public class Entry |
||||
{ |
||||
public Entity Entity { get; } |
||||
public EntityPath? Path { get; } |
||||
|
||||
public Entry? Prev { get; set; } |
||||
public Entry? Next { get; set; } |
||||
|
||||
public Entry(EntityRef entity, Entry? prev, Entry? next) |
||||
{ |
||||
Entity = entity; |
||||
Path = entity.GetFullPath(); |
||||
if ((Prev = prev) != null) Prev.Next = this; |
||||
if ((Next = next) != null) Next.Prev = this; |
||||
} |
||||
} |
||||
} |
||||
|
||||
|
||||
[Component] |
||||
public struct DocPriority { public float Value; } |
||||
|
||||
[Component] |
||||
public struct DocIcon { public char Value; } |
||||
|
||||
|
||||
public void Initialize(EntityRef module) |
||||
{ |
||||
void SetDocInfo(string path, float priority, string icon, float r, float g, float b) |
||||
=> module.World.LookupByPathOrThrow(path) |
||||
.Add<Doc.DisplayType>() |
||||
.Set(new DocPriority { Value = priority }) |
||||
.Set(new DocIcon { Value = icon[0] }) |
||||
.SetDocColor(Color.FromRGB(r, g, b).ToHexString()); |
||||
|
||||
SetDocInfo("/flecs/core/Module" , 0 , Icon.Archive , 1.0f, 0.9f, 0.7f); |
||||
SetDocInfo("/flecs/system/System" , 1 , Icon.Cog , 1.0f, 0.7f, 0.7f); |
||||
SetDocInfo("/flecs/core/Observer" , 2 , Icon.Eye , 1.0f, 0.8f, 0.8f); |
||||
SetDocInfo("/gaemstone/Doc/Relation" , 3 , Icon.ShareAlt , 0.7f, 1.0f, 0.8f); |
||||
SetDocInfo("/flecs/core/Tag" , 4 , Icon.Tag , 0.7f, 0.8f, 1.0f); |
||||
SetDocInfo("/flecs/core/Component" , 5 , Icon.PencilSquare , 0.6f, 0.6f, 1.0f); |
||||
SetDocInfo("/flecs/core/Prefab" , 6 , Icon.Cube , 0.9f, 0.8f, 1.0f); |
||||
} |
||||
|
||||
|
||||
[System] |
||||
public void ShowUIButton(World world, ImGuiData _) |
||||
{ |
||||
var hasAnyInspector = false; |
||||
var inspectorWindow = world.LookupByTypeOrThrow<InspectorWindow>(); |
||||
foreach (var entity in Iterator.FromTerm(world, new(inspectorWindow))) |
||||
{ hasAnyInspector = true; break; } |
||||
|
||||
if (ImGuiUtility.UIButton(0, Icon.Search, "Entity Inspector", hasAnyInspector)) |
||||
NewEntityInspectorWindow(world); |
||||
} |
||||
|
||||
[System] |
||||
public void ShowExplorerWindow(EntityRef window, InspectorWindow _, History? history) |
||||
{ |
||||
var isOpen = true; |
||||
var fontSize = ImGui.GetFontSize(); |
||||
var viewCenter = ImGui.GetMainViewport().GetCenter(); |
||||
ImGui.SetNextWindowPos(viewCenter, ImGuiCond.Appearing, new(0.5f, 0.5f)); |
||||
ImGui.SetNextWindowSize(new(fontSize * 40, fontSize * 25), ImGuiCond.Appearing); |
||||
ImGui.PushFont(ImGui.GetIO().Fonts.Fonts[1]); |
||||
if (ImGui.Begin($"{Icon.Search} Entity Inspector##{window.Id}", |
||||
ref isOpen, ImGuiWindowFlags.NoScrollbar)) { |
||||
ImGui.PushFont(ImGui.GetIO().Fonts.Fonts[0]); |
||||
|
||||
var selected = window.GetTargets<Selected>().FirstOrDefault(); |
||||
ActionBarAndPath(window, history, selected); |
||||
|
||||
ImGui.BeginTable("Views", 2, ImGuiTableFlags.Resizable); |
||||
ImGui.TableSetupColumn("Explorer", ImGuiTableColumnFlags.WidthFixed, fontSize * 12); |
||||
ImGui.TableSetupColumn("Entity", ImGuiTableColumnFlags.WidthStretch); |
||||
|
||||
ImGui.TableNextColumn(); |
||||
ImGui.BeginChild("ExplorerView", new(-float.Epsilon, -float.Epsilon)); |
||||
ExplorerView(window, history, selected); |
||||
ImGui.EndChild(); |
||||
|
||||
void Tab(string name, Action<EntityRef, History?, EntityRef?> contentMethod) |
||||
{ |
||||
if (!ImGui.BeginTabItem(name)) return; |
||||
ImGui.BeginChild($"{name}Tab", new(-float.Epsilon, -float.Epsilon)); |
||||
contentMethod(window, history, selected); |
||||
ImGui.EndChild(); |
||||
ImGui.EndTabItem(); |
||||
} |
||||
|
||||
ImGui.TableNextColumn(); |
||||
ImGui.BeginChild("EntityView", new(-float.Epsilon, -float.Epsilon)); |
||||
if (!ImGui.BeginTabBar("Tabs")) return; |
||||
Tab($"{Icon.PencilSquare} Components", ComponentsTab); |
||||
Tab($"{Icon.ShareAlt} References", ReferencesTab); |
||||
Tab($"{Icon.InfoCircle} Documentation", DocumentationTab); |
||||
ImGui.EndTabBar(); |
||||
ImGui.EndChild(); |
||||
|
||||
ImGui.EndTable(); |
||||
|
||||
ImGui.PopFont(); |
||||
} |
||||
ImGui.PopFont(); |
||||
ImGui.End(); |
||||
|
||||
// If window is closed, delete the entity. |
||||
if (!isOpen) window.Delete(); |
||||
} |
||||
|
||||
[Observer<ObserverEvent.OnRemove>] |
||||
public void ClearStorageOnRemove(EntityRef _1, InspectorWindow _2) |
||||
{ |
||||
// TODO: Clear out settings store for the window. |
||||
} |
||||
|
||||
private void ActionBarAndPath(EntityRef window, History? history, EntityRef? selected) |
||||
{ |
||||
var world = window.World; |
||||
|
||||
static bool IconButtonWithToolTip(string icon, string tooltip, bool enabled = true) { |
||||
if (!enabled) ImGui.BeginDisabled(); |
||||
var clicked = ImGui.Button(icon); |
||||
if (!enabled) ImGui.EndDisabled(); |
||||
if (ImGui.IsItemHovered(ImGuiHoveredFlags.AllowWhenDisabled)) |
||||
ImGui.SetTooltip(tooltip); |
||||
return clicked; |
||||
} |
||||
|
||||
ImGui.PushStyleVar(ImGuiStyleVar.ItemSpacing, new Vector2(2, ImGui.GetStyle().ItemSpacing.Y)); |
||||
ImGui.BeginTable("ActionBar", 3); |
||||
ImGui.TableSetupColumn("Explorer", ImGuiTableColumnFlags.WidthFixed); |
||||
ImGui.TableSetupColumn("Path", ImGuiTableColumnFlags.WidthStretch); |
||||
ImGui.TableSetupColumn("Entity", ImGuiTableColumnFlags.WidthFixed); |
||||
|
||||
ImGui.TableNextColumn(); |
||||
var hasExpanded = window.Has<Expanded, Core.Wildcard>(); |
||||
if (IconButtonWithToolTip(Icon.Outdent, "Collapse all items in the Explorer View", hasExpanded)) |
||||
window.Remove<Expanded, Core.Wildcard>(); |
||||
|
||||
if (history != null) { |
||||
var hasPrev = ((selected != null) ? history.Current?.Prev : history.Current) != null; |
||||
var hasNext = history.Current?.Next != null; |
||||
ImGui.SameLine(); |
||||
if (IconButtonWithToolTip(Icon.ArrowLeft, "Go to the previously viewed entity", hasPrev)) |
||||
GoToPrevious(window, history, selected); |
||||
ImGui.SameLine(); |
||||
if (IconButtonWithToolTip(Icon.ArrowRight, "Go to the next viewed entity", hasNext)) |
||||
GoToNext(window, history); |
||||
} |
||||
|
||||
ImGui.SameLine(); |
||||
if (IconButtonWithToolTip(Icon.Crosshairs, "Scroll to the current entity in the Explorer View", (selected != null))) |
||||
window.Add<ScrollToSelected>(); |
||||
|
||||
ImGui.TableNextColumn(); |
||||
var availableWidth = ImGui.GetColumnWidth() - ImGui.GetStyle().CellPadding.X * 2; |
||||
PathInput(window, history, selected, availableWidth); |
||||
|
||||
ImGui.TableNextColumn(); |
||||
if (IconButtonWithToolTip(Icon.PlusCircle, "Create a new child entity", (selected != null))) |
||||
// FIXME: Replace this once Flecs has been fixed. |
||||
SetSelected(window, history, world.New().Build().ChildOf(selected)); |
||||
// SelectAndScrollTo(windowEntity, windowData, selected!.NewChild().Build(), selected); |
||||
|
||||
ImGui.SameLine(); |
||||
if (IconButtonWithToolTip(Icon.Pencil, "Rename the current entity", false && (selected != null))) |
||||
{ } // TODO: Implement this! |
||||
|
||||
ImGui.SameLine(); |
||||
var isDisabled = (selected?.IsDisabled == true); |
||||
var icon = !isDisabled ? Icon.BellSlash : Icon.Bell; |
||||
var tooltip = $"{(!isDisabled ? "Disable" : "Enable")} the current entity"; |
||||
if (IconButtonWithToolTip(icon, tooltip, (selected != null))) |
||||
{ if (isDisabled) selected!.Enable(); else selected!.Disable(); } |
||||
|
||||
ImGui.SameLine(); |
||||
if (IconButtonWithToolTip(Icon.Trash, "Delete the current entity", (selected != null))) { |
||||
SetSelected(window, history, selected!.Parent); |
||||
selected.Delete(); // TODO: Confirmation dialog? |
||||
|