Component Docker be looking cute

This commit is contained in:
2026-02-28 00:57:23 -05:00
parent 89daba3278
commit 4a9f3d4476
10 changed files with 577 additions and 371 deletions

View File

@@ -1,6 +1,7 @@
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ABuffer_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2025_002E2_003Fresharper_002Dhost_003FSourcesCache_003F3dda17b8c491847aa4bd7c56dd3774cd376d43c76c182d041c160bbf4b812b0_003FBuffer_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AObject_002ECoreCLR_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2025_002E2_003Fresharper_002Dhost_003FSourcesCache_003F41f5f1afc2e9972034b9b24da6b9c16efd59be6d5ae907d0ea203e7865bed2_003FObject_002ECoreCLR_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AObject_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2025_002E2_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003Fd614e426e2154c38846b28c27d289de9ca738_003Fcf_003F95fabefb_003FObject_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/Environment/AssemblyExplorer/XmlDocument/@EntryValue">&lt;AssemblyExplorer&gt;
&lt;Assembly Path="/Users/averynorris/Programming/Test/Awperative/Awperative/bin/Debug/net8.0/Awperative.dll" /&gt;
&lt;/AssemblyExplorer&gt;</s:String></wpf:ResourceDictionary>

View File

@@ -18,38 +18,42 @@ public abstract partial class Component : ComponentDocker, IDisposable
/// <summary>
/// Current parent of the Component. Can be either Scene or another Component.
/// </summary>
/// <summary> Current parent of the Component. Can be either Scene or another Component.</summary>
public ComponentDocker ComponentDocker { get; internal set; } = null;
/// <summary>
/// If the component receives time events or not.
/// </summary>
public bool Enabled = true;
/// <summary>
/// Component name
/// </summary>
public string Name;
[NotNull]
public string Name {
get => _name;
set { if (!NotNull.VerifyOrThrow(value)) return; _name = value; }
} private string _name;
/// <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>
[UnsafeInternal]
private byte OrderProfile;
/// <summary> If the component receives time events or not. </summary>
[CalculatedProperty] [CalculatedPropertyExpense("Very Low")]
public bool Enabled {
get => (OrderProfile & 128) > 0;
set => OrderProfile = (byte)((OrderProfile & 127) | (value ? 128 : 0));
}
/// <summary>
/// Order for when Components are called on. Only applies between Components on the same Docker.
/// </summary>
/// <summary> Represents the Component's Update priority, can be set to any value ranging from -64 to 63; otherwise an error will throw! </summary>
[CalculatedProperty] [CalculatedPropertyExpense("Very Low")]
public int Priority {
get => _priority; set => ComponentDocker.UpdatePriority(this, value);
} internal int _priority;
get => (sbyte)(OrderProfile << 1) >> 1;
set {
if(!ValueFitsRange.VerifyOrThrow(value, -64, 63)) return;
OrderProfile = (byte)((OrderProfile & 0x80) | (value & 0x7F));
ComponentDocker.UpdatePriority(this, value);
}
}
@@ -204,12 +208,16 @@ public abstract partial class Component : ComponentDocker, IDisposable
public ImmutableArray<Component> GetAllChildren() {
List<Component> targets = [.._Components];
for (int i = 0; i < targets.Count; i++) targets.InsertRange(i + 1, targets[i]._Components);
List<Component> targets = [.._components];
for (int i = 0; i < targets.Count; i++) targets.InsertRange(i + 1, targets[i]._components);
return [..targets];
}
public virtual void Dispose() {
GC.SuppressFinalize(this);
}
public override string ToString() {
return this.Name;
}
}

View File

