-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
decembrist-revolt
authored and
decembrist-revolt
committed
Apr 19, 2021
0 parents
commit be9b32c
Showing
45 changed files
with
1,220 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
/.idea/ | ||
|
||
### Godot ### | ||
|
||
# Godot-specific ignores | ||
.import/ | ||
export.cfg | ||
export_presets.cfg | ||
|
||
# Imported translations (automatically generated from CSV files) | ||
*.translation | ||
|
||
# Mono-specific ignores | ||
.mono/ | ||
data_*/ | ||
|
||
### Csharp ### | ||
## Ignore Visual Studio temporary files, build results, and | ||
## files generated by popular Visual Studio add-ons. | ||
## | ||
## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore | ||
|
||
# User-specific files | ||
*.rsuser | ||
*.suo | ||
*.user | ||
*.userosscache | ||
*.sln.docstates | ||
|
||
# User-specific files (MonoDevelop/Xamarin Studio) | ||
*.userprefs | ||
|
||
# Mono auto generated files | ||
mono_crash.* | ||
|
||
# Build results | ||
[Dd]ebug/ | ||
[Dd]ebugPublic/ | ||
[Rr]elease/ | ||
[Rr]eleases/ | ||
x64/ | ||
x86/ | ||
[Ww][Ii][Nn]32/ | ||
[Aa][Rr][Mm]/ | ||
[Aa][Rr][Mm]64/ | ||
bld/ | ||
[Bb]in/ | ||
[Oo]bj/ | ||
[Ll]og/ | ||
[Ll]ogs/ | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
<Project Sdk="Godot.NET.Sdk/3.2.3"> | ||
<PropertyGroup> | ||
<LangVersion>8</LangVersion> | ||
<TargetFramework>netcoreapp3.1</TargetFramework> | ||
<RootNamespace>Decembrist</RootNamespace> | ||
</PropertyGroup> | ||
</Project> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
<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:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=addons/@EntryIndexedValue">True</s:Boolean> | ||
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=addons_005Cdecembrist_005Fplugin/@EntryIndexedValue">True</s:Boolean> | ||
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=addons_005Cspring_005Fframework/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
Microsoft Visual Studio Solution File, Format Version 12.00 | ||
# Visual Studio 2012 | ||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Decembrist Plugin", "Decembrist Plugin.csproj", "{009F4AE3-B7A3-406D-8521-76DE42F276CC}" | ||
EndProject | ||
Global | ||
GlobalSection(SolutionConfigurationPlatforms) = preSolution | ||
Debug|Any CPU = Debug|Any CPU | ||
ExportDebug|Any CPU = ExportDebug|Any CPU | ||
ExportRelease|Any CPU = ExportRelease|Any CPU | ||
EndGlobalSection | ||
GlobalSection(ProjectConfigurationPlatforms) = postSolution | ||
{009F4AE3-B7A3-406D-8521-76DE42F276CC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | ||
{009F4AE3-B7A3-406D-8521-76DE42F276CC}.Debug|Any CPU.Build.0 = Debug|Any CPU | ||
{009F4AE3-B7A3-406D-8521-76DE42F276CC}.ExportDebug|Any CPU.ActiveCfg = ExportDebug|Any CPU | ||
{009F4AE3-B7A3-406D-8521-76DE42F276CC}.ExportDebug|Any CPU.Build.0 = ExportDebug|Any CPU | ||
{009F4AE3-B7A3-406D-8521-76DE42F276CC}.ExportRelease|Any CPU.ActiveCfg = ExportRelease|Any CPU | ||
{009F4AE3-B7A3-406D-8521-76DE42F276CC}.ExportRelease|Any CPU.Build.0 = ExportRelease|Any CPU | ||
EndGlobalSection | ||
EndGlobal |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
using Decembrist.Di; | ||
using Decembrist.Example.Service; | ||
|
||
namespace Decembrist.Example | ||
{ | ||
public class DecembristConfiguration: IDecembristConfiguration | ||
{ | ||
public ContainerBuilder ConfigDi(ContainerBuilder builder) | ||
{ | ||
builder.Register<SomeService2, IService>(); | ||
builder.Register<SomeService1>(); | ||
return builder; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
namespace Decembrist.Example.Service | ||
{ | ||
public interface IService | ||
{ | ||
public void Run(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
using Godot; | ||
|
||
namespace Decembrist.Example.Service | ||
{ | ||
public class SomeService1 | ||
{ | ||
public void SayHello() => GD.Print("Hello"); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
namespace Decembrist.Example.Service | ||
{ | ||
public class SomeService2: IService | ||
{ | ||
private readonly SomeService1 _service1; | ||
|
||
public SomeService2(SomeService1 service1) | ||
{ | ||
_service1 = service1; | ||
} | ||
|
||
public void Run() => _service1.SayHello(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
using Godot; | ||
using Decembrist.Di; | ||
using Decembrist.Example.Service; | ||
using Decembrist.Utils; | ||
|
||
namespace Decembrist.Example | ||
{ | ||
public class TestScene : Node2D | ||
{ | ||
[Inject] | ||
private IService service; | ||
|
||
public override void _Ready() | ||
{ | ||
this.InjectAll(); | ||
service.Run(); | ||
} | ||
|
||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
[gd_scene load_steps=2 format=2] | ||
|
||
[ext_resource path="res://Example/TestScene.cs" type="Script" id=1] | ||
|
||
[node name="Node2D" type="Node2D"] | ||
script = ExtResource( 1 ) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
#nullable enable | ||
using System; | ||
using System.Reflection; | ||
using Godot; | ||
using Decembrist.Di; | ||
using Decembrist.Service; | ||
using DiContainer = Decembrist.Di.Container; | ||
|
||
namespace Decembrist.Autoload | ||
{ | ||
public class DiService : Node2D | ||
{ | ||
public DiContainer Container; | ||
|
||
public override void _Ready() | ||
{ | ||
} | ||
|
||
public DiService() | ||
{ | ||
var builder = new ContainerBuilder(); | ||
builder.RegisterInstance(new ConfigService()); | ||
builder = InstantiateConfig()?.ConfigDi(builder) ?? builder; | ||
Container = builder.Build(); | ||
} | ||
|
||
public T? ResolveOrNull<T>() where T : class | ||
{ | ||
return Container.ResolveOrNull(typeof(T)) as T; | ||
} | ||
|
||
public void InjectAll(object instance) | ||
{ | ||
var type = instance.GetType(); | ||
var fields = type.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); | ||
foreach (var field in fields) | ||
{ | ||
if (field.GetCustomAttribute(typeof(Inject)) != null) | ||
{ | ||
var serviceType = field.FieldType; | ||
var service = Container.ResolveOrNull(serviceType); | ||
if (service != null) | ||
{ | ||
field.SetValue(instance, service); | ||
} | ||
else | ||
{ | ||
GD.PrintErr($"No such type registered in container: {serviceType} for class {type}"); | ||
} | ||
} | ||
} | ||
} | ||
|
||
private IDecembristConfiguration? InstantiateConfig() | ||
{ | ||
if (!(ProjectSettings.GetSetting("decembrist/config_class") is string configClass)) | ||
{ | ||
return null; | ||
} | ||
var configType = Type.GetType(configClass); | ||
if (configType == null) | ||
{ | ||
return null; | ||
} | ||
|
||
var noArgConstructor = configType?.GetConstructor(new Type[0]); | ||
var config = noArgConstructor?.Invoke(null) ?? | ||
throw new Exception($"Decembrist config {configType} has no default constructor"); | ||
if (config is IDecembristConfiguration decembristConfiguration) | ||
{ | ||
return decembristConfiguration; | ||
} | ||
|
||
return null; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
#if TOOLS | ||
using Godot; | ||
|
||
[Tool] | ||
public class DecembristPlugin : EditorPlugin | ||
{ | ||
public override void EnablePlugin() | ||
{ | ||
AddAutoloadSingleton("DI", "res://addons/decembrist_plugin/Autoload/DiService.cs"); | ||
CheckSetting("decembrist/config_class", "DecembristConfiguration"); | ||
} | ||
|
||
public override void DisablePlugin() | ||
{ | ||
RemoveAutoloadSingleton("DI"); | ||
} | ||
|
||
private void CheckSetting(string name, object @default) | ||
{ | ||
var setting = ProjectSettings.GetSetting(name); | ||
if (setting == null) | ||
{ | ||
ProjectSettings.SetSetting(name, @default); | ||
} | ||
} | ||
} | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,115 @@ | ||
#nullable enable | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using System.Reflection; | ||
using Decembrist.Service; | ||
|
||
namespace Decembrist.Di | ||
{ | ||
public class Container | ||
{ | ||
private readonly Dictionary<Type, object> _instanceMap; | ||
|
||
public Container(Dictionary<Type, object> instanceMap, Dictionary<Type, Type> typeMap) | ||
{ | ||
_instanceMap = instanceMap; | ||
InstantiateTypes(typeMap); | ||
} | ||
|
||
public object? ResolveOrNull(Type type) | ||
{ | ||
return _instanceMap.ContainsKey(type) ? _instanceMap[type] : null; | ||
} | ||
|
||
private void InstantiateTypes(Dictionary<Type, Type> typeMap) | ||
{ | ||
var iteration = typeMap.Count; | ||
while (typeMap.Count > 0 && iteration == typeMap.Count) | ||
{ | ||
var toRemove = new List<Type>(); | ||
foreach (var (type, asType) in typeMap) | ||
{ | ||
// Instantiate through no arg constructor | ||
var instance = type.GetConstructor(new Type[0])?.Invoke(null); | ||
if (instance == null) | ||
{ | ||
var ctr = type.GetConstructors().First(); | ||
instance = InstantiateTypes(ctr); | ||
} | ||
|
||
if (instance != null) | ||
{ | ||
_instanceMap[asType] = instance; | ||
toRemove.Add(type); | ||
} | ||
} | ||
foreach (var type in toRemove) | ||
{ | ||
typeMap.Remove(type); | ||
} | ||
|
||
iteration--; | ||
} | ||
|
||
if (typeMap.Count != 0) | ||
{ | ||
var typesArr = typeMap.Values.Select(type => type.ToString()).ToArray(); | ||
throw new Exception($"Unsatisfied dependencies {string.Join("", typesArr)}"); | ||
} | ||
} | ||
|
||
private object? InstantiateTypes(ConstructorInfo ctr) | ||
{ | ||
var parameters = ctr.GetParameters(); | ||
var paramArgs = new List<object>(parameters.Length); | ||
foreach (var parameter in parameters) | ||
{ | ||
var paramType = parameter.ParameterType; | ||
if (_instanceMap.ContainsKey(paramType)) | ||
{ | ||
paramArgs.Add(_instanceMap[paramType]); | ||
} | ||
else | ||
{ | ||
break; | ||
} | ||
|
||
} | ||
|
||
object? result = null; | ||
if (parameters.Length == paramArgs.Count) | ||
{ | ||
result = ctr.Invoke(paramArgs.ToArray()); | ||
} | ||
|
||
return result; | ||
} | ||
} | ||
|
||
public class ContainerBuilder | ||
{ | ||
private readonly Dictionary<Type, object> _instanceMap = new Dictionary<Type, object>(); | ||
private readonly Dictionary<Type, Type> _typeMap = new Dictionary<Type, Type>(); | ||
|
||
public ContainerBuilder RegisterInstance<T>(T instance) | ||
{ | ||
if (instance == null) throw new Exception("Null instance registration"); | ||
|
||
_instanceMap[typeof(T)] = instance; | ||
return this; | ||
} | ||
|
||
public void Register<T>() | ||
{ | ||
_typeMap[typeof(T)] = typeof(T); | ||
} | ||
|
||
public void Register<TYpe, TYpeAs>() | ||
{ | ||
_typeMap[typeof(TYpe)] = typeof(TYpeAs); | ||
} | ||
|
||
public Container Build() => new Container(_instanceMap, _typeMap); | ||
} | ||
} |
Oops, something went wrong.