NEARLY THERE
This commit is contained in:
@@ -1,6 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Collections.ObjectModel;
|
|
||||||
|
|
||||||
|
|
||||||
namespace AwperativeKernel;
|
namespace AwperativeKernel;
|
||||||
@@ -30,6 +29,7 @@ public static class DebugAttributes
|
|||||||
/// <summary> Returns true or false based on the given condition from the attribute, unless Debug.IgnoreErrors is true, in which it will always return true, but still try to throw errors. </summary>
|
/// <summary> Returns true or false based on the given condition from the attribute, unless Debug.IgnoreErrors is true, in which it will always return true, but still try to throw errors. </summary>
|
||||||
/// <usage> It is required to use VerifyOrThrow() to validate important conditions for methods within the kernel. You may also feel free to use this outside in any modules or games.
|
/// <usage> It is required to use VerifyOrThrow() to validate important conditions for methods within the kernel. You may also feel free to use this outside in any modules or games.
|
||||||
/// It is easiest to use VerifyOrThrow like : (In your method) if(!Attribute.VerifyOrThrow()) return; That way the attribute can exit the code if the condition is false.</usage>
|
/// It is easiest to use VerifyOrThrow like : (In your method) if(!Attribute.VerifyOrThrow()) return; That way the attribute can exit the code if the condition is false.</usage>
|
||||||
|
[MarkerAttributes.Expense(MarkerAttributes.Expense.ExpenseLevel.Medium), MarkerAttributes.Complexity(MarkerAttributes.Complexity.TimeComplexity.ON)]
|
||||||
public static bool VerifyOrThrow(ComponentDocker __docker, Component __component) {
|
public static bool VerifyOrThrow(ComponentDocker __docker, Component __component) {
|
||||||
if (__docker.Contains(__component)) return true;
|
if (__docker.Contains(__component)) return true;
|
||||||
|
|
||||||
@@ -56,6 +56,7 @@ public static class DebugAttributes
|
|||||||
|
|
||||||
|
|
||||||
/// <inheritdoc cref="DockerOwns.VerifyOrThrow"/>
|
/// <inheritdoc cref="DockerOwns.VerifyOrThrow"/>
|
||||||
|
[MarkerAttributes.Expense(MarkerAttributes.Expense.ExpenseLevel.Medium), MarkerAttributes.Complexity(MarkerAttributes.Complexity.TimeComplexity.ON)]
|
||||||
public static bool VerifyOrThrow(ComponentDocker __docker, Component __component) {
|
public static bool VerifyOrThrow(ComponentDocker __docker, Component __component) {
|
||||||
if (!__docker.Contains(__component)) return true;
|
if (!__docker.Contains(__component)) return true;
|
||||||
|
|
||||||
@@ -82,6 +83,7 @@ public static class DebugAttributes
|
|||||||
|
|
||||||
|
|
||||||
/// <inheritdoc cref="DockerOwns.VerifyOrThrow"/>
|
/// <inheritdoc cref="DockerOwns.VerifyOrThrow"/>
|
||||||
|
[MarkerAttributes.Expense(MarkerAttributes.Expense.ExpenseLevel.VeryLow), MarkerAttributes.Complexity(MarkerAttributes.Complexity.TimeComplexity.O1)]
|
||||||
public static bool VerifyOrThrow(Component __component) {
|
public static bool VerifyOrThrow(Component __component) {
|
||||||
if (__component.ComponentDocker == null) return true;
|
if (__component.ComponentDocker == null) return true;
|
||||||
|
|
||||||
@@ -108,6 +110,7 @@ public static class DebugAttributes
|
|||||||
|
|
||||||
|
|
||||||
/// <inheritdoc cref="DockerOwns.VerifyOrThrow"/>
|
/// <inheritdoc cref="DockerOwns.VerifyOrThrow"/>
|
||||||
|
[MarkerAttributes.Expense(MarkerAttributes.Expense.ExpenseLevel.VeryLow), MarkerAttributes.Complexity(MarkerAttributes.Complexity.TimeComplexity.O1)]
|
||||||
public static bool VerifyOrThrow(ComponentDocker __docker, ComponentDocker __other) {
|
public static bool VerifyOrThrow(ComponentDocker __docker, ComponentDocker __other) {
|
||||||
if (!__docker.Equals(__other)) return true;
|
if (!__docker.Equals(__other)) return true;
|
||||||
|
|
||||||
@@ -130,6 +133,7 @@ public static class DebugAttributes
|
|||||||
|
|
||||||
|
|
||||||
/// <inheritdoc cref="DockerOwns.VerifyOrThrow"/>
|
/// <inheritdoc cref="DockerOwns.VerifyOrThrow"/>
|
||||||
|
[MarkerAttributes.Expense(MarkerAttributes.Expense.ExpenseLevel.VeryLow), MarkerAttributes.Complexity(MarkerAttributes.Complexity.TimeComplexity.O1)]
|
||||||
public static bool VerifyOrThrow(Component __component) {
|
public static bool VerifyOrThrow(Component __component) {
|
||||||
if (__component != null) return true;
|
if (__component != null) return true;
|
||||||
|
|
||||||
@@ -148,6 +152,7 @@ public static class DebugAttributes
|
|||||||
|
|
||||||
|
|
||||||
/// <inheritdoc cref="DockerOwns.VerifyOrThrow"/>
|
/// <inheritdoc cref="DockerOwns.VerifyOrThrow"/>
|
||||||
|
[MarkerAttributes.Expense(MarkerAttributes.Expense.ExpenseLevel.VeryLow), MarkerAttributes.Complexity(MarkerAttributes.Complexity.TimeComplexity.O1)]
|
||||||
public static bool VerifyOrThrow(ComponentDocker __componentDocker) {
|
public static bool VerifyOrThrow(ComponentDocker __componentDocker) {
|
||||||
if (__componentDocker != null) return true;
|
if (__componentDocker != null) return true;
|
||||||
|
|
||||||
@@ -166,6 +171,7 @@ public static class DebugAttributes
|
|||||||
|
|
||||||
|
|
||||||
/// <inheritdoc cref="DockerOwns.VerifyOrThrow"/>
|
/// <inheritdoc cref="DockerOwns.VerifyOrThrow"/>
|
||||||
|
[MarkerAttributes.Expense(MarkerAttributes.Expense.ExpenseLevel.VeryLow), MarkerAttributes.Complexity(MarkerAttributes.Complexity.TimeComplexity.O1)]
|
||||||
public static bool VerifyOrThrow(Scene __scene) {
|
public static bool VerifyOrThrow(Scene __scene) {
|
||||||
if (__scene != null) return true;
|
if (__scene != null) return true;
|
||||||
|
|
||||||
|
|||||||
@@ -4,30 +4,66 @@ using System;
|
|||||||
namespace AwperativeKernel;
|
namespace AwperativeKernel;
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Provides many handy cosmetic attributes for methods to specify use cases or provide information.
|
||||||
|
/// </summary>
|
||||||
|
/// <author> Avery Norris </author>
|
||||||
public static class MarkerAttributes
|
public static class MarkerAttributes
|
||||||
{
|
{
|
||||||
|
|
||||||
/// <summary>
|
/// <summary> Shows that the given object is unsafe (ex. it doesn't check for null values and such, or it doesn't have guardrails based on cases).
|
||||||
/// Shows that the given object is unsafe (ex. it doesn't check for null values and such, or it doesn't have guardrails based on cases).
|
|
||||||
/// This is just for internal/private methods to remind myself how to call it :) The reasoning is case by case, but most of the time,
|
/// This is just for internal/private methods to remind myself how to call it :) The reasoning is case by case, but most of the time,
|
||||||
/// it is because all of the exposing public methods already check, and double checks would only slow me down
|
/// it is because all the exposing public methods already check, and double checks would only slow me down </summary>
|
||||||
/// </summary>
|
|
||||||
[AttributeUsage(AttributeTargets.All)]
|
[AttributeUsage(AttributeTargets.All)]
|
||||||
public class UnsafeInternal : Attribute { }
|
public class UnsafeInternal : Attribute { }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary> Shows that the given object is calculated every time it is called! Good to know for performance heavy systems. </summary>
|
||||||
/// Shows that the given object (meant for external use) is calculated every time it is called! Good to know for performance heavy systems.
|
|
||||||
/// </summary>
|
|
||||||
[AttributeUsage(AttributeTargets.All)]
|
[AttributeUsage(AttributeTargets.All)]
|
||||||
public class CalculatedProperty() : Attribute { }
|
public class CalculatedProperty : Attribute { }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary> Just a way to write how expensive a calculated property or method can be. </summary>
|
||||||
/// Just a way to write how expensive a calculated property can be.
|
|
||||||
/// </summary>
|
|
||||||
[AttributeUsage(AttributeTargets.All)]
|
[AttributeUsage(AttributeTargets.All)]
|
||||||
public class CalculatedPropertyExpense(string Expense) : Attribute { }
|
public class Expense(Expense.ExpenseLevel __expense) : Attribute
|
||||||
|
{
|
||||||
|
public enum ExpenseLevel {
|
||||||
|
None,
|
||||||
|
VeryLow,
|
||||||
|
Low,
|
||||||
|
Medium,
|
||||||
|
High,
|
||||||
|
VeryHigh,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public ExpenseLevel expense = __expense;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary> Just a way to write the time complexity of a calculated property or method. </summary>
|
||||||
|
[AttributeUsage(AttributeTargets.All)]
|
||||||
|
public class Complexity(Complexity.TimeComplexity __complexity) : Attribute
|
||||||
|
{
|
||||||
|
public enum TimeComplexity
|
||||||
|
{
|
||||||
|
O1,
|
||||||
|
OLogN,
|
||||||
|
ON,
|
||||||
|
ONLogN,
|
||||||
|
ON2,
|
||||||
|
ON3
|
||||||
|
}
|
||||||
|
|
||||||
|
public TimeComplexity complexity = __complexity;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary> Shows that the given method does not actually belong to the object, but instead just calls a lambda to another method. </summary>
|
||||||
|
[AttributeUsage(AttributeTargets.All)]
|
||||||
|
public class MethodPointer : Attribute { }
|
||||||
}
|
}
|
||||||
@@ -1,32 +1,26 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Collections.Immutable;
|
|
||||||
using System.Collections.ObjectModel;
|
|
||||||
using System.Diagnostics;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Reflection;
|
|
||||||
using Microsoft.VisualBasic;
|
|
||||||
|
|
||||||
|
|
||||||
namespace AwperativeKernel;
|
namespace AwperativeKernel;
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The backing class for components in Awperative; provides access to a few important methods, and inheriting this is required to receive time based events.
|
||||||
|
/// When Start() is called, Awperative reflectively analyzes all classes that inherits component, and checks for given events. See the wiki for more information!
|
||||||
|
/// </summary>
|
||||||
|
/// <author> Avery Norris </author>
|
||||||
public abstract partial class Component : ComponentDocker
|
public abstract partial class Component : ComponentDocker
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary> Current parent of the Component. Can be either Scene or another Component.</summary>
|
/// <summary> Current parent of the Component. Can be either a Scene or another Component.</summary>
|
||||||
[MarkerAttributes.UnsafeInternal]
|
[MarkerAttributes.UnsafeInternal]
|
||||||
public ComponentDocker ComponentDocker { get; set; } = null;
|
public ComponentDocker ComponentDocker { get; internal set; } = null;
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary> Component's name </summary>
|
||||||
/// Component name
|
[DebugAttributes.NotNull]
|
||||||
/// </summary>
|
|
||||||
[NotNull]
|
|
||||||
public string Name {
|
public string Name {
|
||||||
get => _name;
|
get => _name;
|
||||||
set { if (!DebugAttributes.NotNull.VerifyOrThrow(value)) return; _name = value; }
|
set { if (!DebugAttributes.NotNull.VerifyOrThrow(value)) return; _name = value; }
|
||||||
@@ -34,19 +28,19 @@ public abstract partial class Component : ComponentDocker
|
|||||||
|
|
||||||
|
|
||||||
/// <summary> Represents the state of this Component, The largest bit represents if the Component is enabled or not, while the
|
/// <summary> Represents the state of this Component, The largest bit represents if the Component is enabled or not, while the
|
||||||
/// next 7 represent its priority </summary>
|
/// next 7 represent its priority like so : (Enabled -> 0 | Priority -> 0000000) </summary>
|
||||||
[MarkerAttributes.UnsafeInternal]
|
[MarkerAttributes.UnsafeInternal]
|
||||||
private byte OrderProfile;
|
private byte OrderProfile;
|
||||||
|
|
||||||
/// <summary> If the component receives time events or not. </summary>
|
/// <summary> If the component receives time events or not. </summary>
|
||||||
[MarkerAttributes.CalculatedProperty, MarkerAttributes.CalculatedPropertyExpense("Very Low")]
|
[MarkerAttributes.CalculatedProperty, MarkerAttributes.Expense(MarkerAttributes.Expense.ExpenseLevel.VeryLow), MarkerAttributes.Complexity(MarkerAttributes.Complexity.TimeComplexity.O1)]
|
||||||
public bool Enabled {
|
public bool Enabled {
|
||||||
get => (OrderProfile & 128) > 0;
|
get => (OrderProfile & 128) > 0;
|
||||||
set => OrderProfile = (byte)((OrderProfile & 127) | (value ? 128 : 0));
|
set => OrderProfile = (byte)((OrderProfile & 127) | (value ? 128 : 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary> Represents the Component's Update priority, can be set to any value ranging from -64 to 63; otherwise an error will throw! </summary>
|
/// <summary> Represents the Component's Update priority; higher priorities get updated first. Can be any integer in the range -64 -> 63. </summary>
|
||||||
[MarkerAttributes.CalculatedProperty, MarkerAttributes.CalculatedPropertyExpense("Very Low")]
|
[MarkerAttributes.CalculatedProperty, MarkerAttributes.Expense(MarkerAttributes.Expense.ExpenseLevel.VeryLow), MarkerAttributes.Complexity(MarkerAttributes.Complexity.TimeComplexity.O1)]
|
||||||
public int Priority {
|
public int Priority {
|
||||||
get => (sbyte)(OrderProfile << 1) >> 1;
|
get => (sbyte)(OrderProfile << 1) >> 1;
|
||||||
set {
|
set {
|
||||||
@@ -57,13 +51,12 @@ public abstract partial class Component : ComponentDocker
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary> A list of all tags belonging to the component. Use AddTag() to modify it.</summary>
|
||||||
|
public IReadOnlySet<string> Tags => _tags;
|
||||||
|
[MarkerAttributes.UnsafeInternal] internal HashSet<string> _tags = [];
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary> Attempts to send an event to the component, and quietly exits if not.</summary>
|
||||||
/// <summary>
|
|
||||||
/// Attempts to send an Event to the Component, terminates if the Component does not have the given Event
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="__timeEvent">Type of Event</param>
|
|
||||||
[MarkerAttributes.UnsafeInternal]
|
[MarkerAttributes.UnsafeInternal]
|
||||||
internal void TryEvent(int __timeEvent) {
|
internal void TryEvent(int __timeEvent) {
|
||||||
Awperative._TypeAssociatedTimeEvents[GetType()][__timeEvent]?.Invoke(this);
|
Awperative._TypeAssociatedTimeEvents[GetType()][__timeEvent]?.Invoke(this);
|
||||||
@@ -71,46 +64,31 @@ public abstract partial class Component : ComponentDocker
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary> Adds a new tag to the component</summary>
|
||||||
/// Identifiers for Components.
|
[MarkerAttributes.CalculatedProperty, MarkerAttributes.Expense(MarkerAttributes.Expense.ExpenseLevel.Low), MarkerAttributes.Complexity(MarkerAttributes.Complexity.TimeComplexity.ON)]
|
||||||
/// </summary>
|
public void AddTag([DebugAttributes.NotNull, DebugAttributes.CollectionDoesntContain] string __tag) {
|
||||||
public IReadOnlyList<string> Tags => [.._tags];
|
|
||||||
[MarkerAttributes.UnsafeInternal] internal HashSet<string> _tags = [];
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Adds a new tag to the Component
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="__tag"> The tag to add</param>
|
|
||||||
public void AddTag([DebugAttributes.NotNull, DebugAttributes.CollectionDoesntContain] string __tag)
|
|
||||||
{
|
|
||||||
if(!DebugAttributes.NotNull.VerifyOrThrow(__tag)) return;
|
if(!DebugAttributes.NotNull.VerifyOrThrow(__tag)) return;
|
||||||
if(!DebugAttributes.CollectionDoesntContain.VerifyOrThrow(__tag, _tags)) return;
|
if(!DebugAttributes.CollectionDoesntContain.VerifyOrThrow(__tag, _tags)) return;
|
||||||
|
|
||||||
_tags.Add(__tag);
|
_tags.Add(__tag);
|
||||||
ComponentDocker.AddTagToComponent(__tag, this);
|
ComponentDocker.HashTaggedComponent(__tag, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary> Removes a tag from the component.</summary>
|
||||||
/// Adds a new tag to the Component
|
[MarkerAttributes.CalculatedProperty, MarkerAttributes.Expense(MarkerAttributes.Expense.ExpenseLevel.Low), MarkerAttributes.Complexity(MarkerAttributes.Complexity.TimeComplexity.ON)]
|
||||||
/// </summary>
|
public void RemoveTag([DebugAttributes.NotNull,DebugAttributes.CollectionContains] string __tag) {
|
||||||
/// <param name="__tag"> The tag to add</param>
|
|
||||||
public void RemoveTag([DebugAttributes.NotNull,DebugAttributes.CollectionContains] string __tag)
|
|
||||||
{
|
|
||||||
if (!DebugAttributes.NotNull.VerifyOrThrow(__tag)) return;
|
if (!DebugAttributes.NotNull.VerifyOrThrow(__tag)) return;
|
||||||
if(!DebugAttributes.CollectionContains.VerifyOrThrow(__tag, _tags)) return;
|
if(!DebugAttributes.CollectionContains.VerifyOrThrow(__tag, _tags)) return;
|
||||||
|
|
||||||
_tags.Remove(__tag);
|
_tags.Remove(__tag);
|
||||||
ComponentDocker.RemoveTagFromComponent(__tag, this);
|
ComponentDocker.UnhashTaggedComponent(__tag, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary> Just gives the Component's name. But makes debugging a little easier :).</summary>
|
||||||
public override string ToString() {
|
public override string ToString() {
|
||||||
return this.Name;
|
return this.Name;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,50 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
|
||||||
|
namespace AwperativeKernel;
|
||||||
|
|
||||||
|
|
||||||
|
public abstract partial class Component
|
||||||
|
{
|
||||||
|
/// <summary> Scene the Component resides in. To save ram it's not stored but calculated on the fly. </summary>
|
||||||
|
[MarkerAttributes.CalculatedProperty, MarkerAttributes.Expense(MarkerAttributes.Expense.ExpenseLevel.Medium), MarkerAttributes.Complexity(MarkerAttributes.Complexity.TimeComplexity.ON)]
|
||||||
|
public Scene Scene => __QueryScene();
|
||||||
|
private Scene __QueryScene() {
|
||||||
|
if (ComponentDocker is Scene scene) return scene;
|
||||||
|
if (ComponentDocker is Component Component) return Component.__QueryScene();
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary> Returns the Parent Component. Will be null if the Component's parent is a Scene. </summary>
|
||||||
|
[MarkerAttributes.CalculatedProperty, MarkerAttributes.Expense(MarkerAttributes.Expense.ExpenseLevel.VeryLow), MarkerAttributes.Complexity(MarkerAttributes.Complexity.TimeComplexity.O1)]
|
||||||
|
public Component Parent => __QueryParent();
|
||||||
|
private Component __QueryParent() {
|
||||||
|
if (ComponentDocker is Component Component)
|
||||||
|
return Component;
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary> All parent Components and the parents of the parents up until the Scene. Will only list parents of parents, not uncle Components. And will not list the Scene </summary>
|
||||||
|
[MarkerAttributes.CalculatedProperty, MarkerAttributes.Expense(MarkerAttributes.Expense.ExpenseLevel.Medium), MarkerAttributes.Complexity(MarkerAttributes.Complexity.TimeComplexity.ON)]
|
||||||
|
public IEnumerable<Component> AllParents => __QueryComponents();
|
||||||
|
private IEnumerable<Component> __QueryComponents() {
|
||||||
|
List<Component> returnValue = [];
|
||||||
|
ComponentDocker currentComponentDocker = ComponentDocker;
|
||||||
|
|
||||||
|
while (currentComponentDocker is not AwperativeKernel.Scene) {
|
||||||
|
if (currentComponentDocker is Component Component) {
|
||||||
|
returnValue.Add(Component);
|
||||||
|
currentComponentDocker = Component.ComponentDocker;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return returnValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,52 +0,0 @@
|
|||||||
using System.Collections.Generic;
|
|
||||||
|
|
||||||
namespace AwperativeKernel;
|
|
||||||
|
|
||||||
public abstract partial class Component
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Scene the Component resides in.
|
|
||||||
/// </summary>
|
|
||||||
[CalculatedProperty, CalculatedPropertyExpense("Medium: O(Parents)")]
|
|
||||||
public Scene Scene => __QueryScene();
|
|
||||||
private Scene __QueryScene() {
|
|
||||||
if (ComponentDocker is Scene scene) return scene;
|
|
||||||
if (ComponentDocker is Component Component) return Component.__QueryScene();
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Returns the Parent Component. Will be null if the Component is at the base of a scene.
|
|
||||||
/// </summary>
|
|
||||||
[CalculatedProperty, CalculatedPropertyExpense("Very Low O(1)")]
|
|
||||||
public Component Parent => __QueryParent();
|
|
||||||
private Component __QueryParent() {
|
|
||||||
if (ComponentDocker is Component Component)
|
|
||||||
return Component;
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// All parent Components and the parents of the parents up until the Scene. Will only list parents of parents, not uncle Components.
|
|
||||||
/// </summary>
|
|
||||||
[CalculatedProperty, CalculatedPropertyExpense("Medium O(Parents)")]
|
|
||||||
public IReadOnlyList<Component> AllParents => __QueryComponents();
|
|
||||||
private IReadOnlyList<Component> __QueryComponents() {
|
|
||||||
List<Component> returnValue = [];
|
|
||||||
ComponentDocker currentComponentDocker = ComponentDocker;
|
|
||||||
|
|
||||||
while (!(currentComponentDocker is Scene))
|
|
||||||
if (currentComponentDocker is Component Component) {
|
|
||||||
returnValue.Add(Component);
|
|
||||||
currentComponentDocker = Component.ComponentDocker;
|
|
||||||
}
|
|
||||||
return [..returnValue];
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,33 +1,40 @@
|
|||||||
namespace AwperativeKernel;
|
namespace AwperativeKernel;
|
||||||
|
|
||||||
|
|
||||||
public abstract partial class Component
|
public abstract partial class Component
|
||||||
{
|
{
|
||||||
/// <inheritdoc cref="Awperative.CreateScene"/>
|
/// <inheritdoc cref="Awperative.CreateScene"/>
|
||||||
|
[MarkerAttributes.MethodPointer]
|
||||||
public static Scene CreateScene(string __name) => Awperative.CreateScene(__name);
|
public static Scene CreateScene(string __name) => Awperative.CreateScene(__name);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// <inheritdoc cref="Awperative.GetScene"/>
|
/// <inheritdoc cref="Awperative.GetScene"/>
|
||||||
|
[MarkerAttributes.MethodPointer]
|
||||||
public static Scene GetScene(string __name) => Awperative.GetScene(__name);
|
public static Scene GetScene(string __name) => Awperative.GetScene(__name);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// <inheritdoc cref="Awperative.CloseScene(AwperativeKernel.Scene)"/>
|
/// <inheritdoc cref="Awperative.CloseScene(AwperativeKernel.Scene)"/>
|
||||||
|
[MarkerAttributes.MethodPointer]
|
||||||
public void RemoveScene(Scene __scene) => Awperative.CloseScene(__scene);
|
public void RemoveScene(Scene __scene) => Awperative.CloseScene(__scene);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// <inheritdock cref="Awperative.CloseScene(string)" />
|
/// <inheritdock cref="Awperative.CloseScene(string)" />
|
||||||
|
[MarkerAttributes.MethodPointer]
|
||||||
public void RemoveScene(string __name) => Awperative.CloseScene(__name);
|
public void RemoveScene(string __name) => Awperative.CloseScene(__name);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// <inheritdoc cref="ComponentDocker.Move"/>
|
/// <inheritdoc cref="ComponentDocker.Move"/>
|
||||||
|
[MarkerAttributes.MethodPointer]
|
||||||
public void Move(ComponentDocker __newDocker) => ComponentDocker.Move(this, __newDocker);
|
public void Move(ComponentDocker __newDocker) => ComponentDocker.Move(this, __newDocker);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary> Makes the Component destroy itself </summary>
|
/// <summary> Makes the Component destroy itself </summary>
|
||||||
|
[MarkerAttributes.MethodPointer]
|
||||||
public void Destroy() => ComponentDocker.Destroy(this);
|
public void Destroy() => ComponentDocker.Destroy(this);
|
||||||
|
|
||||||
}
|
}
|
||||||
143
AwperativeKernel/Kernel/ComponentDocker/ComponentDocker.cs
Normal file
143
AwperativeKernel/Kernel/ComponentDocker/ComponentDocker.cs
Normal file
@@ -0,0 +1,143 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
|
||||||
|
namespace AwperativeKernel;
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Base class for all Awperative objects. Responsible for Managing hierarchy between Components and Scenes, has Extensive Component Manipulation Available.
|
||||||
|
/// Also transfers Time and Carries most of the responsibilities akin to the Component. NOT FOR INHERITING, please use docker by inheriting component.
|
||||||
|
/// </summary>
|
||||||
|
/// <author> Avery Norris </author>
|
||||||
|
public abstract partial class ComponentDocker : IEnumerable<Component>, IEquatable<Component>, IEquatable<ComponentDocker>, IEquatable<Scene>
|
||||||
|
{
|
||||||
|
|
||||||
|
//Blocks external inheritance
|
||||||
|
internal ComponentDocker() {}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary> Core of the Docker, holds all of the Components, sorted by update priority.</summary>
|
||||||
|
[MarkerAttributes.UnsafeInternal] internal readonly List<Component> _components = [];
|
||||||
|
/// <summary> Holds a list of Components at each of their types. This optimizes Get<Type> to O(1) </summary>
|
||||||
|
[MarkerAttributes.UnsafeInternal] internal readonly Dictionary<Type, HashSet<Component>> _componentTypeDictionary = new();
|
||||||
|
/// <summary> Stores a Component in a list at each of their tags. This optimizes Get(string tag) to O(1)</summary>
|
||||||
|
[MarkerAttributes.UnsafeInternal] internal readonly Dictionary<string, HashSet<Component>> _componentTagDictionary = new();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary> All children belonging to the Component. </summary>
|
||||||
|
public IEnumerable<Component> Children => _components;
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary> All children and children of children until the bottom of the scene. Uses Breadth First Search. </summary>
|
||||||
|
[MarkerAttributes.CalculatedProperty, MarkerAttributes.Expense(MarkerAttributes.Expense.ExpenseLevel.High), MarkerAttributes.Complexity(MarkerAttributes.Complexity.TimeComplexity.ON)]
|
||||||
|
public IEnumerable<Component> AllChildren => GetAllChildren();
|
||||||
|
public IEnumerable<Component> GetAllChildren() {
|
||||||
|
List<Component> returnValue = [];
|
||||||
|
Queue<Component> queue = new(_components);
|
||||||
|
while (queue.Count > 0) {
|
||||||
|
Component current = queue.Dequeue();
|
||||||
|
returnValue.Add(current);
|
||||||
|
|
||||||
|
for (int i = 0; i < current.Count; i++) queue.Enqueue(current[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return returnValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>Amount of Components attached to the Docker</summary>
|
||||||
|
public int Count => _components.Count;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//Indexers to make for loops easier.
|
||||||
|
public Component this[[DebugAttributes.ValueFitsRange] int __index] {
|
||||||
|
get => !DebugAttributes.ValueFitsRange.VerifyOrThrow(__index, 0, _components.Count) ? null : _components[__index];
|
||||||
|
set { if (!DebugAttributes.ValueFitsRange.VerifyOrThrow(__index, 0, _components.Count)) return; _components[__index] = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//Enumerators that allow convenient foreach loops.
|
||||||
|
IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); }
|
||||||
|
public IEnumerator<Component> GetEnumerator() { return new ComponentDockEnum([.._components]); }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>Compares the Docker to another Scene.</summary>
|
||||||
|
public bool Equals(Scene __other) {
|
||||||
|
if (this is Scene scene)
|
||||||
|
return scene == __other;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>Compares the Docker to another Component.</summary>
|
||||||
|
public bool Equals(Component __other) {
|
||||||
|
if (this is Component component)
|
||||||
|
return component == __other;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>Compares the Docker to another Docker.</summary>
|
||||||
|
public bool Equals(ComponentDocker __other) {
|
||||||
|
return this == __other;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary> Resorts the component list to order of priority </summary>
|
||||||
|
[MarkerAttributes.UnsafeInternal]
|
||||||
|
internal void UpdatePriority(Component __component, int __priority) {
|
||||||
|
_components.Sort(Awperative._prioritySorter);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary> Sends an event to all Children and tells them to continue it. </summary>
|
||||||
|
/// <param name="__timeEvent"> Integer ID of the event to send. </param>
|
||||||
|
[MarkerAttributes.UnsafeInternal]
|
||||||
|
internal void ChainEvent(int __timeEvent) {
|
||||||
|
for (int i = 0; i < _components.Count; i++) {
|
||||||
|
_components[i].TryEvent(__timeEvent);
|
||||||
|
_components[i].ChainEvent(__timeEvent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary> Add a Component to the Docker. </summary>
|
||||||
|
[MarkerAttributes.UnsafeInternal]
|
||||||
|
private void AddComponentToLists(Component __component) {
|
||||||
|
Type Type = __component.GetType();
|
||||||
|
_components.Add(__component);
|
||||||
|
if (!_componentTypeDictionary.TryAdd(Type, [__component])) _componentTypeDictionary[Type].Add(__component);
|
||||||
|
|
||||||
|
foreach (string tag in __component._tags) HashTaggedComponent(tag, __component);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary> Removes a Component from the Docker. </summary>
|
||||||
|
[MarkerAttributes.UnsafeInternal]
|
||||||
|
private void RemoveComponentFromLists(Component __component) {
|
||||||
|
Type Type = __component.GetType();
|
||||||
|
_components.Remove(__component);
|
||||||
|
|
||||||
|
if(_componentTypeDictionary.TryGetValue(Type, out HashSet<Component> value)) value.Remove(__component);
|
||||||
|
|
||||||
|
foreach (string tag in __component._tags) UnhashTaggedComponent(tag, __component);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary> Hashes a component in the tag dictionary </summary>
|
||||||
|
[MarkerAttributes.UnsafeInternal]
|
||||||
|
internal void HashTaggedComponent(string __tag, Component __component) {
|
||||||
|
if (!_componentTagDictionary.TryAdd(__tag, [__component]))
|
||||||
|
_componentTagDictionary[__tag].Add(__component);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary> Removes a component's hash from the tag dictionary </summary>
|
||||||
|
[MarkerAttributes.UnsafeInternal]
|
||||||
|
internal void UnhashTaggedComponent(string __tag, Component __component) {
|
||||||
|
if(!_componentTagDictionary.ContainsKey(__tag)) _componentTagDictionary[__tag].Remove(__component);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,164 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
|
||||||
|
namespace AwperativeKernel;
|
||||||
|
|
||||||
|
|
||||||
|
public abstract partial class ComponentDocker
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary> Tells you whether the docker contains a component with the given tag </summary>
|
||||||
|
[MarkerAttributes.Expense(MarkerAttributes.Expense.ExpenseLevel.VeryLow), MarkerAttributes.Complexity(MarkerAttributes.Complexity.TimeComplexity.O1)]
|
||||||
|
public bool Contains([DebugAttributes.NotNull] string __tag) => DebugAttributes.NotNull.VerifyOrThrow(__tag) && _componentTagDictionary.ContainsKey(__tag);
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary> Tells you whether the docker contains a component with the given type</summary>
|
||||||
|
[MarkerAttributes.Expense(MarkerAttributes.Expense.ExpenseLevel.VeryLow), MarkerAttributes.Complexity(MarkerAttributes.Complexity.TimeComplexity.O1)]
|
||||||
|
public bool Contains<__Type>() where __Type : Component => _componentTypeDictionary.ContainsKey(typeof(__Type));
|
||||||
|
|
||||||
|
/// <summary> Tells you whether the docker contains a component with a given type and tag</summary>
|
||||||
|
[MarkerAttributes.Expense(MarkerAttributes.Expense.ExpenseLevel.VeryLow), MarkerAttributes.Complexity(MarkerAttributes.Complexity.TimeComplexity.O1)]
|
||||||
|
public bool Contains<__Type>([DebugAttributes.NotNull] string __tag) where __Type : Component => DebugAttributes.NotNull.VerifyOrThrow(__tag) && GetAll<__Type>(__tag).Any();
|
||||||
|
|
||||||
|
/// <summary> Tells you whether the docker contains a component with all the given tags </summary>
|
||||||
|
[MarkerAttributes.Expense(MarkerAttributes.Expense.ExpenseLevel.VeryLow), MarkerAttributes.Complexity(MarkerAttributes.Complexity.TimeComplexity.O1)]
|
||||||
|
public bool Contains(IEnumerable<string> __tags) => GetAll(__tags).Any();
|
||||||
|
|
||||||
|
/// <summary> Tells you whether the docker contains a component with all the given tags and the type</summary>
|
||||||
|
[MarkerAttributes.Expense(MarkerAttributes.Expense.ExpenseLevel.VeryLow), MarkerAttributes.Complexity(MarkerAttributes.Complexity.TimeComplexity.O1)]
|
||||||
|
public bool Contains<__Type>(IEnumerable<string> __tags) where __Type : Component => GetAll<__Type>(__tags).Any();
|
||||||
|
|
||||||
|
/// <summary> Tells you whether the docker contains the given component.</summary>
|
||||||
|
[MarkerAttributes.Expense(MarkerAttributes.Expense.ExpenseLevel.VeryLow), MarkerAttributes.Complexity(MarkerAttributes.Complexity.TimeComplexity.O1)]
|
||||||
|
public bool Contains([DebugAttributes.ComponentNotNull] Component __component) => DebugAttributes.NotNull.VerifyOrThrow(__component) && _componentTypeDictionary.TryGetValue(__component.GetType(), out var components) && components.Contains(__component);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary> Finds the first component with a given Type</summary>
|
||||||
|
[MarkerAttributes.Expense(MarkerAttributes.Expense.ExpenseLevel.VeryLow), MarkerAttributes.Complexity(MarkerAttributes.Complexity.TimeComplexity.O1)]
|
||||||
|
public __Type Get<__Type>() where __Type : Component => _componentTypeDictionary.TryGetValue(typeof(__Type), out HashSet<Component> Components) ? (__Type)Components.FirstOrDefault() : null;
|
||||||
|
|
||||||
|
/// <summary> Tries to find the first component with a given tag, and returns false if there is none</summary>
|
||||||
|
[MarkerAttributes.Expense(MarkerAttributes.Expense.ExpenseLevel.VeryLow), MarkerAttributes.Complexity(MarkerAttributes.Complexity.TimeComplexity.O1)]
|
||||||
|
public bool TryGet<__Type>(out __Type __component) where __Type : Component { __component = Get<__Type>(); return __component != null; }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary> Gets all components of a given type</summary>
|
||||||
|
[MarkerAttributes.Expense(MarkerAttributes.Expense.ExpenseLevel.VeryLow), MarkerAttributes.Complexity(MarkerAttributes.Complexity.TimeComplexity.O1)]
|
||||||
|
public IEnumerable<__Type> GetAll<__Type>() where __Type : Component => _componentTypeDictionary.TryGetValue(typeof(__Type), out var components) ? components.OfType<__Type>().ToList() : [];
|
||||||
|
|
||||||
|
/// <summary> Tries to get all components of a given type and returns false if there are none</summary>
|
||||||
|
[MarkerAttributes.Expense(MarkerAttributes.Expense.ExpenseLevel.VeryLow), MarkerAttributes.Complexity(MarkerAttributes.Complexity.TimeComplexity.O1)]
|
||||||
|
public bool TryGetAll<__Type>(out IEnumerable<__Type> __components) where __Type : Component { __components = GetAll<__Type>(); return __components.Any(); }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary> Finds all components that have all the given tags</summary>
|
||||||
|
[MarkerAttributes.Expense(MarkerAttributes.Expense.ExpenseLevel.VeryLow), MarkerAttributes.Complexity(MarkerAttributes.Complexity.TimeComplexity.ON)]
|
||||||
|
public IEnumerable<Component> GetAll(IEnumerable<string> __tags) {
|
||||||
|
|
||||||
|
HashSet<Component> components;
|
||||||
|
|
||||||
|
if (_componentTagDictionary.TryGetValue(__tags.First(), out var firstComponents)) components = firstComponents; else return [];
|
||||||
|
|
||||||
|
foreach(var tag in __tags)
|
||||||
|
if (_componentTagDictionary.TryGetValue(tag, out var taggedComponents))
|
||||||
|
components.RemoveWhere(x => !taggedComponents.Contains(x));
|
||||||
|
|
||||||
|
return components;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary> Tries to find all components that have all the given tags, returns false if there are none</summary>
|
||||||
|
[MarkerAttributes.Expense(MarkerAttributes.Expense.ExpenseLevel.VeryLow), MarkerAttributes.Complexity(MarkerAttributes.Complexity.TimeComplexity.ON)]
|
||||||
|
public bool TryGetAll(IEnumerable<string> __tags, out IEnumerable<Component> __components)
|
||||||
|
{ __components = GetAll(__tags); return __components.Any(); }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary> Finds all Components that have the given type, and all the given tags</summary>
|
||||||
|
[MarkerAttributes.Expense(MarkerAttributes.Expense.ExpenseLevel.VeryLow), MarkerAttributes.Complexity(MarkerAttributes.Complexity.TimeComplexity.ON)]
|
||||||
|
public IEnumerable<__Type> GetAll<__Type>(IEnumerable<string> __tags) where __Type : Component {
|
||||||
|
|
||||||
|
if (!__tags.Any())
|
||||||
|
return [];
|
||||||
|
|
||||||
|
HashSet<__Type> components = [];
|
||||||
|
|
||||||
|
if (_componentTagDictionary.TryGetValue(__tags.First(), out var firstComponents))
|
||||||
|
foreach (var component in firstComponents) if (component is __Type typedComponent) components.Add(typedComponent);
|
||||||
|
|
||||||
|
foreach(string tag in __tags)
|
||||||
|
if (_componentTagDictionary.TryGetValue(tag, out var taggedComponents))
|
||||||
|
components.RemoveWhere(x => !taggedComponents.Contains(x as Component));
|
||||||
|
|
||||||
|
return components.ToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary> Tries to find all the components that have the given tags and type, returns false if there are none</summary>
|
||||||
|
[MarkerAttributes.Expense(MarkerAttributes.Expense.ExpenseLevel.VeryLow), MarkerAttributes.Complexity(MarkerAttributes.Complexity.TimeComplexity.ON)]
|
||||||
|
public bool TryGetAll<__Type>(IEnumerable<string> __tags, out IEnumerable<__Type> __components) where __Type : Component {
|
||||||
|
__components = GetAll<__Type>(__tags); return __components.Any();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary> Gets all the components with the given tag</summary>
|
||||||
|
[MarkerAttributes.Expense(MarkerAttributes.Expense.ExpenseLevel.VeryLow), MarkerAttributes.Complexity(MarkerAttributes.Complexity.TimeComplexity.O1)]
|
||||||
|
public IEnumerable<Component> GetAll(string __tag) => GetAll([__tag]);
|
||||||
|
|
||||||
|
/// <summary> Tries to get all the components with the given tag, returns false if there are none</summary>
|
||||||
|
[MarkerAttributes.Expense(MarkerAttributes.Expense.ExpenseLevel.VeryLow), MarkerAttributes.Complexity(MarkerAttributes.Complexity.TimeComplexity.O1)]
|
||||||
|
public bool TryGetAll(string __tag, out IEnumerable<Component> __components) { __components = GetAll(__tag); return __components.Any(); }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary> Gets all the components that have a certain type, and a certain tag</summary>
|
||||||
|
[MarkerAttributes.Expense(MarkerAttributes.Expense.ExpenseLevel.VeryLow), MarkerAttributes.Complexity(MarkerAttributes.Complexity.TimeComplexity.ON)]
|
||||||
|
public IEnumerable<__Type> GetAll<__Type>(string __tag) where __Type : Component => GetAll<__Type>([__tag]);
|
||||||
|
|
||||||
|
/// <summary> Tries to get all the components with a certain tag, and a type. Returns false if there are none</summary>
|
||||||
|
[MarkerAttributes.Expense(MarkerAttributes.Expense.ExpenseLevel.VeryLow), MarkerAttributes.Complexity(MarkerAttributes.Complexity.TimeComplexity.ON)]
|
||||||
|
public bool TryGetAll<__Type>(string __tag, out IEnumerable<__Type> __components) where __Type : Component { __components = GetAll<__Type>(__tag); return __components.Any(); }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary> Gets the first component with all the given tags</summary>
|
||||||
|
[MarkerAttributes.Expense(MarkerAttributes.Expense.ExpenseLevel.VeryLow), MarkerAttributes.Complexity(MarkerAttributes.Complexity.TimeComplexity.ON)]
|
||||||
|
public Component Get(IEnumerable<string> __tags) => GetAll(__tags).FirstOrDefault();
|
||||||
|
|
||||||
|
/// <summary> Tries to get the first component with all the given tags. Returns false if there are none</summary>
|
||||||
|
[MarkerAttributes.Expense(MarkerAttributes.Expense.ExpenseLevel.VeryLow), MarkerAttributes.Complexity(MarkerAttributes.Complexity.TimeComplexity.ON)]
|
||||||
|
public bool TryGet(IEnumerable<string> __tags, out Component __component) { __component = Get(__tags); return __component != null; }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary> Finds the first component with the given tag</summary>
|
||||||
|
[MarkerAttributes.Expense(MarkerAttributes.Expense.ExpenseLevel.VeryLow), MarkerAttributes.Complexity(MarkerAttributes.Complexity.TimeComplexity.O1)]
|
||||||
|
public Component Get(string __tag) => GetAll([__tag]).FirstOrDefault();
|
||||||
|
|
||||||
|
/// <summary> Tries to find the first component with the given tag, returns false if there is none</summary>
|
||||||
|
[MarkerAttributes.Expense(MarkerAttributes.Expense.ExpenseLevel.VeryLow), MarkerAttributes.Complexity(MarkerAttributes.Complexity.TimeComplexity.O1)]
|
||||||
|
public bool TryGet(string __tag, out Component __component) { __component = Get(__tag); return __component != null; }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary> Gets the first component with the given type and tag</summary>
|
||||||
|
[MarkerAttributes.Expense(MarkerAttributes.Expense.ExpenseLevel.VeryLow), MarkerAttributes.Complexity(MarkerAttributes.Complexity.TimeComplexity.ON)]
|
||||||
|
public __Type Get<__Type>(string __tag) where __Type : Component => GetAll<__Type>(__tag).FirstOrDefault();
|
||||||
|
|
||||||
|
/// <summary> Tries to get the first component with the given type and tag, returns false if there is none.</summary>
|
||||||
|
[MarkerAttributes.Expense(MarkerAttributes.Expense.ExpenseLevel.VeryLow), MarkerAttributes.Complexity(MarkerAttributes.Complexity.TimeComplexity.ON)]
|
||||||
|
public bool TryGet<__Type>(string __tag, out __Type __component) where __Type : Component { __component = Get<__Type>(__tag); return __component != null; }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,96 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
|
||||||
|
namespace AwperativeKernel;
|
||||||
|
|
||||||
|
|
||||||
|
public abstract partial class ComponentDocker
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary> Moves a component belonging to the docker to another docker</summary>
|
||||||
|
public void Move([DebugAttributes.ComponentNotNull,DebugAttributes.DockerOwns] Component __component, [DebugAttributes.DockerNotNull,DebugAttributes.DifferentDocker] ComponentDocker __componentDocker) {
|
||||||
|
if(!DebugAttributes.ComponentNotNull.VerifyOrThrow(__component)) return;
|
||||||
|
if(!DebugAttributes.DockerOwns.VerifyOrThrow(this, __component)) return;
|
||||||
|
if(!DebugAttributes.DockerNotNull.VerifyOrThrow(__componentDocker)) return;
|
||||||
|
if(!DebugAttributes.DifferentDocker.VerifyOrThrow(this, __componentDocker)) return;
|
||||||
|
|
||||||
|
if (!Contains(__component)) {
|
||||||
|
Debug.LogError("Docker does not have ownership over Component!", ["ComponentType"], [__component.GetType().Name]); return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (__componentDocker == this) {
|
||||||
|
Debug.LogError("Docker already has Component!", ["ComponentType"], [__component.GetType().Name]); return;
|
||||||
|
}
|
||||||
|
|
||||||
|
RemoveComponentFromLists(__component);
|
||||||
|
__componentDocker.AddComponentToLists(__component);
|
||||||
|
|
||||||
|
__component.ComponentDocker = __componentDocker;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary> Moves all components in a list to another docker</summary>
|
||||||
|
public void MoveAll([DebugAttributes.EnumeratorNotNull, DebugAttributes.DockerOwns] IEnumerable<Component> __Components, [DebugAttributes.DockerNotNull, DebugAttributes.DifferentDocker] ComponentDocker __componentDocker) {
|
||||||
|
if(!DebugAttributes.EnumeratorNotNull.VerifyOrThrow(__Components)) return;
|
||||||
|
if(!DebugAttributes.DockerNotNull.VerifyOrThrow(__componentDocker)) return;
|
||||||
|
if(!DebugAttributes.DifferentDocker.VerifyOrThrow(this, __componentDocker)) return;
|
||||||
|
|
||||||
|
foreach (Component Component in __Components) {
|
||||||
|
if(!DebugAttributes.DockerOwns.VerifyOrThrow(__componentDocker, Component)) return;
|
||||||
|
Move(Component, __componentDocker);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary> Moves the first component with a given Type</summary>
|
||||||
|
[MarkerAttributes.Expense(MarkerAttributes.Expense.ExpenseLevel.VeryLow), MarkerAttributes.Complexity(MarkerAttributes.Complexity.TimeComplexity.O1)]
|
||||||
|
public void Move<__Type>(ComponentDocker __componentDocker) where __Type : Component => Move(Get<__Type>(), __componentDocker);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary> Moves all components of a given type</summary>
|
||||||
|
[MarkerAttributes.Expense(MarkerAttributes.Expense.ExpenseLevel.Low), MarkerAttributes.Complexity(MarkerAttributes.Complexity.TimeComplexity.ON)]
|
||||||
|
public void MoveAll<__Type>(ComponentDocker __componentDocker) where __Type : Component => MoveAll(GetAll<__Type>(), __componentDocker);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary> Moves all components that have all the given tags</summary>
|
||||||
|
[MarkerAttributes.Expense(MarkerAttributes.Expense.ExpenseLevel.VeryLow), MarkerAttributes.Complexity(MarkerAttributes.Complexity.TimeComplexity.ON)]
|
||||||
|
public void MoveAll(IEnumerable<string> __tags, ComponentDocker __componentDocker) => MoveAll(GetAll(__tags), __componentDocker);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary> Moves all Components that have the given type, and all the given tags</summary>
|
||||||
|
[MarkerAttributes.Expense(MarkerAttributes.Expense.ExpenseLevel.VeryLow), MarkerAttributes.Complexity(MarkerAttributes.Complexity.TimeComplexity.ON)]
|
||||||
|
public void MoveAll<__Type>(IEnumerable<string> __tags, ComponentDocker __componentDocker) where __Type : Component => MoveAll(GetAll<__Type>(__tags), __componentDocker);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary> Moves all the components with the given tag</summary>
|
||||||
|
[MarkerAttributes.Expense(MarkerAttributes.Expense.ExpenseLevel.VeryLow), MarkerAttributes.Complexity(MarkerAttributes.Complexity.TimeComplexity.O1)]
|
||||||
|
public void MoveAll(string __tag, ComponentDocker __componentDocker) => MoveAll(GetAll([__tag]), __componentDocker);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary> Moves all the components that have a certain type, and a certain tag</summary>
|
||||||
|
[MarkerAttributes.Expense(MarkerAttributes.Expense.ExpenseLevel.VeryLow), MarkerAttributes.Complexity(MarkerAttributes.Complexity.TimeComplexity.ON)]
|
||||||
|
public void MoveAll<__Type>(string __tag, ComponentDocker __componentDocker) where __Type : Component => MoveAll(GetAll<__Type>([__tag]), __componentDocker);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary> Moves the first component with the given tag</summary>
|
||||||
|
[MarkerAttributes.Expense(MarkerAttributes.Expense.ExpenseLevel.VeryLow), MarkerAttributes.Complexity(MarkerAttributes.Complexity.TimeComplexity.O1)]
|
||||||
|
public void Move(string __tag, ComponentDocker __componentDocker) => Move(GetAll([__tag]).FirstOrDefault(), __componentDocker);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary> Moves the moves component with the given type and tag</summary>
|
||||||
|
[MarkerAttributes.Expense(MarkerAttributes.Expense.ExpenseLevel.VeryLow), MarkerAttributes.Complexity(MarkerAttributes.Complexity.TimeComplexity.ON)]
|
||||||
|
public void Move<__Type>(string __tag, ComponentDocker __componentDocker) where __Type : Component => Move(GetAll<__Type>(__tag).FirstOrDefault(), __componentDocker);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,128 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Collections.ObjectModel;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Diagnostics.CodeAnalysis;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
|
||||||
|
namespace AwperativeKernel;
|
||||||
|
|
||||||
|
|
||||||
|
public abstract partial class ComponentDocker
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary> Attaches a preexisting component to the docker, this is not transferring the component, the method will throw an error if the component is already attached to a docker</summary>
|
||||||
|
[MarkerAttributes.Expense(MarkerAttributes.Expense.ExpenseLevel.Medium), MarkerAttributes.Complexity(MarkerAttributes.Complexity.TimeComplexity.O1)]
|
||||||
|
public void Add([DebugAttributes.ComponentNotNull,DebugAttributes.OrphanComponent] Component __component) {
|
||||||
|
if(!DebugAttributes.ComponentNotNull.VerifyOrThrow(__component)) return;
|
||||||
|
if(!DebugAttributes.OrphanComponent.VerifyOrThrow(__component)) return;
|
||||||
|
|
||||||
|
//Component has already been added to another docker
|
||||||
|
if (__component.ComponentDocker != null) { Debug.LogError("You cannot use add if the Component already belongs to a Docker, use Component.Transfer();"); return; }
|
||||||
|
|
||||||
|
InitiateComponent(__component);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary> Creates a new instance of that type of component and attaches it to the docker, and returns a reference to it.</summary>
|
||||||
|
public __Type Add<__Type>() where __Type : Component, new() { Component newComponent = new __Type(); InitiateComponent(newComponent); return (__Type)newComponent; }
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary> Creates a new instance of that type of component and attaches it to the docker, and returns a reference to it.</summary>
|
||||||
|
public __Type Add<__Type>(string name = null, [DebugAttributes.ValueFitsRange] int priority = 0, Collection<string> tags = null) where __Type : Component, new() {
|
||||||
|
Component newComponent = new __Type();
|
||||||
|
newComponent.Name = name ??= typeof(__Type).Name;
|
||||||
|
newComponent._tags = [..tags ??= []];
|
||||||
|
newComponent.Priority = priority;
|
||||||
|
|
||||||
|
InitiateComponent(newComponent); return (__Type)newComponent;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary> Initiates a component into the docker. </summary>
|
||||||
|
[MarkerAttributes.UnsafeInternal]
|
||||||
|
private void InitiateComponent(Component __component) {
|
||||||
|
//add to Component Docker's lists
|
||||||
|
AddComponentToLists(__component);
|
||||||
|
|
||||||
|
__component.ComponentDocker = this;
|
||||||
|
//create event
|
||||||
|
__component.TryEvent(4); __component.ChainEvent(4);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary> Destroys a component attached to the Docker </summary>
|
||||||
|
/// <param name="__component"></param>
|
||||||
|
public void Destroy([DebugAttributes.ComponentNotNull,DebugAttributes.DockerOwns] Component __component) {
|
||||||
|
Stopwatch timer = Stopwatch.StartNew();
|
||||||
|
if(!DebugAttributes.ComponentNotNull.VerifyOrThrow(__component)) return;
|
||||||
|
if(!DebugAttributes.DockerOwns.VerifyOrThrow(this, __component)) return;
|
||||||
|
|
||||||
|
__component.TryEvent(5);
|
||||||
|
__component.ChainEvent(5);
|
||||||
|
|
||||||
|
RemoveComponentFromLists(__component);
|
||||||
|
__component.ComponentDocker = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary> Destroys all the components in a given list </summary>
|
||||||
|
public void DestroyAll([DebugAttributes.ComponentNotNull, DebugAttributes.DockerOwns] IEnumerable<Component> __Components) { foreach(Component component in __Components) Destroy(component); }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary> Destroys the first component with a given Type</summary>
|
||||||
|
[MarkerAttributes.Expense(MarkerAttributes.Expense.ExpenseLevel.VeryLow), MarkerAttributes.Complexity(MarkerAttributes.Complexity.TimeComplexity.O1)]
|
||||||
|
public void Destroy<__Type>() where __Type : Component => Destroy(Get<__Type>());
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary> Destroys all components of a given type</summary>
|
||||||
|
[MarkerAttributes.Expense(MarkerAttributes.Expense.ExpenseLevel.Low), MarkerAttributes.Complexity(MarkerAttributes.Complexity.TimeComplexity.ON)]
|
||||||
|
public void DestroyAll<__Type>() where __Type : Component => DestroyAll(GetAll<__Type>());
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary> Destroys all components that have all the given tags</summary>
|
||||||
|
[MarkerAttributes.Expense(MarkerAttributes.Expense.ExpenseLevel.VeryLow), MarkerAttributes.Complexity(MarkerAttributes.Complexity.TimeComplexity.ON)]
|
||||||
|
public void DestroyAll(IEnumerable<string> __tags) => DestroyAll(GetAll(__tags));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary> Destroys all Components that have the given type, and all the given tags</summary>
|
||||||
|
[MarkerAttributes.Expense(MarkerAttributes.Expense.ExpenseLevel.VeryLow), MarkerAttributes.Complexity(MarkerAttributes.Complexity.TimeComplexity.ON)]
|
||||||
|
public void DestroyAll<__Type>(IEnumerable<string> __tags) where __Type : Component => DestroyAll(GetAll<__Type>(__tags));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary> Destroys all the components with the given tag</summary>
|
||||||
|
[MarkerAttributes.Expense(MarkerAttributes.Expense.ExpenseLevel.VeryLow), MarkerAttributes.Complexity(MarkerAttributes.Complexity.TimeComplexity.O1)]
|
||||||
|
public void DestroyAll(string __tag) => DestroyAll(GetAll([__tag]));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary> Destroys all the components that have a certain type, and a certain tag</summary>
|
||||||
|
[MarkerAttributes.Expense(MarkerAttributes.Expense.ExpenseLevel.VeryLow), MarkerAttributes.Complexity(MarkerAttributes.Complexity.TimeComplexity.ON)]
|
||||||
|
public void DestroyAll<__Type>(string __tag) where __Type : Component => DestroyAll(GetAll<__Type>([__tag]));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary> Destroys the first component with the given tag</summary>
|
||||||
|
[MarkerAttributes.Expense(MarkerAttributes.Expense.ExpenseLevel.VeryLow), MarkerAttributes.Complexity(MarkerAttributes.Complexity.TimeComplexity.O1)]
|
||||||
|
public void Destroy(string __tag) => Destroy(GetAll([__tag]).FirstOrDefault());
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary> Destroys the Destroys component with the given type and tag</summary>
|
||||||
|
[MarkerAttributes.Expense(MarkerAttributes.Expense.ExpenseLevel.VeryLow), MarkerAttributes.Complexity(MarkerAttributes.Complexity.TimeComplexity.ON)]
|
||||||
|
public void Destroy<__Type>(string __tag) where __Type : Component => Destroy(GetAll<__Type>(__tag).FirstOrDefault());
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,168 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Collections.Immutable;
|
|
||||||
using System.Diagnostics;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Reflection;
|
|
||||||
|
|
||||||
namespace AwperativeKernel;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Base class for all Awperative objects. Responsible for Managing hierarchy between Components and Scenes, has Extensive Component Manipulation Available.
|
|
||||||
/// Also transfers Time and Carries most of the responsibilities akin to the Component.
|
|
||||||
/// </summary>
|
|
||||||
/// <remarks> Please don't inherit this. I don't know why you would</remarks>
|
|
||||||
/// <author> Avery Norris </author>
|
|
||||||
public abstract partial class ComponentDocker : IEnumerable, IEnumerable<Component>, IEquatable<Component>, IEquatable<ComponentDocker>, IEquatable<Scene>
|
|
||||||
{
|
|
||||||
|
|
||||||
//Blocks external inheritance
|
|
||||||
internal ComponentDocker() {}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary> Core of the Docker, holds all of the Components, sorted by update priority.</summary>
|
|
||||||
[UnsafeInternal] internal readonly List<Component> _components = [];
|
|
||||||
/// <summary> Holds a list of Components at each of their types. This optimizes Get<Type> to O(1) </summary>
|
|
||||||
[UnsafeInternal] internal readonly Dictionary<Type, HashSet<Component>> _componentTypeDictionary = new();
|
|
||||||
/// <summary> Stores a Component in a list at each of their tags. This optimizes Get(string tag) to O(1)</summary>
|
|
||||||
[UnsafeInternal] internal readonly Dictionary<string, HashSet<Component>> _componentTagDictionary = new();
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//Indexers to allow juicy speedy: for loops
|
|
||||||
public Component this[[ValueFitsRange] int __index] {
|
|
||||||
get => !ValueFitsRange.VerifyOrThrow(__index, 0, _components.Count) ? null : _components[__index];
|
|
||||||
set { if (!ValueFitsRange.VerifyOrThrow(__index, 0, _components.Count)) return; _components[__index] = value; }
|
|
||||||
}
|
|
||||||
|
|
||||||
//Allows uint indexing, which makes me mad because nobody ever does those. To convert it over we just mask the largest bit, and cast to integer. That way
|
|
||||||
//no sign flipping buisness happens.
|
|
||||||
public Component this[uint __index] => this[(int) (__index & 0x7FFFFFFF)];
|
|
||||||
|
|
||||||
|
|
||||||
//Enumerators for convenient foreach loops
|
|
||||||
IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); }
|
|
||||||
public IEnumerator<Component> GetEnumerator() { return new ComponentDockEnum([.._components]); }
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>Amount of Components attached to the Docker</summary>
|
|
||||||
public int Count => _components.Count;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>Compares the Docker to another Scene.</summary>
|
|
||||||
public bool Equals(Scene __other) {
|
|
||||||
if (this is Scene scene)
|
|
||||||
return scene == __other;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>Compares the Docker to another Component.</summary>
|
|
||||||
public bool Equals(Component __other) {
|
|
||||||
if (this is Component component)
|
|
||||||
return component == __other;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>Compares the Docker to another Docker.</summary>
|
|
||||||
public bool Equals(ComponentDocker __other) {
|
|
||||||
return this == __other;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Resorts member of Component list to match the Priority.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="__component"> Component to modify</param>
|
|
||||||
/// <param name="__priority"> New priority for Component</param>
|
|
||||||
[UnsafeInternal]
|
|
||||||
internal void UpdatePriority(Component __component, int __priority) {
|
|
||||||
_components.Sort(Awperative._prioritySorter);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Sends an event to all Children and tells them to continue it.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="__timeEvent"> Type of event to send</param>
|
|
||||||
[UnsafeInternal]
|
|
||||||
internal void ChainEvent(int __timeEvent) {
|
|
||||||
for (int i = 0; i < _components.Count; i++) {
|
|
||||||
_components[i].TryEvent(__timeEvent);
|
|
||||||
_components[i].ChainEvent(__timeEvent);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Add a Component into the lists and dictionaries.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="__component"></param>
|
|
||||||
[UnsafeInternal]
|
|
||||||
private void AddComponentToLists(Component __component) {
|
|
||||||
var Type = __component.GetType();
|
|
||||||
_components.Add(__component);
|
|
||||||
if (!_componentTypeDictionary.TryAdd(Type, [__component])) _componentTypeDictionary[Type].Add(__component);
|
|
||||||
|
|
||||||
foreach (var tag in __component._tags) AddTagToComponent(tag, __component);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Removes a Component from the lists and dictionaries.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="__component"></param>
|
|
||||||
[UnsafeInternal]
|
|
||||||
private void RemoveComponentFromLists(Component __component) {
|
|
||||||
var Type = __component.GetType();
|
|
||||||
_components.Remove(__component);
|
|
||||||
|
|
||||||
if(_componentTypeDictionary.TryGetValue(Type, out var value)) value.Remove(__component);
|
|
||||||
|
|
||||||
foreach (var tag in __component._tags) RemoveTagFromComponent(tag, __component);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Hashes a Component in the tag dictionary
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="__tag">Tag to add</param>
|
|
||||||
/// <param name="__component">Component to add it to</param>
|
|
||||||
[UnsafeInternal]
|
|
||||||
internal void AddTagToComponent(string __tag, Component __component) {
|
|
||||||
if (!_componentTagDictionary.TryAdd(__tag, [__component]))
|
|
||||||
_componentTagDictionary[__tag].Add(__component);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Unhashes a Component from the tag dictionary
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="__tag">Tag to remove</param>
|
|
||||||
/// <param name="__component">Component to remove it from</param>
|
|
||||||
[UnsafeInternal]
|
|
||||||
internal void RemoveTagFromComponent(string __tag, Component __component) {
|
|
||||||
if(!_componentTagDictionary.ContainsKey(__tag)) _componentTagDictionary[__tag].Remove(__component);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// All children belonging to the Component.
|
|
||||||
/// </summary>
|
|
||||||
[CalculatedProperty, CalculatedPropertyExpense("Very Low")]
|
|
||||||
public IReadOnlyList<Component> Children => _components;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// All children and their children until the bottom of the scene. Uses Breadth First Search.
|
|
||||||
/// </summary>
|
|
||||||
[CalculatedProperty, CalculatedPropertyExpense("Medium O(Children)")]
|
|
||||||
public IReadOnlyList<Component> AllChildren => GetAllChildren();
|
|
||||||
public IReadOnlyList<Component> GetAllChildren() {
|
|
||||||
List<Component> targets = [.._components];
|
|
||||||
for (int i = 0; i < targets.Count; i++) targets.InsertRange(i + 1, targets[i]._components);
|
|
||||||
return [..targets];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,366 +0,0 @@
|
|||||||
|
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Collections.Immutable;
|
|
||||||
using System.Collections.ObjectModel;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Runtime.CompilerServices;
|
|
||||||
|
|
||||||
|
|
||||||
namespace AwperativeKernel;
|
|
||||||
|
|
||||||
|
|
||||||
public abstract partial class ComponentDocker
|
|
||||||
{
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Returns a bool based on if the Docker contains a Component with the given tag or not
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="__tag"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
public bool Contains([NotNull] string __tag)
|
|
||||||
=> NotNull.VerifyOrThrow(__tag) && _componentTagDictionary.ContainsKey(__tag);
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Returns a bool for if the Docker contains a Component of that type or not
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="__Type">Type of the Component</typeparam>
|
|
||||||
public bool Contains<__Type>() where __Type : Component
|
|
||||||
=> _componentTypeDictionary.ContainsKey(typeof(__Type));
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Returns a bool based on if the current __Component is owned by this Docker
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="__component"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
public bool Contains([ComponentNotNull] Component __component)
|
|
||||||
=> NotNull.VerifyOrThrow(__component) && _componentTypeDictionary.TryGetValue(__component.GetType(), out var components) && components.Contains(__component);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Finds all Components that have all the given tags
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="__tags"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
public bool Contains<__Type>([NotNull] string __tag)
|
|
||||||
=> NotNull.VerifyOrThrow(__tag) && GetAll<__Type>(__tag).Any();
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Finds all Components that have all the given tags
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="__tags"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
public bool Contains(IList<string> __tags) {
|
|
||||||
return GetAll(__tags).Any();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Finds all Components that have all the given tags
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="__tags"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
public bool Contains(IEnumerable<string> __tags) {
|
|
||||||
return GetAll(__tags).Any();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Finds all Components that have all the given tags
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="__tags"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
public bool Contains<__Type>(IList<string> __tags) {
|
|
||||||
return GetAll<__Type>(__tags).Any();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Finds all Components that have all the given tags
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="__tags"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
public bool Contains<__Type>(IEnumerable<string> __tags) {
|
|
||||||
return GetAll<__Type>(__tags).Any();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Searches and returns the first Component of a type found on the Docker.
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="__Type"> The Type of Component to search for</typeparam>
|
|
||||||
/// <returns></returns>
|
|
||||||
public __Type Get<__Type>() where __Type : Component {
|
|
||||||
return _componentTypeDictionary.TryGetValue(typeof(__Type), out var Components) ? (__Type)Components.FirstOrDefault() : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="__component"></param>
|
|
||||||
/// <typeparam name="__Type"></typeparam>
|
|
||||||
/// <returns></returns>
|
|
||||||
public bool TryGet<__Type>(out __Type __component) where __Type : Component {
|
|
||||||
__component = Get<__Type>(); return __component != null;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Searches and returns all Components of a type found on the Docker.
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="__Type"> The Type of Components to search for</typeparam>
|
|
||||||
/// <returns></returns>
|
|
||||||
public IReadOnlyList<__Type> GetAll<__Type>() where __Type : Component {
|
|
||||||
return _componentTypeDictionary.TryGetValue(typeof(__Type), out var components) ? components.OfType<__Type>().ToList() : [];
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="__components"></param>
|
|
||||||
/// <typeparam name="__Type"></typeparam>
|
|
||||||
/// <returns></returns>
|
|
||||||
public bool TryGetAll<__Type>(out IReadOnlyList<__Type> __components) where __Type : Component {
|
|
||||||
__components = GetAll<__Type>(); return __components.Any();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Finds all Components that have all the given tags
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="__tags"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
public IReadOnlyList<Component> GetAll(IList<string> __tags) {
|
|
||||||
|
|
||||||
if (__tags.Count == 0)
|
|
||||||
return [];
|
|
||||||
|
|
||||||
HashSet<Component> components;
|
|
||||||
|
|
||||||
if (_componentTagDictionary.TryGetValue(__tags[0], out var firstComponents)) components = firstComponents; else return [];
|
|
||||||
|
|
||||||
for (var i = 1; i < __tags.Count; i++)
|
|
||||||
if (_componentTagDictionary.TryGetValue(__tags[i], out var taggedComponents))
|
|
||||||
foreach (var component in components) if (!taggedComponents.Contains(component)) components.Remove(component);else return [];
|
|
||||||
|
|
||||||
return components.ToList();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Finds all Components that have all the given tags
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="__tags"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
public bool TryGetAll(IList<string> __tags, out IReadOnlyList<Component> __components) {
|
|
||||||
__components = GetAll(__tags); return __components.Any();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Finds all Components that have all the given tags, slower than GetAll() using IList. If you are being high performance, use that.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="__tags"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
public IReadOnlyList<Component> GetAll(IEnumerable<string> __tags) {
|
|
||||||
|
|
||||||
if (!__tags.Any())
|
|
||||||
return [];
|
|
||||||
|
|
||||||
HashSet<Component> components;
|
|
||||||
|
|
||||||
if (_componentTagDictionary.TryGetValue(__tags.First(), out var firstComponents)) components = firstComponents; else return [];
|
|
||||||
|
|
||||||
foreach(var tag in __tags)
|
|
||||||
if (_componentTagDictionary.TryGetValue(tag, out var taggedComponents))
|
|
||||||
foreach (var component in components) if (!taggedComponents.Contains(component)) components.Remove(component);else return [];
|
|
||||||
|
|
||||||
return components.ToList();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Finds all Components that have all the given tags
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="__tags"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
public bool TryGetAll(IEnumerable<string> __tags, out IReadOnlyList<Component> __components) {
|
|
||||||
__components = GetAll(__tags); return __components.Any();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Finds all Components that have all the given tags
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="__tags"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
public IReadOnlyList<__Type> GetAll<__Type>(IList<string> __tags) {
|
|
||||||
|
|
||||||
if (!__tags.Any())
|
|
||||||
return [];
|
|
||||||
|
|
||||||
HashSet<__Type> components = [];
|
|
||||||
|
|
||||||
if (_componentTagDictionary.TryGetValue(__tags[0], out var firstComponents))
|
|
||||||
foreach (var component in firstComponents) if (component is __Type typedComponent) components.Add(typedComponent);
|
|
||||||
|
|
||||||
for (var i = 1; i < __tags.Count; i++)
|
|
||||||
if (_componentTagDictionary.TryGetValue(__tags[i], out var taggedComponents))
|
|
||||||
foreach (var component in components) if (!taggedComponents.Contains(component as Component)) components.Remove(component);else return [];
|
|
||||||
|
|
||||||
return components.ToList();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Finds all Components that have all the given tags
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="__tags"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
public bool TryGetAll<__Type>(IList<string> __tags, out IReadOnlyList<__Type> __components) {
|
|
||||||
__components = GetAll<__Type>(__tags); return __components.Any();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Finds all Components that have all the given tags
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="__tags"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
public IReadOnlyList<__Type> GetAll<__Type>(IEnumerable<string> __tags) {
|
|
||||||
|
|
||||||
if (!__tags.Any())
|
|
||||||
return [];
|
|
||||||
|
|
||||||
HashSet<__Type> components = [];
|
|
||||||
|
|
||||||
if (_componentTagDictionary.TryGetValue(__tags.First(), out var firstComponents))
|
|
||||||
foreach (var component in firstComponents) if (component is __Type typedComponent) components.Add(typedComponent);
|
|
||||||
|
|
||||||
foreach(string tag in __tags)
|
|
||||||
if (_componentTagDictionary.TryGetValue(tag, out var taggedComponents))
|
|
||||||
foreach (var component in components) if (!taggedComponents.Contains(component as Component)) components.Remove(component);else return [];
|
|
||||||
|
|
||||||
return components.ToList();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Finds all Components that have all the given tags
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="__tags"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
public bool TryGetAll<__Type>(IEnumerable<string> __tags, out IReadOnlyList<__Type> __components) {
|
|
||||||
__components = GetAll<__Type>(__tags); return __components.Any();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Finds all Components that have all the given tags
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="__tags"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
public IReadOnlyList<Component> GetAll(string __tag) {
|
|
||||||
return GetAll([__tag]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Finds all Components that have all the given tags
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="__tags"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
public bool TryGetAll(string __tag, out IReadOnlyList<Component> __components) {
|
|
||||||
__components = GetAll(__tag); return __components.Any();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Finds all Components that have all the given tags
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="__tags"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
public IReadOnlyList<__Type> GetAll<__Type>(string __tag) {
|
|
||||||
return GetAll<__Type>([__tag]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Finds all Components that have all the given tags
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="__tags"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
public bool TryGetAll<__Type>(string __tag, out IReadOnlyList<__Type> __components) {
|
|
||||||
__components = GetAll<__Type>(__tag); return __components.Any();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public Component Get(IList<string> __tags) {
|
|
||||||
return GetAll(__tags).FirstOrDefault();
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool TryGet(IList<string> __tags, out Component __component) {
|
|
||||||
__component = Get(__tags); return __component != null;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public Component Get(IEnumerable<string> __tags) {
|
|
||||||
return GetAll(__tags).FirstOrDefault();
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool TryGet(IEnumerable<string> __tags, out Component __component) {
|
|
||||||
__component = Get(__tags); return __component != null;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public __Type Get<__Type>(IList<string> __tags) {
|
|
||||||
return GetAll<__Type>(__tags).FirstOrDefault();
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool TryGet<__Type>(IList<string> __tags, out __Type __component) {
|
|
||||||
__component = Get<__Type>(__tags); return __component != null;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public Component Get(string __tag) {
|
|
||||||
return GetAll([__tag]).FirstOrDefault();
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool TryGet(string __tag, out Component __component) {
|
|
||||||
__component = Get(__tag); return __component != null;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public __Type Get<__Type>(string __tag) {
|
|
||||||
return Get<__Type>([__tag]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool TryGet<__Type>(string __tag, out __Type __component) {
|
|
||||||
__component = Get<__Type>([__tag]); return __component != null;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,191 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Collections.ObjectModel;
|
|
||||||
using System.Diagnostics;
|
|
||||||
using System.Diagnostics.CodeAnalysis;
|
|
||||||
|
|
||||||
|
|
||||||
namespace AwperativeKernel;
|
|
||||||
|
|
||||||
|
|
||||||
public abstract partial class ComponentDocker
|
|
||||||
{
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Adds a previously instantiated Component to the Docker
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="__component">The Component to add</param>
|
|
||||||
/// <remarks> This is NOT meant to transfer a Component from one docker to another (Please use Move() for that).
|
|
||||||
/// And If you are just instantiating an Empty Component, also consider instead using Add<Type>();</remarks>
|
|
||||||
/// <author> Avery Norris</author>
|
|
||||||
#nullable enable
|
|
||||||
public void Add([ComponentNotNull,OrphanComponent] Component __component) {
|
|
||||||
if(!ComponentNotNull.VerifyOrThrow(__component)) return;
|
|
||||||
if(!OrphanComponent.VerifyOrThrow(__component)) return;
|
|
||||||
|
|
||||||
//Component has already been added to another docker
|
|
||||||
if (__component.ComponentDocker != null) { Debug.LogError("You cannot use add if the Component already belongs to a Docker, use Component.Transfer();"); return; }
|
|
||||||
|
|
||||||
InitiateComponent(__component);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Add a new Component to the Docker; and returns a reference to it!
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="__Type"> Type of Component to instantiate</typeparam>
|
|
||||||
/// <remarks>Component cannot have a Constructor</remarks>
|
|
||||||
/// <author> Avery Norris</author>
|
|
||||||
public __Type Add<__Type>() where __Type : Component, new() { Component newComponent = new __Type(); InitiateComponent(newComponent); return (__Type)newComponent; }
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Add a new Component to the Docker; and returns a reference to it!
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="__Type"> Type of Component to instantiate</typeparam>
|
|
||||||
/// <remarks>Component cannot have a Constructor</remarks>
|
|
||||||
/// <author> Avery Norris</author>
|
|
||||||
public __Type Add<__Type>(string name = null, [ValueFitsRange] int priority = 0, Collection<string> tags = null) where __Type : Component, new() {
|
|
||||||
Component newComponent = new __Type();
|
|
||||||
newComponent.Name = name ??= typeof(__Type).Name;
|
|
||||||
newComponent._tags = [..tags ??= []];
|
|
||||||
newComponent.Priority = priority;
|
|
||||||
|
|
||||||
InitiateComponent(newComponent); return (__Type)newComponent;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Sets important Component variables; and tries to send the Create() event.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="__component"></param>
|
|
||||||
/// <typeparam name="__Type"></typeparam>
|
|
||||||
private void InitiateComponent(Component __component) {
|
|
||||||
//add to Component Docker's lists
|
|
||||||
AddComponentToLists(__component);
|
|
||||||
|
|
||||||
__component.ComponentDocker = this;
|
|
||||||
//create event
|
|
||||||
__component.TryEvent(4); __component.ChainEvent(4);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Transfers a Component to another Docker
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="__component"> Component to move</param>
|
|
||||||
/// <param name="__componentDocker"> Docker to move component to</param>
|
|
||||||
/// <remarks> Components cannot transfer themselves with this Method!</remarks>
|
|
||||||
public void Move([ComponentNotNull,DockerOwns] Component __component, [DockerNotNull,DifferentDocker] ComponentDocker __componentDocker) {
|
|
||||||
if(!ComponentNotNull.VerifyOrThrow(__component)) return;
|
|
||||||
if(!DockerOwns.VerifyOrThrow(this, __component)) return;
|
|
||||||
if(!DockerNotNull.VerifyOrThrow(__componentDocker)) return;
|
|
||||||
if(!DifferentDocker.VerifyOrThrow(this, __componentDocker)) return;
|
|
||||||
|
|
||||||
if (!Contains(__component)) {
|
|
||||||
Debug.LogError("Docker does not have ownership over Component!", ["ComponentType"], [__component.GetType().Name]); return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (__componentDocker == this) {
|
|
||||||
Debug.LogError("Docker already has Component!", ["ComponentType"], [__component.GetType().Name]); return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var type = __component.GetType();
|
|
||||||
|
|
||||||
//Modify collections on both Dockers
|
|
||||||
RemoveComponentFromLists(__component);
|
|
||||||
__componentDocker.AddComponentToLists(__component);
|
|
||||||
|
|
||||||
__component.ComponentDocker = __componentDocker;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Transfers the first found Component of a specific type to another Docker
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="__componentDocker"> Docker to move the Component to</param>
|
|
||||||
/// <typeparam name="__Type"> Type of component</typeparam>
|
|
||||||
public void Move<__Type>([DockerNotNull,DifferentDocker] ComponentDocker __componentDocker) where __Type : Component => Move(Get<__Type>(), __componentDocker);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Transfers all Components in a collection to another Docker.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="__Components"> The Components that need to be transferred</param>
|
|
||||||
/// <param name="__componentDocker"> Docker to move Component to</param>
|
|
||||||
public void MoveAll([ComponentNotNull,DockerOwns] IEnumerable<Component> __Components, [DockerNotNull,DifferentDocker] ComponentDocker __componentDocker) { foreach (Component Component in (Component[])[..__Components]) Move(Component, __componentDocker); }
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Transfers all Components of a type to another Docker.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="__componentDocker"> Target Docker</param>
|
|
||||||
/// <typeparam name="__Type"> Type of Components to transfer</typeparam>
|
|
||||||
public void MoveAll<__Type>([DockerNotNull, DifferentDocker] ComponentDocker __componentDocker) where __Type : Component => MoveAll(GetAll<__Type>(), __componentDocker);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public TimeSpan total;
|
|
||||||
/// <summary>
|
|
||||||
/// Destroys a Component attached to the Docker
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="__component"></param>
|
|
||||||
public void Destroy([ComponentNotNull,DockerOwns] Component __component) {
|
|
||||||
Stopwatch timer = Stopwatch.StartNew();
|
|
||||||
if(!ComponentNotNull.VerifyOrThrow(__component)) return;
|
|
||||||
if(!DockerOwns.VerifyOrThrow(this, __component)) return;
|
|
||||||
|
|
||||||
__component.TryEvent(5);
|
|
||||||
__component.ChainEvent(5);
|
|
||||||
|
|
||||||
RemoveComponentFromLists(__component);
|
|
||||||
__component.ComponentDocker = null;
|
|
||||||
timer.Stop();
|
|
||||||
total += timer.Elapsed;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Destroys the first found Component of a given type
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="__Type"> Type of Component to destroy</typeparam>
|
|
||||||
public void Destroy<__Type>() where __Type : Component => DestroyAll(GetAll<__Type>());
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Destroys all Components from a given collection.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="__Components"></param>
|
|
||||||
public void DestroyAll([ComponentNotNull, DockerOwns] IReadOnlyList<Component> __Components) { for (var i = 0; i < __Components.Count; i++) Destroy(__Components[i]); }
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Destroys all Components of a given type
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="__Type"></typeparam>
|
|
||||||
public void DestroyAll<__Type>() where __Type : Component => DestroyAll(GetAll<__Type>());
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Destroys all Components attached to Docker
|
|
||||||
/// </summary>
|
|
||||||
public void DestroyAll() { for(var i = 0; i < _components.Count; i++) Destroy(_components[i]); }
|
|
||||||
}
|
|
||||||
@@ -27,16 +27,16 @@ public static partial class Awperative
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Bottom class of Awperative. Contains the OpenTK Instance.
|
/// Bottom class of Awperative. Contains the OpenTK Instance.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[NotNull, UnsafeInternal] private static Base Base;
|
[DebugAttributes.NotNull, MarkerAttributes.UnsafeInternal] private static Base Base;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// List of all scenes currently loaded in the kernel.
|
/// List of all scenes currently loaded in the kernel.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[CalculatedProperty, CalculatedPropertyExpense("Very Low")]
|
[MarkerAttributes.CalculatedProperty]
|
||||||
public static IReadOnlyList<Scene> Scenes => [.._scenes];
|
public static IEnumerable<Scene> Scenes => [.._scenes];
|
||||||
[UnsafeInternal] internal static HashSet<Scene> _scenes { get; private set; } = [];
|
[MarkerAttributes.UnsafeInternal] internal static HashSet<Scene> _scenes { get; private set; } = [];
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -68,7 +68,7 @@ public static partial class Awperative
|
|||||||
public static void AddScene(Scene __scene) {
|
public static void AddScene(Scene __scene) {
|
||||||
if (!ContainsScene(__scene.Name)) {
|
if (!ContainsScene(__scene.Name)) {
|
||||||
_scenes.Add(__scene);
|
_scenes.Add(__scene);
|
||||||
} else Debug.LogError("Awperative already has a Scene with that name!", ["Scene", "Name"], [GetScene(__scene.Name).GetHashCode().ToString(), __scene.Name]); return null;
|
} else Debug.LogError("Awperative already has a Scene with that name!", ["Scene", "Name"], [GetScene(__scene.Name).GetHashCode().ToString(), __scene.Name]); return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -17,13 +17,13 @@ public interface IDebugger
|
|||||||
public void Stop();
|
public void Stop();
|
||||||
|
|
||||||
public void LogAction(string __message);
|
public void LogAction(string __message);
|
||||||
public void LogAction(string __message, IReadOnlyList<string> __values, IReadOnlyList<string> __args);
|
public void LogAction(string __message, IEnumerable<string> __values, IEnumerable<string> __args);
|
||||||
|
|
||||||
public void LogWarning(string __message);
|
public void LogWarning(string __message);
|
||||||
public void LogWarning(string __message, IReadOnlyList<string> __values, IReadOnlyList<string> __args);
|
public void LogWarning(string __message, IEnumerable<string> __values, IEnumerable<string> __args);
|
||||||
|
|
||||||
public void LogError(string __message);
|
public void LogError(string __message);
|
||||||
public void LogError(string __message, IReadOnlyList<string> __values, IReadOnlyList<string> __args);
|
public void LogError(string __message, IEnumerable<string> __values, IEnumerable<string> __args);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -7,5 +7,5 @@ namespace AwperativeKernel;
|
|||||||
|
|
||||||
public interface IModuleManager
|
public interface IModuleManager
|
||||||
{
|
{
|
||||||
public IReadOnlyList<Assembly> GetDependencies();
|
public IEnumerable<Assembly> GetDependencies();
|
||||||
}
|
}
|
||||||
@@ -13,7 +13,7 @@ using System.Reflection;
|
|||||||
[assembly: System.Reflection.AssemblyCompanyAttribute("AwperativeKernel")]
|
[assembly: System.Reflection.AssemblyCompanyAttribute("AwperativeKernel")]
|
||||||
[assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")]
|
[assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")]
|
||||||
[assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")]
|
[assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")]
|
||||||
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+8c3803fcdf9411da13e462596847a88f1080bb39")]
|
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+41dbab5ce36d1e19917d80ba23482cbbd5b04533")]
|
||||||
[assembly: System.Reflection.AssemblyProductAttribute("AwperativeKernel")]
|
[assembly: System.Reflection.AssemblyProductAttribute("AwperativeKernel")]
|
||||||
[assembly: System.Reflection.AssemblyTitleAttribute("AwperativeKernel")]
|
[assembly: System.Reflection.AssemblyTitleAttribute("AwperativeKernel")]
|
||||||
[assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")]
|
[assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")]
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
1401ec548e06fa205cbd38d50de2d7971689c7694c0af3dc509c2945921d606a
|
b1a9e115a38433219f1f2e46313d2b5f0dd905c9ce83715b972f620249d7097d
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
22dd22d60e6c8fbd5110065c2450e37bceb89fe776160bf2e51e6a6a8825b2b1
|
5635b864dfc1ecaa0f2c52b65d178dd300857fd622e8afa48acfcadbd77f72d1
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1 +1 @@
|
|||||||
17722975223225869
|
17722975227348769
|
||||||
Reference in New Issue
Block a user