feat: refactoring again, trying to find a naming convention

This commit is contained in:
Dylan R. E. Moonfire 2022-07-08 23:31:38 -05:00
parent 2b73a04fdb
commit 148e0c149e
14 changed files with 664 additions and 149 deletions

View file

@ -4,7 +4,7 @@ root = true
[*]
charset = utf-8
end_of_line = lf
insert_final_newline = true
insert_final_newline = false
indent_style = space
indent_size = 4
@ -31,11 +31,22 @@ dotnet_naming_rule.private_instance_fields_rule.import_to_resharper = as_predefi
dotnet_naming_rule.private_instance_fields_rule.severity = warning
dotnet_naming_rule.private_instance_fields_rule.style = lower_camel_case_style
dotnet_naming_rule.private_instance_fields_rule.symbols = private_instance_fields_symbols
dotnet_naming_rule.private_static_fields_override_rule.import_to_resharper = False
dotnet_naming_rule.private_static_fields_override_rule.severity = warning
dotnet_naming_rule.private_static_fields_override_rule.style = upper_camel_case_style
dotnet_naming_rule.private_static_fields_override_rule.symbols = private_static_fields_override_symbols
dotnet_naming_rule.private_static_fields_rule.import_to_resharper = as_predefined
dotnet_naming_rule.private_static_fields_rule.resharper_style = AaBb, aaBb
dotnet_naming_rule.private_static_fields_rule.severity = warning
dotnet_naming_rule.private_static_fields_rule.style = upper_camel_case_style
dotnet_naming_rule.private_static_fields_rule.symbols = private_static_fields_symbols
dotnet_naming_rule.private_static_fields_rule_1.import_to_resharper = True
dotnet_naming_rule.private_static_fields_rule_1.resharper_description = PrivateStaticFields
dotnet_naming_rule.private_static_fields_rule_1.resharper_guid = 2ec29786-2764-45cc-849e-7a476ce55db8
dotnet_naming_rule.private_static_fields_rule_1.resharper_style = AaBb, aaBb
dotnet_naming_rule.private_static_fields_rule_1.severity = warning
dotnet_naming_rule.private_static_fields_rule_1.style = upper_camel_case_style
dotnet_naming_rule.private_static_fields_rule_1.symbols = private_static_fields_symbols_1
dotnet_naming_rule.private_static_readonly_rule.import_to_resharper = as_predefined
dotnet_naming_rule.private_static_readonly_rule.severity = warning
dotnet_naming_rule.private_static_readonly_rule.style = upper_camel_case_style
@ -54,9 +65,17 @@ dotnet_naming_symbols.private_constants_symbols.applicable_kinds = field
dotnet_naming_symbols.private_constants_symbols.required_modifiers = const
dotnet_naming_symbols.private_instance_fields_symbols.applicable_accessibilities = private
dotnet_naming_symbols.private_instance_fields_symbols.applicable_kinds = field
dotnet_naming_symbols.private_static_fields_override_symbols.applicable_accessibilities = local,private
dotnet_naming_symbols.private_static_fields_override_symbols.applicable_kinds = field
dotnet_naming_symbols.private_static_fields_override_symbols.required_modifiers = const,static
dotnet_naming_symbols.private_static_fields_symbols.applicable_accessibilities = private
dotnet_naming_symbols.private_static_fields_symbols.applicable_kinds = field
dotnet_naming_symbols.private_static_fields_symbols.required_modifiers = static
dotnet_naming_symbols.private_static_fields_symbols_1.applicable_accessibilities = local,private
dotnet_naming_symbols.private_static_fields_symbols_1.applicable_kinds = field
dotnet_naming_symbols.private_static_fields_symbols_1.required_modifiers = static
dotnet_naming_symbols.private_static_fields_symbols_1.resharper_applicable_kinds = field
dotnet_naming_symbols.private_static_fields_symbols_1.resharper_required_modifiers = static
dotnet_naming_symbols.private_static_readonly_symbols.applicable_accessibilities = private
dotnet_naming_symbols.private_static_readonly_symbols.applicable_kinds = field
dotnet_naming_symbols.private_static_readonly_symbols.required_modifiers = static, readonly
@ -75,11 +94,14 @@ dotnet_style_require_accessibility_modifiers = for_non_interface_members:suggest
# ReSharper properties
resharper_alignment_tab_fill_style = optimal_fill
resharper_align_multiline_binary_expressions_chain = false
resharper_align_multiline_statement_conditions = false
resharper_apply_on_completion = true
resharper_autodetect_indent_settings = true
resharper_blank_lines_after_control_transfer_statements = 1
resharper_blank_lines_after_multiline_statements = 1
resharper_blank_lines_around_single_line_auto_property = 1
resharper_blank_lines_around_single_line_property = 1
resharper_blank_lines_before_control_transfer_statements = 1
resharper_blank_lines_before_multiline_statements = 1
resharper_blank_lines_before_single_line_comment = 1
resharper_braces_for_for = required
resharper_braces_for_foreach = required
@ -124,6 +146,8 @@ resharper_keep_existing_declaration_block_arrangement = true
resharper_keep_existing_declaration_parens_arrangement = false
resharper_keep_existing_embedded_block_arrangement = true
resharper_keep_existing_enum_arrangement = true
resharper_keep_existing_linebreaks = true
resharper_keep_user_linebreaks = true
resharper_min_blank_lines_after_imports = 1
resharper_nested_ternary_style = expanded
resharper_new_line_before_while = true
@ -133,7 +157,7 @@ resharper_place_type_constraints_on_same_line = false
resharper_protobuf_insert_final_newline = true
resharper_qualified_using_at_nested_scope = true
resharper_resx_alignment_tab_fill_style = optimal_fill
resharper_T4_alignment_tab_fill_style = optimal_fill
resharper_t4_alignment_tab_fill_style = optimal_fill
resharper_t4_insert_final_newline = true
resharper_use_continuous_indent_inside_initializer_braces = false
resharper_use_indents_from_main_language_in_file = false
@ -146,7 +170,7 @@ resharper_wrap_before_extends_colon = true
resharper_wrap_before_first_type_parameter_constraint = true
resharper_wrap_before_type_parameter_langle = true
resharper_wrap_chained_binary_expressions = chop_if_long
resharper_wrap_chained_method_calls = chop_if_long
resharper_wrap_chained_method_calls = chop_always
resharper_wrap_object_and_collection_initializer_style = chop_always
resharper_xmldoc_alignment_tab_fill_style = optimal_fill
resharper_xmldoc_indent_child_elements = ZeroIndent
@ -162,6 +186,7 @@ resharper_arrange_type_modifiers_highlighting = hint
resharper_built_in_type_reference_style_for_member_access_highlighting = hint
resharper_built_in_type_reference_style_highlighting = hint
resharper_check_namespace_highlighting = none
resharper_class_never_instantiated_global_highlighting = none
resharper_convert_to_auto_property_highlighting = none
resharper_localizable_element_highlighting = none
resharper_redundant_comma_in_attribute_list_highlighting = none
@ -205,3 +230,8 @@ tab_width = 4
indent_style = space
indent_size = 4
tab_width = 4
[*.{appxmanifest,asax,ascx,aspx,axaml,build,c,c++,cc,cginc,compute,cp,cpp,cs,cshtml,cu,cuh,cxx,dtd,fx,fxh,h,hh,hlsl,hlsli,hlslinc,hpp,hxx,inc,inl,ino,ipp,master,mpp,mq4,mq5,mqh,nuspec,paml,razor,resw,resx,skin,tpp,usf,ush,vb,xaml,xamlx,xoml,xsd}]
indent_style = space
indent_size = 4
tab_width = 4

