|
|
@ -52,9 +52,9 @@ public class ModuleManager |
|
|
|
|
|
|
|
|
|
|
|
var path = GetModulePath(type); |
|
|
|
var path = GetModulePath(type); |
|
|
|
var module = new ModuleInfo(Universe, type, path); |
|
|
|
var module = new ModuleInfo(Universe, type, path); |
|
|
|
_modules.Add(module.ModuleEntity, module); |
|
|
|
_modules.Add(module.Entity, module); |
|
|
|
TryEnableModule(module); |
|
|
|
TryEnableModule(module); |
|
|
|
return module.ModuleEntity; |
|
|
|
return module.Entity; |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
@ -67,14 +67,16 @@ public class ModuleManager |
|
|
|
// Find other modules that might be missing this module as a dependency. |
|
|
|
// Find other modules that might be missing this module as a dependency. |
|
|
|
foreach (var other in _modules.Values) { |
|
|
|
foreach (var other in _modules.Values) { |
|
|
|
if (other.IsActive) continue; |
|
|
|
if (other.IsActive) continue; |
|
|
|
if (!other.UnmetDependencies.Contains(module.ModuleEntity)) continue; |
|
|
|
if (!other.UnmetDependencies.Contains(module.Entity)) continue; |
|
|
|
|
|
|
|
|
|
|
|
// Move the just enabled module from unmet to met depedencies. |
|
|
|
// Move the just enabled module from unmet to met depedencies. |
|
|
|
other.UnmetDependencies.Remove(module.ModuleEntity); |
|
|
|
other.UnmetDependencies.Remove(module.Entity); |
|
|
|
other.MetDependencies.Add(module); |
|
|
|
other.MetDependencies.Add(module); |
|
|
|
|
|
|
|
|
|
|
|
TryEnableModule(other); |
|
|
|
TryEnableModule(other); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Console.WriteLine("Enabled module " + module.Path); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public static EntityPath GetModulePath(Type type) |
|
|
|
public static EntityPath GetModulePath(Type type) |
|
|
@ -103,10 +105,10 @@ public class ModuleManager |
|
|
|
internal class ModuleInfo |
|
|
|
internal class ModuleInfo |
|
|
|
{ |
|
|
|
{ |
|
|
|
public Universe Universe { get; } |
|
|
|
public Universe Universe { get; } |
|
|
|
public Type ModuleType { get; } |
|
|
|
public Type Type { get; } |
|
|
|
public EntityPath ModulePath { get; } |
|
|
|
public EntityPath Path { get; } |
|
|
|
|
|
|
|
|
|
|
|
public EntityRef ModuleEntity { get; } |
|
|
|
public EntityRef Entity { get; } |
|
|
|
public object? Instance { get; internal set; } |
|
|
|
public object? Instance { get; internal set; } |
|
|
|
public bool IsActive => Instance != null; |
|
|
|
public bool IsActive => Instance != null; |
|
|
|
|
|
|
|
|
|
|
@ -116,18 +118,18 @@ internal class ModuleInfo |
|
|
|
public ModuleInfo(Universe universe, Type type, EntityPath path) |
|
|
|
public ModuleInfo(Universe universe, Type type, EntityPath path) |
|
|
|
{ |
|
|
|
{ |
|
|
|
Universe = universe; |
|
|
|
Universe = universe; |
|
|
|
ModuleType = type; |
|
|
|
Type = type; |
|
|
|
ModulePath = path; |
|
|
|
Path = path; |
|
|
|
|
|
|
|
|
|
|
|
if (ModuleType.IsAbstract || ModuleType.IsSealed) throw new Exception( |
|
|
|
if (Type.IsAbstract || Type.IsSealed) throw new Exception( |
|
|
|
$"Module {ModuleType} must not be abstract or sealed"); |
|
|
|
$"Module {Type} must not be abstract or sealed"); |
|
|
|
if (ModuleType.GetConstructor(Type.EmptyTypes) == null) throw new Exception( |
|
|
|
if (Type.GetConstructor(Type.EmptyTypes) == null) throw new Exception( |
|
|
|
$"Module {ModuleType} must define public parameterless constructor"); |
|
|
|
$"Module {Type} must define public parameterless constructor"); |
|
|
|
|
|
|
|
|
|
|
|
var module = Universe.New(path).Add<Module>(); |
|
|
|
var module = Universe.New(path).Add<Module>(); |
|
|
|
|
|
|
|
|
|
|
|
// Add module dependencies from [DependsOn] attributes. |
|
|
|
// Add module dependencies from [DependsOn] attributes. |
|
|
|
foreach (var dependsAttr in ModuleType.GetMultiple<DependsOnAttribute>()) { |
|
|
|
foreach (var dependsAttr in Type.GetMultiple<DependsOnAttribute>()) { |
|
|
|
var dependsPath = ModuleManager.GetModulePath(dependsAttr.Type); |
|
|
|
var dependsPath = ModuleManager.GetModulePath(dependsAttr.Type); |
|
|
|
var dependency = Universe.Lookup(dependsPath) ?? |
|
|
|
var dependency = Universe.Lookup(dependsPath) ?? |
|
|
|
Universe.New(dependsPath).Add<Module>().Disable().Build(); |
|
|
|
Universe.New(dependsPath).Add<Module>().Disable().Build(); |
|
|
@ -139,26 +141,26 @@ internal class ModuleInfo |
|
|
|
module.Add<DependsOn>(dependency); |
|
|
|
module.Add<DependsOn>(dependency); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
ModuleEntity = module.Build().CreateLookup(type); |
|
|
|
Entity = module.Build().CreateLookup(type); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public void Enable() |
|
|
|
public void Enable() |
|
|
|
{ |
|
|
|
{ |
|
|
|
ModuleEntity.Enable(); |
|
|
|
Entity.Enable(); |
|
|
|
Instance = Activator.CreateInstance(ModuleType)!; |
|
|
|
Instance = Activator.CreateInstance(Type)!; |
|
|
|
RegisterNestedTypes(); |
|
|
|
RegisterNestedTypes(); |
|
|
|
(Instance as IModuleInitializer)?.Initialize(ModuleEntity); |
|
|
|
(Instance as IModuleInitializer)?.Initialize(Entity); |
|
|
|
RegisterMethods(Instance); |
|
|
|
RegisterMethods(Instance); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private void RegisterNestedTypes() |
|
|
|
private void RegisterNestedTypes() |
|
|
|
{ |
|
|
|
{ |
|
|
|
foreach (var type in ModuleType.GetNestedTypes()) { |
|
|
|
foreach (var type in Type.GetNestedTypes()) { |
|
|
|
if (type.Get<EntityAttribute>() is not EntityAttribute attr) continue; |
|
|
|
if (type.Get<EntityAttribute>() is not EntityAttribute attr) continue; |
|
|
|
if (attr.Name?.Contains(EntityPath.Separator) == true) throw new Exception( |
|
|
|
if (attr.Name?.Contains(EntityPath.Separator) == true) throw new Exception( |
|
|
|
$"{type} must not contain '{EntityPath.Separator}'"); |
|
|
|
$"{type} must not contain '{EntityPath.Separator}'"); |
|
|
|
var name = attr.Name ?? type.Name; |
|
|
|
var name = attr.Name ?? type.Name; |
|
|
|
var entity = ModuleEntity.NewChild(name).Symbol(name); |
|
|
|
var entity = Entity.NewChild(name).Symbol(name); |
|
|
|
switch (attr) { |
|
|
|
switch (attr) { |
|
|
|
|
|
|
|
|
|
|
|
case TagAttribute: |
|
|
|
case TagAttribute: |
|
|
@ -183,11 +185,11 @@ internal class ModuleInfo |
|
|
|
|
|
|
|
|
|
|
|
private void RegisterMethods(object? instance) |
|
|
|
private void RegisterMethods(object? instance) |
|
|
|
{ |
|
|
|
{ |
|
|
|
foreach (var method in ModuleType.GetMethods()) { |
|
|
|
foreach (var method in Type.GetMethods()) { |
|
|
|
if (method.Has<SystemAttribute>()) |
|
|
|
if (method.Has<SystemAttribute>()) |
|
|
|
Universe.RegisterSystem(instance, method).ChildOf(ModuleEntity); |
|
|
|
Universe.RegisterSystem(instance, method).ChildOf(Entity); |
|
|
|
if (method.Has<ObserverAttribute>()) |
|
|
|
if (method.Has<ObserverAttribute>()) |
|
|
|
Universe.RegisterObserver(instance, method).ChildOf(ModuleEntity); |
|
|
|
Universe.RegisterObserver(instance, method).ChildOf(Entity); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|