@@ -1,4 +1,6 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
namespace AwperativeKernel;
@@ -7,7 +9,7 @@ namespace AwperativeKernel;
/// <summary>
/// Requires that the Docker owns the parameter
/// </summary>
[AttributeUsage(AttributeTargets.Parameter)]
[AttributeUsage(AttributeTargets.All)]
public class DockerOwns : Attribute
{
@@ -38,7 +40,7 @@ public class DockerOwns : Attribute
/// <summary>
/// Requires that the Docker does not own the parameter
/// </summary>
[AttributeUsage(AttributeTargets.Parameter)]
[AttributeUsage(AttributeTargets.All)]
public class DockerDoesntOwn : Attribute
{
@@ -69,7 +71,7 @@ public class DockerDoesntOwn : Attribute
/// <summary>
/// Requires that the component is not attached to any Docker
/// </summary>
[AttributeUsage(AttributeTargets.Parameter)]
[AttributeUsage(AttributeTargets.All)]
public class OrphanComponent : Attribute
{
@@ -101,7 +103,7 @@ public class OrphanComponent : Attribute
/// <summary>
/// Requires that the Component is not null
/// </summary>
[AttributeUsage(AttributeTargets.Parameter)]
[AttributeUsage(AttributeTargets.All)]
public class ComponentNotNull : Attribute
{
@@ -125,7 +127,7 @@ public class ComponentNotNull : Attribute
/// <summary>
/// Requires that the Docker is not null
/// </summary>
[AttributeUsage(AttributeTargets.Parameter)]
[AttributeUsage(AttributeTargets.All)]
public class DockerNotNull : Attribute
{
@@ -149,7 +151,7 @@ public class DockerNotNull : Attribute
/// <summary>
/// Requires that the Scene is not null
/// </summary>
[AttributeUsage(AttributeTargets.Parameter)]
[AttributeUsage(AttributeTargets.All)]
public class SceneNotNull : Attribute
{
@@ -157,7 +159,6 @@ public class SceneNotNull : Attribute
/// <summary>
/// Verifies if the Scene is not null! Throws an error otherwise.
/// </summary>
/// <param name="__componentDocker"></param>
/// <returns></returns>
public static bool VerifyOrThrow(Scene __scene) {
if (__scene != null) return true;
@@ -170,10 +171,56 @@ public class SceneNotNull : Attribute
/// <summary>
/// Requires that everything in the collection is not null
/// </summary>
[AttributeUsage(AttributeTargets.All)]
public class CollectionNotNull : Attribute
{
/// <summary>
/// Verifies if the Scene is not null! Throws an error otherwise.
/// </summary>
/// <returns></returns>
public static bool VerifyOrThrow(Collection<object> __collection) {
for (var i = 0; i < __collection.Count; i++)
if (__collection[i] == null)
Debug.LogError("A Given Collection has null members!", ["Type"], [__collection.GetType().Name]);
return Awperative.IgnoreErrors;
}
}
/// <summary>
/// Requires that everything in the collection is not null
/// </summary>
[AttributeUsage(AttributeTargets.All)]
public class EnumeratorNotNull : Attribute
{
/// <summary>
/// Verifies if the Scene is not null! Throws an error otherwise.
/// </summary>
/// <returns></returns>
public static bool VerifyOrThrow(IEnumerable<object> __enumerator) {
foreach (object obj in __enumerator)
if (obj == null)
Debug.LogError("A Given Enumerator has null members!", ["Type"], [__enumerator.GetType().Name]);
return Awperative.IgnoreErrors;
}
}
/// <summary>
/// Requires that the object is not null
/// </summary>
[AttributeUsage(AttributeTargets.Parameter)]
[AttributeUsage(AttributeTargets.All)]
public class NotNull : Attribute
{
@@ -181,7 +228,6 @@ public class NotNull : Attribute
/// <summary>
/// Verifies if the Scene is not null! Throws an error otherwise.
/// </summary>
/// <param name="__componentDocker"></param>
/// <returns></returns>
public static bool VerifyOrThrow(Object __object) {
if (__object != null) return true;
@@ -199,7 +245,7 @@ public class NotNull : Attribute
/// <summary>
/// Requires that the Docker is a different docker than the one given
/// </summary>
[AttributeUsage(AttributeTargets.Parameter)]
[AttributeUsage(AttributeTargets.All)]
public class DifferentDocker : Attribute
{
@@ -207,7 +253,6 @@ public class DifferentDocker : Attribute
/// <summary>
/// Verifies if the Dockers are different!
/// </summary>
/// <param name="__componentDocker"></param>
/// <returns></returns>
public static bool VerifyOrThrow(ComponentDocker __docker, ComponentDocker __other) {
if (__docker != __other) return true;
@@ -221,3 +266,53 @@ public class DifferentDocker : Attribute
return Awperative.IgnoreErrors;
}
}
/// <summary>
/// Requires that the index fits a given collection
/// </summary>
[AttributeUsage(AttributeTargets.All)]
public class ValueFitsRange : Attribute
{
/// <summary>
/// Verifies if the value fits a range
/// </summary>
/// <param name="__componentDocker"></param>
/// <returns></returns>
public static bool VerifyOrThrow(int __index, int __min, int __max) {
if (__index >= __min && __index <= __max) return true;
Debug.LogError("Value does not fit range!", ["Index"], [__index.ToString("N0")]);
return Awperative.IgnoreErrors;
}
}
/// <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).
/// 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
/// </summary>
[AttributeUsage(AttributeTargets.All)]
public class UnsafeInternal : Attribute { }
/// <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)]
public class CalculatedProperty() : Attribute { }
/// <summary>
/// Just a way to write how expensive a calculated property can be.
/// </summary>
[AttributeUsage(AttributeTargets.All)]
public class CalculatedPropertyExpense(string Expense) : Attribute { }

View File

@@ -5,8 +5,6 @@ using System.Collections.Immutable;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using AwperativeKernel.Attributes;
namespace AwperativeKernel;
@@ -16,66 +14,68 @@ namespace AwperativeKernel;
/// </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>
public abstract partial class ComponentDocker : IEnumerable, IEnumerable<Component>, IEquatable<Component>, IEquatable<ComponentDocker>, IEquatable<Scene>
{
public bool Equals(Component __other) {
if (this is Component component) {
return component == __other;
} else return false;
}
public bool Equals(ComponentDocker __other) {
return this == __other;
}
//blocks external inheritance
//Blocks external inheritance
internal ComponentDocker() {}
IEnumerator IEnumerable.GetEnumerator() {
return GetEnumerator();
}
public IEnumerator<Component> GetEnumerator() {
Console.WriteLine("enumerator called" + _Components.Count);
return new ComponentDockEnum([.._Components]);
}
/// <summary>
/// List of all Components belonging to the Docker, Please Use Add, Get, Move and Destroy to modify it.
/// </summary>
public ImmutableArray<Component> Components => [.._Components];
/// <summary>
/// Amount of all Components in the Docker
/// </summary>
public int Count => _Components.Count;
/// <summary>
/// Core of Docker, contains all of our precious Components. Sorts them by their priorities with highest going first.
/// If they are equal it defaults to hash codes to ensure consistent Behavior
/// </summary>
internal List<Component> _Components = new();
internal Dictionary<Type, HashSet<Component>> _ComponentDictionary = new();
internal Dictionary<string, HashSet<Component>> _taggedComponents = new();
/// <summary> Core of the Docker, holds all of the Components, sorted by update priority.</summary>
[UnsafeInternal] internal List<Component> _components = new();
/// <summary> Holds a list of Components at each of their types. This optimizes Get&lt;Type&gt; to O(1) </summary>
[UnsafeInternal] internal 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 Dictionary<string, HashSet<Component>> _componentTagDictionary = new();
/// <summary>
/// How Priority is sorted.
/// </summary>
private readonly static Comparer<Component> _componentSorter = Comparer<Component>.Create((a, b) => {
int result = b.Priority.CompareTo(a.Priority);
return (result != 0) ? result : a.GetHashCode().CompareTo(b.GetHashCode());
});
//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> List of all Components belonging to the Docker, Please Use Add, Get, Move and Destroy to modify it </summary>
public IReadOnlyList<Component> Components => _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;
}
@@ -86,305 +86,69 @@ public abstract partial class ComponentDocker : IEnumerable, IEnumerable<Compone
/// </summary>
/// <param name="__component"> Component to modify</param>
/// <param name="__priority"> New priority for Component</param>
[UnsafeInternal]
internal void UpdatePriority(Component __component, int __priority) {
//add ownership enforcement/method
_Components.Sort(_componentSorter);
__component._priority = __priority;
_components.Sort(Awperative._prioritySorter);
}
//internal void TryEvent(Component __component, Awperative.TimeEvent __timeEvent) => __component.TryEvent(__timeEvent);
/// <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);
for (int i = 0; i < _components.Count; i++) {
_components[i].TryEvent(__timeEvent);
_components[i].ChainEvent(__timeEvent);
}
}
/// <summary>
/// Add component to its proper place in the dictionary and resort values to match priorities.
/// </summary>
/// <param name="__component"> Component to hash</param>
/// <param name="__tag"> Value to try and hash</param>
internal void HashTaggedComponent(Component __component, string __tag) {
if (!__component._tags.Add(__tag)) {
Debug.LogError("Component already has tag!", ["Component", "Type", "Tag", "Docker"],
[__component.GetHashCode().ToString(), __component.GetType().ToString(), __tag, GetHashCode().ToString()]); return;
}
if (_taggedComponents.TryGetValue(__tag, out SortedSet<Component> components)) {
components.Add(__component);
} else { _taggedComponents.Add(__tag, new SortedSet<Component>(_componentSorter)); _taggedComponents[__tag].Add(__component); }
}
/// <summary>
///
/// Add a Component into the lists and dictionaries.
/// </summary>
/// <param name="__component"></param>
/// <param name="__tag"></param>
internal void UnhashTaggedComponent(Component __component, string __tag) {
if (!__component._tags.Remove(__tag)) {
Debug.LogError("Component already doesn't have that tag!", ["Component", "Type", "Tag", "Docker"],
[__component.GetHashCode().ToString(), __component.GetType().ToString(), __tag, GetHashCode().ToString()]); return;
}
if (_taggedComponents.TryGetValue(__tag, out SortedSet<Component> components)) {
components.Remove(__component);
if(components.Count == 0)
_taggedComponents.Remove(__tag);
}
}
/// <summary>
/// Finds the first instance of a component with a given tag
/// </summary>
/// <param name="__tag"> Tag to search for</param>
/// <returns></returns>
internal Component Get(string __tag) {
if (_taggedComponents.TryGetValue(__tag, out SortedSet<Component> components))
return ((Component[])[..components])[0];
return null;
}
/// <summary>
/// Finds the first instance of a component with a given tag
/// </summary>
/// <param name="__tag"> Tag to search for</param>
/// <param name="__component">Component that has been found</param>
/// <returns></returns>
internal bool TryGet(string __tag, out Component __component) { __component = Get(__tag); return __component != null; }
/// <summary>
/// Finds all Components with a given tag
/// </summary>
/// <param name="__tag"></param>
/// <returns></returns>
internal ImmutableArray<Component> GetAll(string __tag) {
if (_taggedComponents.TryGetValue(__tag, out SortedSet<Component> components))
return [..components];
return [];
}
/// <summary>
/// Searches for all Components with a given tag
/// </summary>
/// <param name="__tag"></param>
/// <param name="__components"></param>
/// <returns></returns>
internal bool TryGetAll(string __tag, out ImmutableArray<Component> __components) { __components = GetAll(__tag); return __components.Length > 0; }
/// <summary>
/// Finds the first Component that has all the given tags
/// </summary>
/// <param name="__tags"></param>
/// <returns></returns>
internal Component Get(List<string> __tags) { ImmutableArray<Component> returnValue = GetAll(__tags); return returnValue.Length > 0 ? returnValue[0] : null; }
/// <summary>
/// Finds the first Component that has all the given tags
/// </summary>
/// <param name="__tags"></param>
/// <returns></returns>
internal bool TryGet(List<string> __tags, out Component __component) { __component = Get(__tags); return __component != null; }
/// <summary>
/// Finds all Components that have all the given tags
/// </summary>
/// <param name="__tags"></param>
/// <returns></returns>
internal ImmutableArray<Component> GetAll(List<string> __tags) {
if (__tags.Count == 0)
return [];
SortedSet<Component> foundComponents = _taggedComponents[__tags[0]];
for (int i = 1; i < __tags.Count; i++) {
foreach (Component component in (Component[])[..foundComponents]) {
if (!_taggedComponents[__tags[i]].Contains(component)) foundComponents.Remove(component);
}
}
return [..foundComponents];
}
/// <summary>
/// Tries to get all components with the given tags
/// </summary>
/// <param name="__tags"></param>
/// <param name="__components"></param>
/// <returns></returns>
internal bool TryGetAll(List<string> __tags, out ImmutableArray<Component> __components) { __components = GetAll(__tags); return __components.Length > 0; }
/// <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 {
//Iterates through the loop and returns if a match is found
foreach (Component component in (Component[])[.._Components])
if (component is __Type foundComponent) return foundComponent;
//Throws error if there is no Component found
Debug.LogError("Docker does not have target Component", ["Type", "Docker"],
[typeof(__Type).ToString(), GetHashCode().ToString()]); return 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 ImmutableArray<__Type> GetAll<__Type>() where __Type : Component {
List<__Type> foundComponents = [];
//Iterates through the loop and returns if a match is found
foreach (Component component in (Component[])[.._Components]) {
if (component is __Type foundComponent) {
foundComponents.Add(foundComponent);
}
}
//Throws error if there is no Component found
if (foundComponents.Count == 0) {
Debug.LogError("Docker does not have target Component", ["Type", "Docker"],
[typeof(__Type).ToString(), GetHashCode().ToString()]);
return [];
}
return [..foundComponents];
}
/// <summary>
///
/// </summary>
/// <param name="__components"></param>
/// <typeparam name="__Type"></typeparam>
/// <returns></returns>
public bool TryGetAll<__Type>(out ImmutableArray<__Type> __components) where __Type : Component { __components = GetAll<__Type>(); return __components.Length > 0; }
[UnsafeInternal]
private void AddComponentToLists(Component __component) {
var Type = __component.GetType();
_Components.Add(__component);
if (!_ComponentDictionary.TryAdd(Type, [__component])) _ComponentDictionary[Type].Add(__component);
_components.Add(__component);
if (!_componentTypeDictionary.TryAdd(Type, [__component])) _componentTypeDictionary[Type].Add(__component);
for(var i = 0; i < __component.Tags.Length; i++) { HashTaggedComponent(__component.Tags[i], __component); }
for(var i = 0; i < __component.Tags.Length; i++) { AddTagToComponent(__component.Tags[i], __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);
_components.Remove(__component);
if(!_ComponentDictionary.ContainsKey(Type)) _ComponentDictionary[Type].Remove(__component);
if(!_componentTypeDictionary.ContainsKey(Type)) _componentTypeDictionary[Type].Remove(__component);
for(var i = 0; i < __component.Tags.Length; i++) { UnhashTaggedComponent(__component.Tags[i], __component); }
for(var i = 0; i < __component.Tags.Length; i++) { RemoveTagFromComponent(__component.Tags[i], __component); }
}
private void HashTaggedComponent(string __tag, Component __component) {
if (!_taggedComponents.TryAdd(__component.Tags[i], [__component]))
_taggedComponents[__component.Tags[i]].Add(__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]
private void AddTagToComponent(string __tag, Component __component) {
if (!_componentTagDictionary.TryAdd(__tag, [__component]))
_componentTagDictionary[__tag].Add(__component);
}
private void UnhashTaggedComponent(string __tag, Component __component) {
if(!_taggedComponents.ContainsKey(__tag)) _taggedComponents[__tag].Remove(__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]
private void RemoveTagFromComponent(string __tag, Component __component) {
if(!_componentTagDictionary.ContainsKey(__tag)) _componentTagDictionary[__tag].Remove(__component);
}
}

View File

@@ -1,5 +1,12 @@
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Collections.ObjectModel;
using System.Linq;
using System.Runtime.CompilerServices;
namespace AwperativeKernel;
@@ -12,14 +19,16 @@ public abstract partial class ComponentDocker
/// </summary>
/// <param name="__tag"></param>
/// <returns></returns>
public bool Contains([NotNull] string __tag) => NotNull.VerifyOrThrow(__tag) && _taggedComponents.ContainsKey(__tag);
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 => _ComponentDictionary.ContainsKey(typeof(__Type));
public bool Contains<__Type>() where __Type : Component
=> _componentTypeDictionary.ContainsKey(typeof(__Type));
@@ -28,5 +37,330 @@ public abstract partial class ComponentDocker
/// </summary>
/// <param name="__component"></param>
/// <returns></returns>
public bool Contains([ComponentNotNull,DockerOwns] Component __component) => NotNull.VerifyOrThrow(__component) && DockerOwns.VerifyOrThrow(this, __component) && _Components.Contains(__component);
public bool Contains([ComponentNotNull,DockerOwns] Component __component)
=> NotNull.VerifyOrThrow(__component) && DockerOwns.VerifyOrThrow(this, __component) && _components.Contains(__component);
/// <summary>
/// Finds all Components that have all the given tags
/// </summary>
/// <param name="__tags"></param>
/// <returns></returns>
public bool Contains<__Type>(string __tag) {
return 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 (IReadOnlyList<__Type>)_componentTypeDictionary.GetValueOrDefault(typeof(__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;
}
}

View File

@@ -185,5 +185,5 @@ public abstract partial class ComponentDocker
/// <summary>
/// Destroys all Components attached to Docker
/// </summary>
public void DestroyAll() { for(var i = 0; i < _Components.Count; i++) Destroy(_Components[i]); }
public void DestroyAll() { for(var i = 0; i < _components.Count; i++) Destroy(_components[i]); }
}

View File

@@ -144,9 +144,13 @@ public static class Awperative
}
}
internal static Comparer<Component> _prioritySorter = Comparer<Component>.Create((a, b) => {
int result = b.Priority.CompareTo(a.Priority);
return (result != 0) ? result : a.GetHashCode().CompareTo(b.GetHashCode());
});
/// <summary>

View File

@@ -13,7 +13,7 @@ using System.Reflection;
[assembly: System.Reflection.AssemblyCompanyAttribute("AwperativeKernel")]
[assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")]
[assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")]
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+abd47153ad47e5c2d5300dcab27ac4628f468ab1")]
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+89daba3278f3425069ad72c1e889e2d5c12ffebb")]
[assembly: System.Reflection.AssemblyProductAttribute("AwperativeKernel")]
[assembly: System.Reflection.AssemblyTitleAttribute("AwperativeKernel")]
[assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")]

View File

@@ -1 +1 @@
8e04a8f03c26d3cf7cdf50da4979193904b566d6f40392f132e749a5bd9092b9
fd20f709f0c09dd5820bb098e786f44ec3ff4e66593743fc97dd004440680728

View File

@@ -1 +1 @@
e4b135c3045a438e4953bde74a036a568da5652715efda203daab787973e7f7e
fb1e5e1f7af8237ad8bd2d22975bb0a75e1f0b64faaaa35af565406d250bd296