View file

@ -85,7 +85,10 @@
<s:Int64 x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/KEEP_BLANK_LINES_IN_CODE/@EntryValue">1</s:Int64>
<s:Int64 x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/KEEP_BLANK_LINES_IN_DECLARATIONS/@EntryValue">1</s:Int64>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/KEEP_EXISTING_DECLARATION_PARENS_ARRANGEMENT/@EntryValue">False</s:Boolean>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/KEEP_EXISTING_INVOCATION_PARENS_ARRANGEMENT/@EntryValue">False</s:Boolean>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/LINE_FEED_AT_FILE_END/@EntryValue">True</s:Boolean>
<s:Int64 x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/MAX_ENUM_MEMBERS_ON_LINE/@EntryValue">1</s:Int64>
<s:Int64 x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/MAX_FORMAL_PARAMETERS_ON_LINE/@EntryValue">1</s:Int64>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/NESTED_TERNARY_STYLE/@EntryValue">EXPANDED</s:String>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/PLACE_ACCESSOR_ATTRIBUTE_ON_SAME_LINE_EX/@EntryValue">NEVER</s:String>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/PLACE_ACCESSORHOLDER_ATTRIBUTE_ON_SAME_LINE_EX/@EntryValue">NEVER</s:String>
@ -115,7 +118,9 @@
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/WRAP_CHAINED_METHOD_CALLS/@EntryValue">CHOP_IF_LONG</s:String>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/WRAP_EXTENDS_LIST_STYLE/@EntryValue">CHOP_IF_LONG</s:String>
<s:Int64 x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/WRAP_LIMIT/@EntryValue">80</s:Int64>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/WRAP_MULTIPLE_TYPE_PARAMEER_CONSTRAINTS_STYLE/@EntryValue">CHOP_ALWAYS</s:String>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/WRAP_PARAMETERS_STYLE/@EntryValue">CHOP_IF_LONG</s:String>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/WRAP_VERBATIM_INTERPOLATED_STRINGS/@EntryValue">CHOP_IF_LONG</s:String>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CssFormatter/ALIGNMENT_TAB_FILL_STYLE/@EntryValue">OPTIMAL_FILL</s:String>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/HtmlFormatter/ALIGNMENT_TAB_FILL_STYLE/@EntryValue">OPTIMAL_FILL</s:String>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/JavaScriptCodeFormatting/ALIGNMENT_TAB_FILL_STYLE/@EntryValue">OPTIMAL_FILL</s:String>

View file

@ -1,3 +1,3 @@
# Gallium CIL
A small Entity-Component-System (ECS) that is built around LINQ calls and IEnumerable<Entity> objects.
A small Entity-Component-System (ECS) that is built around LINQ calls and `IEnumerable<Entity>` objects.

