diff --git a/Convention-CSharp.csproj b/Convention-CSharp.csproj
index cdc5c57..1bb1198 100644
--- a/Convention-CSharp.csproj
+++ b/Convention-CSharp.csproj
@@ -5,8 +5,6 @@
Exe
net8.0
Convention
- enable
- enable
diff --git a/Convention/Runtime/Architecture.cs b/Convention/Runtime/Architecture.cs
index 5daa48f..18369af 100644
--- a/Convention/Runtime/Architecture.cs
+++ b/Convention/Runtime/Architecture.cs
@@ -3,33 +3,40 @@ using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
-using System.Text;
-using System.Threading.Tasks;
-using static System.Runtime.InteropServices.JavaScript.JSType;
+using Microsoft.VisualBasic;
namespace Convention
{
// Interface
+ public interface ISignal
+ {
+
+ }
+
public interface IModel
{
string Save();
void Load(string data);
}
- public interface IConvertModel
- : IModel
+ public interface IConvertable
{
T ConvertTo();
}
+ public interface IConvertModel
+ : IModel, IConvertable
+ {
+ }
+
// Instance
public class SingletonModel: IModel
{
- private static T? InjectInstance = default;
+ private static T InjectInstance = default;
- public static T? Instance
+ public static T Instance
{
get => InjectInstance;
set
@@ -43,7 +50,7 @@ namespace Convention
}
}
- public T? Data => InjectInstance;
+ public T Data => InjectInstance;
void IModel.Load(string data)
{
@@ -63,7 +70,7 @@ namespace Convention
throw new InvalidOperationException();
}
- public static implicit operator T?(SingletonModel _) => InjectInstance;
+ public static implicit operator T(SingletonModel _) => InjectInstance;
}
public class DependenceModel
@@ -118,10 +125,10 @@ namespace Convention
return type.Assembly + "::" + type.FullName;
}
- public static Type? LoadFromFormat(string data)
+ public static Type LoadFromFormat(string data)
{
var keys = data.Split("::");
- Assembly? asm = null;
+ Assembly asm = null;
try
{
asm = Assembly.LoadFrom(keys[0]);
@@ -133,11 +140,11 @@ namespace Convention
}
}
- public static Type? LoadFromFormat(string data, out Exception? exception)
+ public static Type LoadFromFormat(string data, out Exception exception)
{
exception = null;
var keys = data.Split("::");
- Assembly? asm = null;
+ Assembly asm = null;
try
{
asm = Assembly.LoadFrom(keys[0]);
@@ -150,6 +157,23 @@ namespace Convention
}
}
+ internal static void InternalReset()
+ {
+ // Register System
+ RegisterHistory.Clear();
+ UncompleteTargets.Clear();
+ Completer.Clear();
+ Dependences.Clear();
+ Childs.Clear();
+ // Event Listener
+ SignalListener.Clear();
+ // Linear Chain for Dependence
+ TimelineQuenes.Clear();
+ TimelineContentID = 0;
+ }
+
+ #region Objects Registered
+
private class TypeQuery
: IConvertModel
{
@@ -176,11 +200,11 @@ namespace Convention
}
}
- private static HashSet RegisterHistory = new();
- private static Dictionary UncompleteTargets = new();
- private static Dictionary Completer = new();
- private static Dictionary Dependences = new();
- private static Dictionary Childs = new();
+ private static readonly HashSet RegisterHistory = new();
+ private static readonly Dictionary UncompleteTargets = new();
+ private static readonly Dictionary Completer = new();
+ private static readonly Dictionary Dependences = new();
+ private static readonly Dictionary Childs = new();
public class Registering : IConvertModel
{
@@ -207,7 +231,7 @@ namespace Convention
}
}
- private static bool InternalComplete(out HashSet InternalUpdateBuffer)
+ private static bool InternalRegisteringComplete(out HashSet InternalUpdateBuffer)
{
InternalUpdateBuffer = new();
bool result = false;
@@ -222,19 +246,22 @@ namespace Convention
return result;
}
- private static void InternalUpdate(HashSet InternalUpdateBuffer)
+ private static void InternalRegisteringUpdate(HashSet InternalUpdateBuffer)
{
foreach (var complete in InternalUpdateBuffer)
{
Dependences.Remove(complete);
-
+ }
+ foreach (var complete in InternalUpdateBuffer)
+ {
+ Completer[complete]();
+ Completer.Remove(complete);
}
foreach (var complete in InternalUpdateBuffer)
{
Childs.Add(complete, UncompleteTargets[complete]);
UncompleteTargets.Remove(complete);
}
- InternalUpdateBuffer.Clear();
}
public static Registering Register(Type slot, object target, Action completer, params Type[] dependences)
@@ -245,9 +272,9 @@ namespace Convention
}
Completer[slot] = completer;
UncompleteTargets[slot] = target;
- Dependences[slot] = new DependenceModel(from dependence in dependences select new TypeQuery(dependence));
- while (InternalComplete(out var buffer))
- InternalUpdate(buffer);
+ Dependences[slot] = new DependenceModel(from dependence in dependences where dependence != slot select new TypeQuery(dependence));
+ while (InternalRegisteringComplete(out var buffer))
+ InternalRegisteringUpdate(buffer);
return new Registering(slot);
}
@@ -262,5 +289,124 @@ namespace Convention
public static object Get(Type type) => InternalGet(type);
public static T Get() => (T)Get(typeof(T));
+
+ #endregion
+
+ #region Signal & Update
+
+ private static readonly Dictionary>> SignalListener = new();
+
+ public class Listening
+ {
+ private readonly Action action;
+ private readonly Type type;
+
+ public Listening(Action action, Type type)
+ {
+ this.action = action;
+ this.type = type;
+ }
+
+ public void StopListening()
+ {
+ if (SignalListener.TryGetValue(type, out var actions))
+ actions.Remove(action);
+ }
+ }
+
+ public static Listening AddListener(Type slot, Action listener) where Signal : ISignal
+ {
+ if (SignalListener.ContainsKey(slot) == false)
+ SignalListener.Add(slot, new());
+ Action action = x =>
+ {
+ if (x is Signal signal)
+ listener(signal);
+ };
+ Listening result = new(action, slot);
+ SignalListener[slot].Add(action);
+ return result;
+ }
+
+ public static void SendMessage(Type slot, ISignal signal)
+ {
+ if(SignalListener.TryGetValue(slot,out var actions))
+ {
+ foreach (var action in actions)
+ {
+ action(signal);
+ }
+ }
+ }
+
+ public static void SendMessage(Signal signal) where Signal : ISignal => SendMessage(signal.GetType(), signal);
+
+ #endregion
+
+ #region Timeline/Chain & Update
+
+ private class TimelineQueneEntry
+ {
+ public Func predicate;
+ public List actions = new();
+ }
+
+ private class Timeline
+ {
+ public Dictionary, int> PredicateMapper = new();
+ public List Quene = new();
+ public int Context = 0;
+ }
+
+ private static Dictionary TimelineQuenes = new();
+ private static int TimelineContentID = 0;
+
+ public static int CreateTimeline()
+ {
+ TimelineQuenes.Add(TimelineContentID++, new());
+ return TimelineQuenes.Count;
+ }
+
+ public static void AddStep(int timelineId, Func predicate,params Action[] actions)
+ {
+ var timeline = TimelineQuenes[timelineId];
+ if (timeline.PredicateMapper.TryGetValue(predicate, out var time))
+ {
+ timeline.Quene[time].actions.AddRange(actions);
+ }
+ else
+ {
+ time = timeline.Quene.Count;
+ timeline.PredicateMapper.Add(predicate, time);
+ timeline.Quene.Add(new()
+ {
+ predicate = predicate,
+ actions = actions.ToList()
+ });
+ }
+ }
+
+ public static void UpdateTimeline()
+ {
+ foreach (var pair in TimelineQuenes)
+ {
+ var timeline = pair.Value;
+ if(timeline.Quene[timeline.Context].predicate())
+ {
+ foreach (var action in timeline.Quene[timeline.Context].actions)
+ {
+ action();
+ }
+ timeline.Context++;
+ }
+ }
+ }
+
+ public static void ResetTimelineContext(int timelineId)
+ {
+ TimelineQuenes[timelineId].Context = 0;
+ }
+
+ #endregion
}
}
diff --git a/Convention/Runtime/Config.cs b/Convention/Runtime/Config.cs
index abd0192..a0cd628 100644
--- a/Convention/Runtime/Config.cs
+++ b/Convention/Runtime/Config.cs
@@ -6,5 +6,59 @@ using System.Threading.Tasks;
namespace Convention
{
+ namespace NTree
+ {
+ public class NTreeNode
+ {
+ public NTreeNode Parent;
+ public NTreeNode Child;
+ public NTreeNode Right;
+ public T Data;
+ public int BranchSize()
+ {
+ if (Parent == null)
+ return -1;
+ var left = Parent.Child;
+ int result = 0;
+ while (left != null)
+ result++;
+ return result;
+ }
+
+ public int BranchLeftCount()
+ {
+ if (Parent == null)
+ return -1;
+ var left = Parent.Child;
+ int result = 0;
+ while (left != this)
+ result++;
+ return result;
+ }
+
+ public int BranchRightSize()
+ {
+ var left = this;
+ int result = 0;
+ while (left != null)
+ result++;
+ return result;
+ }
+ }
+
+ public class NTree
+ {
+ internal NTreeNode Root;
+
+ public bool IsEmpty() => Root == null;
+
+ public NTreeNode UpdateRoot(NTreeNode node)
+ {
+ var oldRoot = Root;
+ Root = node;
+ return oldRoot;
+ }
+ }
+ }
}
diff --git a/[Test]/Program.cs b/[Test]/Program.cs
index 3849a54..cd10e48 100644
--- a/[Test]/Program.cs
+++ b/[Test]/Program.cs
@@ -1,9 +1,48 @@
-using Convention;
+using System;
+using System.Collections.Generic;
+using System.Threading;
+using Convention;
public class Program
{
+ class Slot1
+ {
+
+ }
+ class Slot2
+ {
+
+ }
+ class Slot3
+ {
+
+ }
+ class Slot4
+ {
+
+ }
+
static void Main(string[] args)
{
- Console.WriteLine("Hello, World!");
+ var seed = new Random(2049);
+ for (int i = 0; i < 100000; i++)
+ {
+ Convention.Architecture.InternalReset();
+ var slot1 = new Slot1();
+ var slot2 = new Slot2();
+ var slot3 = new Slot3();
+ var slot4 = new Slot4();
+ List list = new() {
+ ()=> Convention.Architecture.Register(slot1,()=>{ },typeof(Slot2),typeof(Slot3),typeof(Slot4)),
+ ()=> Convention.Architecture.Register(slot2,()=>{ },typeof(Slot3),typeof(Slot4)),
+ ()=> Convention.Architecture.Register(slot3,()=>{ },typeof(Slot4)),
+ ()=> Convention.Architecture.Register(slot4,()=>{ })};
+ list.Sort((x, y) => seed.Next() > seed.Next() ? 1 : -1);
+ foreach (var item in list)
+ {
+ item();
+ }
+ Console.Write($"{i}\t\r");
+ }
}
}
\ No newline at end of file