BS 0.0.1
This commit is contained in:
@@ -5,8 +5,6 @@
|
|||||||
<OutputType>Exe</OutputType>
|
<OutputType>Exe</OutputType>
|
||||||
<TargetFramework>net8.0</TargetFramework>
|
<TargetFramework>net8.0</TargetFramework>
|
||||||
<RootNamespace>Convention</RootNamespace>
|
<RootNamespace>Convention</RootNamespace>
|
||||||
<ImplicitUsings>enable</ImplicitUsings>
|
|
||||||
<Nullable>enable</Nullable>
|
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
@@ -3,33 +3,40 @@ using System.Collections;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Text;
|
using Microsoft.VisualBasic;
|
||||||
using System.Threading.Tasks;
|
|
||||||
using static System.Runtime.InteropServices.JavaScript.JSType;
|
|
||||||
|
|
||||||
namespace Convention
|
namespace Convention
|
||||||
{
|
{
|
||||||
// Interface
|
// Interface
|
||||||
|
|
||||||
|
public interface ISignal
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
public interface IModel
|
public interface IModel
|
||||||
{
|
{
|
||||||
string Save();
|
string Save();
|
||||||
void Load(string data);
|
void Load(string data);
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface IConvertModel<T>
|
public interface IConvertable<T>
|
||||||
: IModel
|
|
||||||
{
|
{
|
||||||
T ConvertTo();
|
T ConvertTo();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public interface IConvertModel<T>
|
||||||
|
: IModel, IConvertable<T>
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
// Instance
|
// Instance
|
||||||
|
|
||||||
public class SingletonModel<T>: IModel
|
public class SingletonModel<T>: IModel
|
||||||
{
|
{
|
||||||
private static T? InjectInstance = default;
|
private static T InjectInstance = default;
|
||||||
|
|
||||||
public static T? Instance
|
public static T Instance
|
||||||
{
|
{
|
||||||
get => InjectInstance;
|
get => InjectInstance;
|
||||||
set
|
set
|
||||||
@@ -43,7 +50,7 @@ namespace Convention
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public T? Data => InjectInstance;
|
public T Data => InjectInstance;
|
||||||
|
|
||||||
void IModel.Load(string data)
|
void IModel.Load(string data)
|
||||||
{
|
{
|
||||||
@@ -63,7 +70,7 @@ namespace Convention
|
|||||||
throw new InvalidOperationException();
|
throw new InvalidOperationException();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static implicit operator T?(SingletonModel<T> _) => InjectInstance;
|
public static implicit operator T(SingletonModel<T> _) => InjectInstance;
|
||||||
}
|
}
|
||||||
|
|
||||||
public class DependenceModel
|
public class DependenceModel
|
||||||
@@ -118,10 +125,10 @@ namespace Convention
|
|||||||
return type.Assembly + "::" + type.FullName;
|
return type.Assembly + "::" + type.FullName;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Type? LoadFromFormat(string data)
|
public static Type LoadFromFormat(string data)
|
||||||
{
|
{
|
||||||
var keys = data.Split("::");
|
var keys = data.Split("::");
|
||||||
Assembly? asm = null;
|
Assembly asm = null;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
asm = Assembly.LoadFrom(keys[0]);
|
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;
|
exception = null;
|
||||||
var keys = data.Split("::");
|
var keys = data.Split("::");
|
||||||
Assembly? asm = null;
|
Assembly asm = null;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
asm = Assembly.LoadFrom(keys[0]);
|
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
|
private class TypeQuery
|
||||||
: IConvertModel<bool>
|
: IConvertModel<bool>
|
||||||
{
|
{
|
||||||
@@ -176,11 +200,11 @@ namespace Convention
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static HashSet<Type> RegisterHistory = new();
|
private static readonly HashSet<Type> RegisterHistory = new();
|
||||||
private static Dictionary<Type, object> UncompleteTargets = new();
|
private static readonly Dictionary<Type, object> UncompleteTargets = new();
|
||||||
private static Dictionary<Type, Action> Completer = new();
|
private static readonly Dictionary<Type, Action> Completer = new();
|
||||||
private static Dictionary<Type, DependenceModel> Dependences = new();
|
private static readonly Dictionary<Type, DependenceModel> Dependences = new();
|
||||||
private static Dictionary<Type, object> Childs = new();
|
private static readonly Dictionary<Type, object> Childs = new();
|
||||||
|
|
||||||
public class Registering : IConvertModel<bool>
|
public class Registering : IConvertModel<bool>
|
||||||
{
|
{
|
||||||
@@ -207,7 +231,7 @@ namespace Convention
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static bool InternalComplete(out HashSet<Type> InternalUpdateBuffer)
|
private static bool InternalRegisteringComplete(out HashSet<Type> InternalUpdateBuffer)
|
||||||
{
|
{
|
||||||
InternalUpdateBuffer = new();
|
InternalUpdateBuffer = new();
|
||||||
bool result = false;
|
bool result = false;
|
||||||
@@ -222,19 +246,22 @@ namespace Convention
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void InternalUpdate(HashSet<Type> InternalUpdateBuffer)
|
private static void InternalRegisteringUpdate(HashSet<Type> InternalUpdateBuffer)
|
||||||
{
|
{
|
||||||
foreach (var complete in InternalUpdateBuffer)
|
foreach (var complete in InternalUpdateBuffer)
|
||||||
{
|
{
|
||||||
Dependences.Remove(complete);
|
Dependences.Remove(complete);
|
||||||
|
}
|
||||||
|
foreach (var complete in InternalUpdateBuffer)
|
||||||
|
{
|
||||||
|
Completer[complete]();
|
||||||
|
Completer.Remove(complete);
|
||||||
}
|
}
|
||||||
foreach (var complete in InternalUpdateBuffer)
|
foreach (var complete in InternalUpdateBuffer)
|
||||||
{
|
{
|
||||||
Childs.Add(complete, UncompleteTargets[complete]);
|
Childs.Add(complete, UncompleteTargets[complete]);
|
||||||
UncompleteTargets.Remove(complete);
|
UncompleteTargets.Remove(complete);
|
||||||
}
|
}
|
||||||
InternalUpdateBuffer.Clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Registering Register(Type slot, object target, Action completer, params Type[] dependences)
|
public static Registering Register(Type slot, object target, Action completer, params Type[] dependences)
|
||||||
@@ -245,9 +272,9 @@ namespace Convention
|
|||||||
}
|
}
|
||||||
Completer[slot] = completer;
|
Completer[slot] = completer;
|
||||||
UncompleteTargets[slot] = target;
|
UncompleteTargets[slot] = target;
|
||||||
Dependences[slot] = new DependenceModel(from dependence in dependences select new TypeQuery(dependence));
|
Dependences[slot] = new DependenceModel(from dependence in dependences where dependence != slot select new TypeQuery(dependence));
|
||||||
while (InternalComplete(out var buffer))
|
while (InternalRegisteringComplete(out var buffer))
|
||||||
InternalUpdate(buffer);
|
InternalRegisteringUpdate(buffer);
|
||||||
return new Registering(slot);
|
return new Registering(slot);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -262,5 +289,124 @@ namespace Convention
|
|||||||
public static object Get(Type type) => InternalGet(type);
|
public static object Get(Type type) => InternalGet(type);
|
||||||
|
|
||||||
public static T Get<T>() => (T)Get(typeof(T));
|
public static T Get<T>() => (T)Get(typeof(T));
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Signal & Update
|
||||||
|
|
||||||
|
private static readonly Dictionary<Type, HashSet<Action<ISignal>>> SignalListener = new();
|
||||||
|
|
||||||
|
public class Listening
|
||||||
|
{
|
||||||
|
private readonly Action<ISignal> action;
|
||||||
|
private readonly Type type;
|
||||||
|
|
||||||
|
public Listening(Action<ISignal> 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<Signal>(Type slot, Action<Signal> listener) where Signal : ISignal
|
||||||
|
{
|
||||||
|
if (SignalListener.ContainsKey(slot) == false)
|
||||||
|
SignalListener.Add(slot, new());
|
||||||
|
Action<ISignal> 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 signal) where Signal : ISignal => SendMessage(signal.GetType(), signal);
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Timeline/Chain & Update
|
||||||
|
|
||||||
|
private class TimelineQueneEntry
|
||||||
|
{
|
||||||
|
public Func<bool> predicate;
|
||||||
|
public List<Action> actions = new();
|
||||||
|
}
|
||||||
|
|
||||||
|
private class Timeline
|
||||||
|
{
|
||||||
|
public Dictionary<Func<bool>, int> PredicateMapper = new();
|
||||||
|
public List<TimelineQueneEntry> Quene = new();
|
||||||
|
public int Context = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Dictionary<int, Timeline> 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<bool> 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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -6,5 +6,59 @@ using System.Threading.Tasks;
|
|||||||
|
|
||||||
namespace Convention
|
namespace Convention
|
||||||
{
|
{
|
||||||
|
namespace NTree
|
||||||
|
{
|
||||||
|
public class NTreeNode<T>
|
||||||
|
{
|
||||||
|
public NTreeNode<T> Parent;
|
||||||
|
public NTreeNode<T> Child;
|
||||||
|
public NTreeNode<T> 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<T>
|
||||||
|
{
|
||||||
|
internal NTreeNode<T> Root;
|
||||||
|
|
||||||
|
public bool IsEmpty() => Root == null;
|
||||||
|
|
||||||
|
public NTreeNode<T> UpdateRoot(NTreeNode<T> node)
|
||||||
|
{
|
||||||
|
var oldRoot = Root;
|
||||||
|
Root = node;
|
||||||
|
return oldRoot;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,9 +1,48 @@
|
|||||||
using Convention;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Threading;
|
||||||
|
using Convention;
|
||||||
|
|
||||||
public class Program
|
public class Program
|
||||||
{
|
{
|
||||||
|
class Slot1
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
class Slot2
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
class Slot3
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
class Slot4
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
static void Main(string[] args)
|
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<Action> 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");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
Reference in New Issue
Block a user