View file

@ -64,20 +64,6 @@ namespace Gallium
return this.Has(typeof(T1));
}
/// <summary>
/// Gets a value indicating whether the entity has components of the given types
/// registered.
/// </summary>
/// <typeparam name="T1">The first component type.</typeparam>
/// <returns>
/// True if there are components of the given type exists, otherwise
/// false.
/// </returns>
public bool HasAll<T1>()
{
return this.Has<T1>();
}
/// <summary>
/// Gets a value indicating whether the entity has components of the given types
/// registered.
@ -90,7 +76,7 @@ namespace Gallium
/// </returns>
public bool HasAll<T1, T2>()
{
return this.Has<T1>() && this.Has<T2>();
return this.HasAll(typeof(T1), typeof(T2));
}
/// <summary>
@ -106,7 +92,7 @@ namespace Gallium
/// </returns>
public bool HasAll<T1, T2, T3>()
{
return this.Has<T1>() && this.Has<T2>() && this.Has<T3>();
return this.HasAll(typeof(T1), typeof(T2), typeof(T3));
}
/// <summary>
@ -123,10 +109,7 @@ namespace Gallium
/// </returns>
public bool HasAll<T1, T2, T3, T4>()
{
return this.Has<T1>()
&& this.Has<T2>()
&& this.Has<T3>()
&& this.Has<T4>();
return this.HasAll(typeof(T1), typeof(T2), typeof(T3), typeof(T4));
}
/// <summary>
@ -140,6 +123,54 @@ namespace Gallium
return this.Components.ContainsKey(type);
}
/// <summary>
/// Gets a value indicating whether the entity has components for all the given
/// types.
/// </summary>
/// <param name="t1">The component type.</param>
/// <param name="t2">The component type.</param>
/// <returns>True if the type exists, otherwise false.</returns>
public bool HasAll(
Type t1,
Type t2)
{
return this.Has(t1) && this.Components.ContainsKey(t2);
}
/// <summary>
/// Gets a value indicating whether the entity has components for all the given
/// types.
/// </summary>
/// <param name="t1">The component type.</param>
/// <param name="t2">The component type.</param>
/// <param name="t3">The component type.</param>
/// <returns>True if the type exists, otherwise false.</returns>
public bool HasAll(
Type t1,
Type t2,
Type t3)
{
return this.HasAll(t1, t2) && this.Components.ContainsKey(t3);
}
/// <summary>
/// Gets a value indicating whether the entity has components for all the given
/// types.
/// </summary>
/// <param name="t1">The component type.</param>
/// <param name="t2">The component type.</param>
/// <param name="t3">The component type.</param>
/// <param name="t4">The component type.</param>
/// <returns>True if the type exists, otherwise false.</returns>
public bool HasAll(
Type t1,
Type t2,
Type t3,
Type t4)
{
return this.HasAll(t1, t2, t3) && this.Components.ContainsKey(t4);
}
/// <summary>
/// Retrieves a registered component of the given type.
/// </summary>
@ -191,10 +222,12 @@ namespace Gallium
if (this.Has<T1>())
{
value = this.Get<T1>();
return true;
}
value = default!;
return false;
}
@ -208,17 +241,21 @@ namespace Gallium
/// <typeparam name="T1">The first component type.</typeparam>
/// <typeparam name="T2">The second component type.</typeparam>
/// <returns>True if found, otherwise false.</returns>
public bool TryGet<T1, T2>(out T1 value1, out T2 value2)
public bool TryGet<T1, T2>(
out T1 value1,
out T2 value2)
{
if (this.HasAll<T1, T2>())
{
value1 = this.Get<T1>();
value2 = this.Get<T2>();
return true;
}
value1 = default!;
value2 = default!;
return false;
}
@ -229,6 +266,7 @@ namespace Gallium
/// </summary>
/// <param name="value1">The value if contained in the entity.</param>
/// <param name="value2">The value if contained in the entity.</param>
/// <param name="value3">The value if contained in the entity.</param>
/// <typeparam name="T1">The first component type.</typeparam>
/// <typeparam name="T2">The second component type.</typeparam>
/// <typeparam name="T3">The third component type.</typeparam>
@ -243,12 +281,14 @@ namespace Gallium
value1 = this.Get<T1>();
value2 = this.Get<T2>();
value3 = this.Get<T3>();
return true;
}
value1 = default!;
value2 = default!;
value3 = default!;
return false;
}
@ -259,6 +299,8 @@ namespace Gallium
/// </summary>
/// <param name="value1">The value if contained in the entity.</param>
/// <param name="value2">The value if contained in the entity.</param>
/// <param name="value3">The value if contained in the entity.</param>
/// <param name="value4">The value if contained in the entity.</param>
/// <typeparam name="T1">The first component type.</typeparam>
/// <typeparam name="T2">The second component type.</typeparam>
/// <typeparam name="T3">The third component type.</typeparam>
@ -276,6 +318,7 @@ namespace Gallium
value2 = this.Get<T2>();
value3 = this.Get<T3>();
value4 = this.Get<T4>();
return true;
}
@ -283,6 +326,7 @@ namespace Gallium
value2 = default!;
value3 = default!;
value4 = default!;
return false;
}
@ -291,18 +335,18 @@ namespace Gallium
/// component already registered.
/// </summary>
/// <param name="component">The component to register.</param>
/// <typeparam name="TType">The component type.</typeparam>
/// <typeparam name="T1">The component type.</typeparam>
/// <returns>The entity for chaining.</returns>
/// <exception cref="ArgumentNullException"></exception>
public Entity Set<TType>(TType component)
public Entity Set<T1>(T1 component)
{
if (component == null)
{
throw new ArgumentNullException(nameof(component));
}
if (this.Components.TryGetValue(typeof(TType), out object? value)
&& value is TType
if (this.Components.TryGetValue(typeof(T1), out object? value)
&& value is T1
&& value.Equals(component))
{
return this;
@ -310,7 +354,7 @@ namespace Gallium
return this with
{
Components = this.Components.SetItem(typeof(TType), component),
Components = this.Components.SetItem(typeof(T1), component),
};
}
@ -318,30 +362,30 @@ namespace Gallium
/// Adds a component to the entity.
/// </summary>
/// <param name="component">The component to register.</param>
/// <typeparam name="TType">The component type.</typeparam>
/// <typeparam name="T1">The component type.</typeparam>
/// <returns>
/// The same entity if the component is already registered, otherwise a
/// cloned entity with the new component.
/// </returns>
/// <exception cref="ArgumentNullException"></exception>
public Entity Add<TType>(TType component)
public Entity Add<T1>(T1 component)
{
if (component == null)
{
throw new ArgumentNullException(nameof(component));
}
if (this.Has<TType>())
if (this.Has<T1>())
{
throw new ArgumentException(
"An element with the same type ("
+ typeof(TType).FullName
+ typeof(T1).FullName
+ ") already exists.",
nameof(component));
}
if (this.Components.TryGetValue(typeof(TType), out object? value)
&& value is TType
if (this.Components.TryGetValue(typeof(T1), out object? value)
&& value is T1
&& value.Equals(component))
{
return this;
@ -349,7 +393,7 @@ namespace Gallium
return this with
{
Components = this.Components.Add(typeof(TType), component),
Components = this.Components.Add(typeof(T1), component),
};
}
@ -392,7 +436,7 @@ namespace Gallium
/// Gets the identifier of the entity. This should be treated as an
/// opaque field.
/// </summary>
public int Id { get; private set; }
public int Id { get; private init; }
/// <summary>
/// Creates a copy of the entity, including copying the identifier.

View file

@ -4,7 +4,7 @@ using System.Linq;
namespace Gallium
{
public static class MergeEnumerableEntityExtensions
public static class JoinEntityExtensions
{
/// <summary>
/// Merges two sets of entities using the identifier to determine which
@ -18,21 +18,12 @@ namespace Gallium
/// <param name="other">The collection of entities to merge from.</param>
/// <param name="merge">The callback to merge the two.</param>
/// <returns>An sequence of entities, merged and unmerged.</returns>
public static IEnumerable<Entity> MergeEntities(
public static IEnumerable<Entity> JoinEntity(
this IEnumerable<Entity> input,
ICollection<Entity> other,
Func<Entity, Entity, Entity> merge)
{
return input
.Select(
entity =>
{
Entity? found = other.FirstOrDefault(y => y == entity);
return found == null
? entity
: merge(entity, found);
});
return input.Join(other, a => a.Id, a => a.Id, merge);
}
}
}

View file

@ -0,0 +1,153 @@
using System;
using System.Collections.Generic;
using System.Linq;
namespace Gallium;
/// <summary>
/// An extension method that handle SelectManyEntity which extracts all the
/// entities that match the given components,
/// passes the results to a select many callback, and then optionally includes the
/// ones that didn't have the components
/// before return.
/// </summary>
public static class SelectManyEntityExtensions
{
/// <summary>
/// Pulls out all the entities that match the given components into an enumeration,
/// passes it into the callback
/// function, and then optionally merges the entities that did not match before
/// returning.
/// </summary>
/// <param name="entities">The entities to process</param>
/// <param name="selectMany">
/// The callback function to manipulate the list of
/// entities.
/// </param>
/// <param name="includeEntitiesWithoutComponents">
/// If true, the include entities
/// without components.
/// </param>
/// <typeparam name="T1">The type of the first component.</typeparam>
/// <returns>An enumeration of entities.</returns>
public static IEnumerable<Entity> SelectManyEntity<T1>(
this IEnumerable<Entity> entities,
Func<IEnumerable<Entity>, IEnumerable<Entity>> selectMany,
bool includeEntitiesWithoutComponents = true)
{
SplitEntityEnumerations split = entities.SplitEntity<T1>();
IEnumerable<Entity> results = selectMany(split.HasAll);
if (includeEntitiesWithoutComponents)
{
results = results.Union(split.NotHasAll);
}
return results;
}
/// <summary>
/// Pulls out all the entities that match the given components into an enumeration,
/// passes it into the callback
/// function, and then optionally merges the entities that did not match before
/// returning.
/// </summary>
/// <param name="entities">The entities to process</param>
/// <param name="selectMany">
/// The callback function to manipulate the list of
/// entities.
/// </param>
/// <param name="includeEntitiesWithoutComponents">
/// If true, the include entities
/// without components.
/// </param>
/// <typeparam name="T1">The type of the first component.</typeparam>
/// <typeparam name="T2">The type of the second component.</typeparam>
/// <returns>An enumeration of entities.</returns>
public static IEnumerable<Entity> SelectManyEntity<T1, T2>(
this IEnumerable<Entity> entities,
Func<IEnumerable<Entity>, IEnumerable<Entity>> selectMany,
bool includeEntitiesWithoutComponents = true)
{
SplitEntityEnumerations split = entities.SplitEntity<T1, T2>();
IEnumerable<Entity> results = selectMany(split.HasAll);
if (includeEntitiesWithoutComponents)
{
results = results.Union(split.NotHasAll);
}
return results;
}
/// <summary>
/// Pulls out all the entities that match the given components into an enumeration,
/// passes it into the callback
/// function, and then optionally merges the entities that did not match before
/// returning.
/// </summary>
/// <param name="entities">The entities to process</param>
/// <param name="selectMany">
/// The callback function to manipulate the list of
/// entities.
/// </param>
/// <param name="includeEntitiesWithoutComponents">
/// If true, the include entities
/// without components.
/// </param>
/// <typeparam name="T1">The type of the first component.</typeparam>
/// <typeparam name="T2">The type of the second component.</typeparam>
/// <typeparam name="T3">The type of the second component.</typeparam>
/// <returns>An enumeration of entities.</returns>
public static IEnumerable<Entity> SelectManyEntity<T1, T2, T3>(
this IEnumerable<Entity> entities,
Func<IEnumerable<Entity>, IEnumerable<Entity>> selectMany,
bool includeEntitiesWithoutComponents = true)
{
SplitEntityEnumerations split = entities.SplitEntity<T1, T2, T3>();
IEnumerable<Entity> results = selectMany(split.HasAll);
if (includeEntitiesWithoutComponents)
{
results = results.Union(split.NotHasAll);
}
return results;
}
/// <summary>
/// Pulls out all the entities that match the given components into an enumeration,
/// passes it into the callback
/// function, and then optionally merges the entities that did not match before
/// returning.
/// </summary>
/// <param name="entities">The entities to process</param>
/// <param name="selectMany">
/// The callback function to manipulate the list of
/// entities.
/// </param>
/// <param name="includeEntitiesWithoutComponents">
/// If true, the include entities
/// without components.
/// </param>
/// <typeparam name="T1">The type of the first component.</typeparam>
/// <typeparam name="T2">The type of the second component.</typeparam>
/// <typeparam name="T3">The type of the second component.</typeparam>
/// <typeparam name="T4">The type of the second component.</typeparam>
/// <returns>An enumeration of entities.</returns>
public static IEnumerable<Entity> SelectManyEntity<T1, T2, T3, T4>(
this IEnumerable<Entity> entities,
Func<IEnumerable<Entity>, IEnumerable<Entity>> selectMany,
bool includeEntitiesWithoutComponents = true)
{
SplitEntityEnumerations split = entities.SplitEntity<T1, T2, T3, T4>();
IEnumerable<Entity> results = selectMany(split.HasAll);
if (includeEntitiesWithoutComponents)
{
results = results.Union(split.NotHasAll);
}
return results;
}
}

View file

@ -0,0 +1,18 @@
using System.Collections.Generic;
namespace Gallium;
public record SplitEntityEnumerations(
IEnumerable<Entity> HasAll,
IEnumerable<Entity> NotHasAll)
{
/// <summary>
/// Gets a sequence of all entities that have all the given components.
/// </summary>
public IEnumerable<Entity> HasAll { get; } = HasAll;
/// <summary>
/// Gets the sequence of all entities that do not have all the given components.
/// </summary>
public IEnumerable<Entity> NotHasAll { get; } = NotHasAll;
}

View file

@ -0,0 +1,298 @@
using System;
using System.Collections.Generic;
using System.Linq;
namespace Gallium;
/// <summary>
/// Extension methods for IEnumerable&lt;Entity&gt; that split the entity into two
/// sequences, one that contains the
/// various components and the other list which does not.
/// </summary>
public static class SplitEntityExtensions
{
/// <summary>
/// Splits the enumeration of entities into two separate enumerations, ones that
/// have the given generic components
/// and those which do not.
/// </summary>
/// <param name="entities">The entities to split into two lists.</param>
/// <param name="test">
/// An additional test function to determine if the entity is
/// included in the has list. If null, then entities with all the components will
/// be included.
/// </param>
/// <typeparam name="T1">
/// A component to require to be in included in the first
/// list.
/// </typeparam>
/// <returns>A pair of enumerations, ones with the components and ones without.</returns>
public static SplitEntityEnumerations SplitEntity
<T1>(
this IEnumerable<Entity> entities,
Func<Entity, T1, bool>? test = null)
{
test ??= (
e,
v1) => true;
return entities.SplitEntity(
typeof(T1),
(
e,
v1) => test(e, (T1)v1));
}
/// <summary>
/// Splits the enumeration of entities into two separate enumerations, ones that
/// have the given generic components
/// and those which do not.
/// </summary>
/// <param name="entities">The entities to split into two lists.</param>
/// <param name="test">
/// An additional test function to determine if the entity is
/// included in the has list. If null, then entities with all the components will
/// be included.
/// </param>
/// <typeparam name="T1">
/// A component to require to be in included in the first list.
/// </typeparam>
/// <typeparam name="T2">
/// A component to require to be in included in the first list.
/// </typeparam>
/// <returns>A pair of enumerations, ones with the components and ones without.</returns>
public static SplitEntityEnumerations SplitEntity
<T1, T2>(
this IEnumerable<Entity> entities,
Func<Entity, T1, T2, bool>? test = null)
{
test ??= (
e,
v1,
v2) => true;
return entities.SplitEntity(
typeof(T1),
typeof(T2),
(
e,
v1,
v2) => test(e, (T1)v1, (T2)v2));
}
/// <summary>
/// Splits the enumeration of entities into two separate enumerations, ones that
/// have the given generic components
/// and those which do not.
/// </summary>
/// <param name="entities">The entities to split into two lists.</param>
/// <param name="test">
/// An additional test function to determine if the entity is
/// included in the has list. If null, then entities with all the components will
/// be included.
/// </param>
/// <typeparam name="T1">
/// A component to require to be in included in the first list.
/// </typeparam>
/// <typeparam name="T2">
/// A component to require to be in included in the first list.
/// </typeparam>
/// <typeparam name="T3">
/// A component to require to be in included in the first list.
/// </typeparam>
/// <returns>A pair of enumerations, ones with the components and ones without.</returns>
public static SplitEntityEnumerations SplitEntity
<T1, T2, T3>(
this IEnumerable<Entity> entities,
Func<Entity, T1, T2, T3, bool>? test = null)
{
test ??= (
e,
v1,
v2,
v3) => true;
return entities.SplitEntity(
typeof(T1),
typeof(T2),
typeof(T3),
(
e,
v1,
v2,
v3) => test(e, (T1)v1, (T2)v2, (T3)v3));
}
/// <summary>
/// Splits the enumeration of entities into two separate enumerations, ones that
/// have the given generic components
/// and those which do not.
/// </summary>
/// <param name="entities">The entities to split into two lists.</param>
/// <param name="test">
/// An additional test function to determine if the entity is
/// included in the has list. If null, then entities with all the components will
/// be included.
/// </param>
/// <typeparam name="T1">
/// A component to require to be in included in the first list.
/// </typeparam>
/// <typeparam name="T2">
/// A component to require to be in included in the first list.
/// </typeparam>
/// <typeparam name="T3">
/// A component to require to be in included in the first list.
/// </typeparam>
/// <typeparam name="T4">
/// A component to require to be in included in the first list.
/// </typeparam>
/// <returns>A pair of enumerations, ones with the components and ones without.</returns>
public static SplitEntityEnumerations SplitEntity
<T1, T2, T3, T4>(
this IEnumerable<Entity> entities,
Func<Entity, T1, T2, T3, T4, bool>? test = null)
{
test ??= (
e,
v1,
v2,
v3,
v4) => true;
return entities.SplitEntity(
typeof(T1),
typeof(T2),
typeof(T3),
typeof(T4),
(
e,
v1,
v2,
v3,
v4) => test(e, (T1)v1, (T2)v2, (T3)v3, (T4)v4));
}
/// <summary>
/// Splits the enumeration of entities into two separate enumerations, ones that
/// have the given component types and those which do not.
/// </summary>
/// <param name="entities">The entities to split into two lists.</param>
/// <param name="t1">The type of a required component.</param>
/// <param name="test">
/// An additional test function to determine if the entity is
/// included in the has list. If null, then entities with all the components will
/// be included.
/// </param>
/// <returns>A pair of enumerations, ones with the components and ones without.</returns>
public static SplitEntityEnumerations SplitEntity(
this IEnumerable<Entity> entities,
Type t1,
Func<Entity, object, bool> test)
{
return SplitEntity(entities, a => a.Has(t1) && test(a, a.Get<object>(t1)));
}
/// <summary>
/// Splits the enumeration of entities into two separate enumerations, ones that
/// have the given component types and those which do not.
/// </summary>
/// <param name="entities">The entities to split into two lists.</param>
/// <param name="t1">The type of a required component.</param>
/// <param name="t2">The type of a required component.</param>
/// <param name="test">
/// An additional test function to determine if the entity is
/// included in the has list. If null, then entities with all the components will
/// be included.
/// </param>
/// <returns>A pair of enumerations, ones with the components and ones without.</returns>
public static SplitEntityEnumerations SplitEntity(
this IEnumerable<Entity> entities,
Type t1,
Type t2,
Func<Entity, object, object, bool> test)
{
return SplitEntity(entities, a => a.HasAll(t1, t2));
}
/// <summary>
/// Splits the enumeration of entities into two separate enumerations, ones that
/// have the given component types and those which do not.
/// </summary>
/// <param name="entities">The entities to split into two lists.</param>
/// <param name="t1">The type of a required component.</param>
/// <param name="t2">The type of a required component.</param>
/// <param name="t3">The type of a required component.</param>
/// <param name="test">
/// An additional test function to determine if the entity is
/// included in the has list. If null, then entities with all the components will
/// be included.
/// </param>
/// <returns>A pair of enumerations, ones with the components and ones without.</returns>
public static SplitEntityEnumerations SplitEntity(
this IEnumerable<Entity> entities,
Type t1,
Type t2,
Type t3,
Func<Entity, object, object, object, bool> test)
{
return SplitEntity(entities, a => a.HasAll(t1, t2, t3));
}
/// <summary>
/// Splits the enumeration of entities into two separate enumerations, ones that
/// have the given component types and those which do not.
/// </summary>
/// <param name="entities">The entities to split into two lists.</param>
/// <param name="t1">The type of a required component.</param>
/// <param name="t2">The type of a required component.</param>
/// <param name="t3">The type of a required component.</param>
/// <param name="t4">The type of a required component.</param>
/// <param name="test">
/// An additional test function to determine if the entity is
/// included in the has list. If null, then entities with all the components will
/// be included.
/// </param>
/// <returns>A pair of enumerations, ones with the components and ones without.</returns>
public static SplitEntityEnumerations SplitEntity(
this IEnumerable<Entity> entities,
Type t1,
Type t2,
Type t3,
Type t4,
Func<Entity, object, object, object, object, bool> test)
{
return SplitEntity(
entities,
a => a.HasAll(t1, t2, t3, t4)
&& test(
a,
a.Get<object>(t1),
a.Get<object>(t2),
a.Get<object>(t3),
a.Get<object>(t4)));
}
private static SplitEntityEnumerations SplitEntity(
IEnumerable<Entity> entities,
Func<Entity, bool> keySelector)
{
if (entities == null)
{
throw new ArgumentNullException(nameof(entities));
}
IEnumerable<IGrouping<bool, Entity>> group = entities
.GroupBy(keySelector, a => a)
.ToList();
IEnumerable<Entity>? has = group
.Where(a => a.Key)
.SelectMany(a => a);
IEnumerable<Entity>? hasNot = group
.Where(a => !a.Key)
.SelectMany(a => a);
return new SplitEntityEnumerations(has, hasNot);
}
}

View file

@ -1,34 +0,0 @@
using System.Collections.Generic;
using System.Linq;
namespace Gallium
{
public static class WhereAllComponentsExtensions
{
public static IEnumerable<Entity> WhereAllComponents<T1>(
this IEnumerable<Entity> entities)
{
return entities.Where(x => x.Has<T1>());
}
public static IEnumerable<Entity> WhereAllComponents<T1, T2>(
this IEnumerable<Entity> entities)
{
return entities.Where(x => x.Has<T1>() && x.Has<T2>());
}
public static IEnumerable<Entity> WhereAllComponents<T1, T2, T3>(
this IEnumerable<Entity> entities)
{
return entities.Where(
x => x.Has<T1>() && x.Has<T2>() && x.Has<T3>());
}
public static IEnumerable<Entity> WhereAllComponents<T1, T2, T3, T4>(
this IEnumerable<Entity> entities)
{
return entities.Where(
x => x.Has<T1>() && x.Has<T2>() && x.Has<T3>() && x.Has<T4>());
}
}
}

View file

@ -4,45 +4,39 @@ using System.Linq;
namespace Gallium
{
public static class WhereComponentsExtensions
public static class WhereEntityExtensions
{
public static IEnumerable<Entity> WhereComponents<T1>(
public static IEnumerable<Entity> WhereEntity<T1>(
this IEnumerable<Entity> entities,
Func<Entity, T1, bool> include)
{
return entities.Where(x => x.Has<T1>() && include(x, x.Get<T1>()));
}
public static IEnumerable<Entity> WhereComponents<T1, T2>(
public static IEnumerable<Entity> WhereEntity<T1, T2>(
this IEnumerable<Entity> entities,
Func<Entity, T1, T2, bool> include)
{
return entities.Where(
x => x.Has<T1>()
&& x.Has<T2>()
x => x.HasAll<T1, T2>()
&& include(x, x.Get<T1>(), x.Get<T2>()));
}
public static IEnumerable<Entity> WhereComponents<T1, T2, T3>(
public static IEnumerable<Entity> WhereEntity<T1, T2, T3>(
this IEnumerable<Entity> entities,
Func<Entity, T1, T2, T3, bool> include)
{
return entities.Where(
x => x.Has<T1>()
&& x.Has<T2>()
&& x.Has<T3>()
x => x.HasAll<T1, T2, T3>()
&& include(x, x.Get<T1>(), x.Get<T2>(), x.Get<T3>()));
}
public static IEnumerable<Entity> WhereComponents<T1, T2, T3, T4>(
public static IEnumerable<Entity> WhereEntity<T1, T2, T3, T4>(
this IEnumerable<Entity> entities,
Func<Entity, T1, T2, T3, T4, bool> include)
{
return entities.Where(
x => x.Has<T1>()
&& x.Has<T2>()
&& x.Has<T3>()
&& x.Has<T4>()
x => x.HasAll<T1, T2, T3, T4>()
&& include(
x,
x.Get<T1>(),

View file

@ -0,0 +1,32 @@
using System.Collections.Generic;
using System.Linq;
namespace Gallium
{
public static class WhereEntityHasExtensions
{
public static IEnumerable<Entity> WhereEntityHas<T1>(
this IEnumerable<Entity> entities)
{
return entities.Where(x => x.Has<T1>());
}
public static IEnumerable<Entity> WhereEntityHasAll<T1, T2>(
this IEnumerable<Entity> entities)
{
return entities.Where(x => x.HasAll<T1, T2>());
}
public static IEnumerable<Entity> WhereEntityHasAll<T1, T2, T3>(
this IEnumerable<Entity> entities)
{
return entities.Where(x => x.HasAll<T1, T2, T3>());
}
public static IEnumerable<Entity> WhereEntityHasAll<T1, T2, T3, T4>(
this IEnumerable<Entity> entities)
{
return entities.Where(x => x.HasAll<T1, T2, T3, T4>());
}
}
}

View file

@ -0,0 +1,28 @@
using System.Collections.Generic;
using System.Linq;
namespace Gallium
{
public static class WhereEntityNotHasExtensions
{
public static IEnumerable<Entity> WhereEntityNotHas<T1>(this IEnumerable<Entity> entities)
{
return entities.Where(x => !x.Has<T1>());
}
public static IEnumerable<Entity> WhereEntityNotHasAll<T1, T2>(this IEnumerable<Entity> entities)
{
return entities.Where(x => !x.HasAll<T1, T2>());
}
public static IEnumerable<Entity> WhereEntityNotHasAll<T1, T2, T3>(this IEnumerable<Entity> entities)
{
return entities.Where(x => !x.HasAll<T1, T2, T3>());
}
public static IEnumerable<Entity> WhereEntityNotHasAll<T1, T2, T3, T4>(this IEnumerable<Entity> entities)
{
return entities.Where(x => !x.HasAll<T1, T2, T3, T4>());
}
}
}

View file

@ -1,44 +0,0 @@
using System.Collections.Generic;
using System.Linq;
namespace Gallium
{
public static class WhereNotAllComponentExtensions
{
public static IEnumerable<Entity> WhereNotComponent<T1>(
this IEnumerable<Entity> entities)
{
return entities.Where(x => !x.Has<T1>());
}
public static IEnumerable<Entity> WhereNotAllComponents<T1>(
this IEnumerable<Entity> entities)
{
return entities.Where(x => !x.Has<T1>());
}
public static IEnumerable<Entity> WhereNotAllComponents<T1, T2>(
this IEnumerable<Entity> entities)
{
return entities.Where(x => !x.HasAll<T1, T2>());
}
public static IEnumerable<Entity> WhereNotAllComponents<T1, T2, T3>(
this IEnumerable<Entity> entities)
{
return entities.Where(
x => !x.HasAll<T1, T2, T3>());
}
public static IEnumerable<Entity> WhereNotAllComponents<T1, T2, T3, T4>(
this IEnumerable<Entity> entities)
{
return entities.Where(
x => !x.Has<T1>()
|| !x.Has<T2>()
|| !x.Has<T3>()
|| !x.Has<T4>());
}
}
}

View file

@ -73,7 +73,7 @@ namespace Gallium.Tests
Assert.Equal(
new[] { "1", "3" },
entities.WhereAllComponents<TestComponent1>().Select(x => x.Get<string>()).ToArray());
entities.WhereEntityHas<TestComponent1>().Select(x => x.Get<string>()).ToArray());
}
[Fact]
@ -88,7 +88,7 @@ namespace Gallium.Tests
Assert.Equal(
new[] { "2" },
entities.WhereAllComponents<TestComponent1, TestComponent2>().Select(x => x.Get<string>()).ToArray());
entities.WhereEntityHasAll<TestComponent1, TestComponent2>().Select(x => x.Get<string>()).ToArray());
}
[Fact]
@ -106,7 +106,7 @@ namespace Gallium.Tests
Assert.Equal(
new[] { "1" },
entities.WhereAllComponents<TestComponent1, TestComponent2, ITestComponent3>()
entities.WhereEntityHasAll<TestComponent1, TestComponent2, ITestComponent3>()
.Select(x => x.Get<string>())
.ToArray());
}
@ -123,7 +123,7 @@ namespace Gallium.Tests
Assert.Equal(
new[] { "2" },
entities.WhereNotComponent<TestComponent1>().Select(x => x.Get<string>()).ToArray());
entities.WhereEntityNotHas<TestComponent1>().Select(x => x.Get<string>()).ToArray());
}
[Fact]
@ -138,7 +138,7 @@ namespace Gallium.Tests
Assert.Equal(
new[] { "1", "3" },
entities.WhereNotAllComponents<TestComponent1, TestComponent2>()
entities.WhereEntityNotHasAll<TestComponent1, TestComponent2>()
.Select(x => x.Get<string>())
.ToArray());
}
@ -158,7 +158,7 @@ namespace Gallium.Tests
Assert.Equal(
new string[] { "1", "3" },
entities.WhereNotAllComponents<TestComponent1, TestComponent2, ITestComponent3>()
entities.WhereEntityNotHasAll<TestComponent1, TestComponent2, ITestComponent3>()
.Select(x => x.Get<string>())
.ToArray());
}