refactor
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
using UnityEngine;
|
||||
using RebootKit.Engine.Foundation;
|
||||
using UnityEngine;
|
||||
|
||||
namespace RebootKit.Engine {
|
||||
[CreateAssetMenu(menuName = RConsts.k_AddComponentMenu + RConsts.k_EngineConfigAssetName, fileName = RConsts.k_EngineConfigAssetName)]
|
||||
@@ -6,6 +7,8 @@ namespace RebootKit.Engine {
|
||||
public bool initializeOnLoad = true;
|
||||
|
||||
public EngineCoreServicesAsset coreServices;
|
||||
public ServiceAsset[] services;
|
||||
|
||||
public AppConfig appConfig;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,11 @@ using Object = UnityEngine.Object;
|
||||
namespace RebootKit.Engine.Extensions {
|
||||
public static class TransformEx {
|
||||
public static void DestroyChildren(this Transform transform) {
|
||||
foreach (Transform child in transform) Object.Destroy(child);
|
||||
foreach (Transform child in transform) {
|
||||
if (child.OrNull() != null) {
|
||||
Object.Destroy(child.gameObject);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void ForEachChild(this Transform transform, Action<Transform> action) {
|
||||
|
||||
@@ -45,7 +45,7 @@ namespace RebootKit.Engine.Services.Console {
|
||||
public override string ToString() {
|
||||
return kind switch {
|
||||
CVarValueKind.Number => numberValue.ToString(),
|
||||
CVarValueKind.String => $"\"{stringValue}\"",
|
||||
CVarValueKind.String => $"{stringValue}",
|
||||
_ => throw new ArgumentOutOfRangeException()
|
||||
};
|
||||
}
|
||||
@@ -53,17 +53,21 @@ namespace RebootKit.Engine.Services.Console {
|
||||
|
||||
[Flags]
|
||||
public enum CVarFlags {
|
||||
None, Persistent, ReadOnly
|
||||
None = 0,
|
||||
Client = 1 << 0,
|
||||
Server = 1 << 1,
|
||||
ReadOnly = 1 << 2,
|
||||
User = 1 << 3,
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public class CVar {
|
||||
public class ConfigVar {
|
||||
public CVarFlags flags;
|
||||
public string name;
|
||||
public string description;
|
||||
public CVarValue defaultValue;
|
||||
|
||||
public CVar(CVar other) {
|
||||
public ConfigVar(ConfigVar other) {
|
||||
flags = other.flags;
|
||||
name = other.name;
|
||||
description = other.description;
|
||||
@@ -71,35 +75,35 @@ namespace RebootKit.Engine.Services.Console {
|
||||
Value = other.Value;
|
||||
}
|
||||
|
||||
public CVar(string name, CVarValue value, string description = "") {
|
||||
public ConfigVar(string name, CVarValue value, string description = "") {
|
||||
this.name = name;
|
||||
this.description = description;
|
||||
defaultValue = value;
|
||||
Value = defaultValue;
|
||||
}
|
||||
|
||||
public CVar(string name, int value, string description = "") {
|
||||
public ConfigVar(string name, int value, string description = "") {
|
||||
this.name = name;
|
||||
this.description = description;
|
||||
defaultValue = new CVarValue(value);
|
||||
Value = defaultValue;
|
||||
}
|
||||
|
||||
public CVar(string name, float value, string description = "") {
|
||||
public ConfigVar(string name, float value, string description = "") {
|
||||
this.name = name;
|
||||
this.description = description;
|
||||
defaultValue = new CVarValue(value);
|
||||
Value = defaultValue;
|
||||
}
|
||||
|
||||
public CVar(string name, double value, string description = "") {
|
||||
public ConfigVar(string name, double value, string description = "") {
|
||||
this.name = name;
|
||||
this.description = description;
|
||||
defaultValue = new CVarValue(value);
|
||||
Value = defaultValue;
|
||||
}
|
||||
|
||||
public CVar(string name, string value, string description = "") {
|
||||
public ConfigVar(string name, string value, string description = "") {
|
||||
this.name = name;
|
||||
this.description = description;
|
||||
defaultValue = new CVarValue(value);
|
||||
@@ -113,43 +117,54 @@ namespace RebootKit.Engine.Services.Console {
|
||||
public double NumberValue => Value.numberValue;
|
||||
public string StringValue => Value.stringValue;
|
||||
|
||||
public event Action StateChanged = delegate { };
|
||||
public static event Action<ConfigVar> StateChanged = delegate { };
|
||||
|
||||
public void Set(int value) {
|
||||
if (flags.HasFlag(CVarFlags.ReadOnly)) return;
|
||||
if (flags.HasFlag(CVarFlags.ReadOnly)) {
|
||||
return;
|
||||
}
|
||||
|
||||
Value = new CVarValue(value);
|
||||
StateChanged?.Invoke();
|
||||
StateChanged?.Invoke(this);
|
||||
}
|
||||
|
||||
public void Set(float value) {
|
||||
if (flags.HasFlag(CVarFlags.ReadOnly)) return;
|
||||
if (flags.HasFlag(CVarFlags.ReadOnly)) {
|
||||
return;
|
||||
}
|
||||
|
||||
Value = new CVarValue(value);
|
||||
StateChanged?.Invoke();
|
||||
StateChanged?.Invoke(this);
|
||||
}
|
||||
|
||||
public void Set(string value) {
|
||||
if (flags.HasFlag(CVarFlags.ReadOnly)) return;
|
||||
if (flags.HasFlag(CVarFlags.ReadOnly)) {
|
||||
return;
|
||||
}
|
||||
|
||||
Value = new CVarValue(value);
|
||||
StateChanged?.Invoke();
|
||||
StateChanged?.Invoke(this);
|
||||
}
|
||||
|
||||
public void ParseFromString(string str) {
|
||||
if (flags.HasFlag(CVarFlags.ReadOnly)) return;
|
||||
if (flags.HasFlag(CVarFlags.ReadOnly)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (float.TryParse(str, out float f))
|
||||
if (float.TryParse(str, out float f)) {
|
||||
Set(f);
|
||||
else
|
||||
} else {
|
||||
Set(str);
|
||||
}
|
||||
}
|
||||
|
||||
public void Reset() {
|
||||
if (flags.HasFlag(CVarFlags.ReadOnly)) return;
|
||||
if (flags.HasFlag(CVarFlags.ReadOnly)) {
|
||||
return;
|
||||
}
|
||||
|
||||
Value = defaultValue;
|
||||
StateChanged?.Invoke();
|
||||
StateChanged?.Invoke(this);
|
||||
}
|
||||
|
||||
public override string ToString() {
|
||||
153
Runtime/Engine/Code/Foundation/ConfigVarsContainer.cs
Normal file
153
Runtime/Engine/Code/Foundation/ConfigVarsContainer.cs
Normal file
@@ -0,0 +1,153 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using RebootKit.Engine.Services.Console;
|
||||
using UnityEngine;
|
||||
using ZLinq;
|
||||
|
||||
namespace RebootKit.Engine.Foundation {
|
||||
[AttributeUsage(AttributeTargets.Field)]
|
||||
public class ConfigVarAttribute : Attribute {
|
||||
public ConfigVarAttribute(string name, float defaultValue, string description = "", CVarFlags flags = CVarFlags.Client) {
|
||||
Name = name;
|
||||
Description = description;
|
||||
Value = new CVarValue(defaultValue);
|
||||
Flags = flags;
|
||||
}
|
||||
|
||||
public ConfigVarAttribute(string name, double defaultValue, string description = "", CVarFlags flags = CVarFlags.Client) {
|
||||
Name = name;
|
||||
Description = description;
|
||||
Value = new CVarValue(defaultValue);
|
||||
Flags = flags;
|
||||
}
|
||||
|
||||
public ConfigVarAttribute(string name, string defaultValue, string description = "", CVarFlags flags = CVarFlags.Client) {
|
||||
Name = name;
|
||||
Description = description;
|
||||
Value = new CVarValue(defaultValue);
|
||||
Flags = flags;
|
||||
}
|
||||
|
||||
public ConfigVarAttribute(string name, int defaultValue, string description = "", CVarFlags flags = CVarFlags.Client) {
|
||||
Name = name;
|
||||
Description = description;
|
||||
Value = new CVarValue(defaultValue);
|
||||
Flags = flags;
|
||||
}
|
||||
|
||||
internal string Name { get; }
|
||||
internal string Description { get; }
|
||||
internal CVarValue Value { get; }
|
||||
internal CVarFlags Flags { get; }
|
||||
}
|
||||
|
||||
public static class ConfigVarsContainer {
|
||||
static readonly Logger s_logger = new(nameof(ConfigVarsContainer));
|
||||
|
||||
static readonly List<ConfigVar> s_configVars = new();
|
||||
|
||||
public static void Register(ConfigVar cvar) {
|
||||
if (s_configVars.AsValueEnumerable().Any(c => c.name.Equals(cvar.name, StringComparison.Ordinal))) {
|
||||
throw new Exception($"CVar with name '{cvar.name}' already exists");
|
||||
}
|
||||
|
||||
s_configVars.Add(cvar);
|
||||
s_logger.Info($"Registered CVar: {cvar.name}");
|
||||
}
|
||||
|
||||
public static void Clear() {
|
||||
s_configVars.Clear();
|
||||
s_logger.Info("Cleared all CVars");
|
||||
}
|
||||
|
||||
public static ConfigVar Get(string name) {
|
||||
return s_configVars.AsValueEnumerable().FirstOrDefault(c => c.name.Equals(name, StringComparison.Ordinal));
|
||||
}
|
||||
|
||||
public static IEnumerable<ConfigVar> All() => s_configVars;
|
||||
|
||||
public static void Init() {
|
||||
Clear();
|
||||
|
||||
Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
|
||||
|
||||
foreach (Assembly assembly in assemblies) {
|
||||
Type[] types = assembly.GetTypes();
|
||||
|
||||
foreach (Type type in types) {
|
||||
FieldInfo[] fields = type.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static);
|
||||
|
||||
foreach (FieldInfo field in fields) {
|
||||
if (Attribute.IsDefined(field, typeof(ConfigVarAttribute))) {
|
||||
ConfigVarAttribute cvarAttribute = field.GetCustomAttribute<ConfigVarAttribute>();
|
||||
|
||||
ConfigVar cvar = Get(cvarAttribute.Name);
|
||||
if (cvar == null) {
|
||||
cvar = new ConfigVar(cvarAttribute.Name, cvarAttribute.Value, cvarAttribute.Description) {
|
||||
flags = cvarAttribute.Flags
|
||||
};
|
||||
Register(cvar);
|
||||
}
|
||||
|
||||
field.SetValue(null, cvar);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Load();
|
||||
}
|
||||
|
||||
public static void Save() {
|
||||
string path = Application.persistentDataPath + "/" + RConsts.k_CVarsFilename;
|
||||
|
||||
s_logger.Info("Saving cvars to file: " + path);
|
||||
|
||||
StringBuilder sb = new();
|
||||
|
||||
foreach (ConfigVar cvar in All()) {
|
||||
if (!cvar.flags.HasFlag(CVarFlags.ReadOnly)) {
|
||||
sb.AppendFormat("{0} {1}\n", cvar.name, cvar);
|
||||
}
|
||||
}
|
||||
|
||||
File.WriteAllText(path, sb.ToString());
|
||||
}
|
||||
|
||||
public static void Load() {
|
||||
string path = Application.persistentDataPath + "/" + RConsts.k_CVarsFilename;
|
||||
if (!File.Exists(path)) {
|
||||
s_logger.Info("CVar file not found, skipping load");
|
||||
return;
|
||||
}
|
||||
|
||||
s_logger.Info("Loading cvars from file: " + path);
|
||||
string[] lines = File.ReadAllLines(path);
|
||||
foreach (string line in lines) {
|
||||
string[] parts = line.Split(' ');
|
||||
if (parts.Length < 2) {
|
||||
continue;
|
||||
}
|
||||
|
||||
string name = parts[0];
|
||||
string value = parts[1];
|
||||
|
||||
ConfigVar cvar = Get(name);
|
||||
if (cvar != null) {
|
||||
cvar.Value.CopyFrom(new CVarValue(value));
|
||||
s_logger.Info($"Loaded CVar: {name} = {value}");
|
||||
} else {
|
||||
cvar = new ConfigVar(name, value) {
|
||||
flags = CVarFlags.User
|
||||
};
|
||||
cvar.ParseFromString(value);
|
||||
|
||||
Register(cvar);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
9
Runtime/Engine/Code/Foundation/ConstantsAsset.cs
Normal file
9
Runtime/Engine/Code/Foundation/ConstantsAsset.cs
Normal file
@@ -0,0 +1,9 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace RebootKit.Engine.Foundation {
|
||||
public class ConstantsAsset<T> : RAsset {
|
||||
[SerializeField] T m_Value;
|
||||
|
||||
public T Value => m_Value;
|
||||
}
|
||||
}
|
||||
3
Runtime/Engine/Code/Foundation/ConstantsAsset.cs.meta
Normal file
3
Runtime/Engine/Code/Foundation/ConstantsAsset.cs.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 602c79db950d497ea9800a6538aa7ab6
|
||||
timeCreated: 1743848110
|
||||
7
Runtime/Engine/Code/Foundation/ConstsColorAsset.cs
Normal file
7
Runtime/Engine/Code/Foundation/ConstsColorAsset.cs
Normal file
@@ -0,0 +1,7 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace RebootKit.Engine.Foundation {
|
||||
[CreateAssetMenu(menuName = RConsts.k_CreateAssetMenu + "Constants/Consts Color")]
|
||||
public class ConstsColorAsset : ConstantsAsset<Color> {
|
||||
}
|
||||
}
|
||||
3
Runtime/Engine/Code/Foundation/ConstsColorAsset.cs.meta
Normal file
3
Runtime/Engine/Code/Foundation/ConstsColorAsset.cs.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5055a0315a6942988576e3dc5fa72368
|
||||
timeCreated: 1743848378
|
||||
7
Runtime/Engine/Code/Foundation/ConstsFloatAsset.cs
Normal file
7
Runtime/Engine/Code/Foundation/ConstsFloatAsset.cs
Normal file
@@ -0,0 +1,7 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace RebootKit.Engine.Foundation {
|
||||
[CreateAssetMenu(menuName = RConsts.k_CreateAssetMenu + "Constants/Consts Float")]
|
||||
public class ConstsFloatAsset : ConstantsAsset<float> {
|
||||
}
|
||||
}
|
||||
3
Runtime/Engine/Code/Foundation/ConstsFloatAsset.cs.meta
Normal file
3
Runtime/Engine/Code/Foundation/ConstsFloatAsset.cs.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 82df0e4f31ac4722ae6ec18f66815179
|
||||
timeCreated: 1743848335
|
||||
7
Runtime/Engine/Code/Foundation/ConstsIntAsset.cs
Normal file
7
Runtime/Engine/Code/Foundation/ConstsIntAsset.cs
Normal file
@@ -0,0 +1,7 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace RebootKit.Engine.Foundation {
|
||||
[CreateAssetMenu(menuName = RConsts.k_CreateAssetMenu + "Constants/Consts Int")]
|
||||
public class ConstsIntAsset : ConfigAsset<int> {
|
||||
}
|
||||
}
|
||||
3
Runtime/Engine/Code/Foundation/ConstsIntAsset.cs.meta
Normal file
3
Runtime/Engine/Code/Foundation/ConstsIntAsset.cs.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 064ad4ee1c584489b0c65417e8b500ea
|
||||
timeCreated: 1743848190
|
||||
37
Runtime/Engine/Code/Foundation/ConstsProperty.cs
Normal file
37
Runtime/Engine/Code/Foundation/ConstsProperty.cs
Normal file
@@ -0,0 +1,37 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace RebootKit.Engine.Foundation {
|
||||
[Serializable]
|
||||
public struct ConstsProperty<T> {
|
||||
[SerializeField] T m_InlineValue;
|
||||
[SerializeField] ConstantsAsset<T> m_Asset;
|
||||
[SerializeField] bool m_UseInlineValue;
|
||||
|
||||
public ConstsProperty(T value) {
|
||||
m_InlineValue = value;
|
||||
m_Asset = null;
|
||||
m_UseInlineValue = true;
|
||||
}
|
||||
|
||||
public ConstsProperty(ConstantsAsset<T> asset) {
|
||||
m_InlineValue = default;
|
||||
m_Asset = asset;
|
||||
m_UseInlineValue = false;
|
||||
}
|
||||
|
||||
public T Value {
|
||||
get {
|
||||
if (m_UseInlineValue) {
|
||||
return m_InlineValue;
|
||||
}
|
||||
|
||||
if (m_Asset != null) {
|
||||
return m_Asset.Value;
|
||||
}
|
||||
|
||||
return default;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
3
Runtime/Engine/Code/Foundation/ConstsProperty.cs.meta
Normal file
3
Runtime/Engine/Code/Foundation/ConstsProperty.cs.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 426c2ae5506c4629bf757f51c5b94249
|
||||
timeCreated: 1743848423
|
||||
@@ -2,6 +2,7 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using ZLinq;
|
||||
|
||||
namespace RebootKit.Engine.Foundation {
|
||||
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Method)]
|
||||
@@ -28,7 +29,9 @@ namespace RebootKit.Engine.Foundation {
|
||||
}
|
||||
|
||||
public void Bind(Type type, object obj) {
|
||||
if (!m_BindingsMaps.TryAdd(type, obj)) s_logger.Error($"Cannot bind to '{type}', slot is already occupied");
|
||||
if (!m_BindingsMaps.TryAdd(type, obj)) {
|
||||
s_logger.Error($"Cannot bind to '{type}', slot is already occupied");
|
||||
}
|
||||
}
|
||||
|
||||
public void Bind<TBind>(TBind obj) {
|
||||
@@ -53,22 +56,27 @@ namespace RebootKit.Engine.Foundation {
|
||||
Inject(instance);
|
||||
return instance;
|
||||
}
|
||||
|
||||
|
||||
public T Create<T>(params object[] args) {
|
||||
T instance = (T) Activator.CreateInstance(typeof(T), args);
|
||||
Inject(instance);
|
||||
return instance;
|
||||
}
|
||||
|
||||
public void Inject<T>(T target) {
|
||||
Type type = typeof(T);
|
||||
|
||||
foreach (FieldInfo field in type.GetFields(k_fieldsBindingFlags)) InjectField(field, target);
|
||||
public void Inject(object target) {
|
||||
Type type = target.GetType();
|
||||
|
||||
foreach (FieldInfo field in type.GetFields(k_fieldsBindingFlags)) {
|
||||
InjectField(field, target);
|
||||
}
|
||||
|
||||
foreach (MethodInfo method in type.GetMethods(k_methodsBindingFlags)) {
|
||||
if (!Attribute.IsDefined(method, typeof(InjectAttribute))) continue;
|
||||
if (!Attribute.IsDefined(method, typeof(InjectAttribute))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Type[] paramsTypes = method.GetParameters()
|
||||
.AsValueEnumerable()
|
||||
.Select(t => t.ParameterType)
|
||||
.ToArray();
|
||||
|
||||
@@ -77,7 +85,9 @@ namespace RebootKit.Engine.Foundation {
|
||||
for (int i = 0; i < paramsTypes.Length; ++i) {
|
||||
instances[i] = Resolve(paramsTypes[i]);
|
||||
|
||||
if (instances[i] == null) s_logger.Error($"Failed to resolve method parameter of type `{paramsTypes[i]}`");
|
||||
if (instances[i] == null) {
|
||||
s_logger.Error($"Failed to resolve method parameter of type `{paramsTypes[i]}`");
|
||||
}
|
||||
}
|
||||
|
||||
method.Invoke(target, instances);
|
||||
@@ -85,9 +95,11 @@ namespace RebootKit.Engine.Foundation {
|
||||
}
|
||||
|
||||
bool InjectField(FieldInfo field, object target) {
|
||||
for (int i = m_FieldInjectors.Count - 1; i >= 0; i--)
|
||||
if (m_FieldInjectors[i].Inject(field, target, this))
|
||||
for (int i = m_FieldInjectors.Count - 1; i >= 0; i--) {
|
||||
if (m_FieldInjectors[i].Inject(field, target, this)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -18,12 +18,16 @@ namespace RebootKit.Engine.Foundation {
|
||||
|
||||
RR.s_Shared = null;
|
||||
|
||||
// unload all scenes
|
||||
|
||||
s_cancellationTokenSource = new CancellationTokenSource();
|
||||
RunAsync(s_cancellationTokenSource.Token).Forget();
|
||||
|
||||
#if UNITY_EDITOR
|
||||
static void OnPlayerModeState(PlayModeStateChange state) {
|
||||
if (state == PlayModeStateChange.ExitingPlayMode) s_cancellationTokenSource.Cancel();
|
||||
if (state == PlayModeStateChange.ExitingPlayMode) {
|
||||
s_cancellationTokenSource.Cancel();
|
||||
}
|
||||
}
|
||||
|
||||
EditorApplication.playModeStateChanged -= OnPlayerModeState;
|
||||
@@ -32,6 +36,9 @@ namespace RebootKit.Engine.Foundation {
|
||||
}
|
||||
|
||||
static async UniTask RunAsync(CancellationToken cancellationToken) {
|
||||
s_logger.Info("Loading boot scene");
|
||||
SceneManager.LoadScene(RConsts.k_BootSceneBuildIndex, LoadSceneMode.Single);
|
||||
|
||||
s_logger.Info("Loading engine config");
|
||||
EngineConfigAsset configAsset = Resources.Load<EngineConfigAsset>(RConsts.k_EngineConfigResourcesPath);
|
||||
if (configAsset == null) {
|
||||
@@ -42,7 +49,7 @@ namespace RebootKit.Engine.Foundation {
|
||||
if (!configAsset.initializeOnLoad) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
using RR instance = new();
|
||||
RR.s_Shared = instance;
|
||||
|
||||
@@ -54,6 +61,8 @@ namespace RebootKit.Engine.Foundation {
|
||||
|
||||
s_logger.Info("Starting RR");
|
||||
instance.Run();
|
||||
|
||||
await UniTask.WaitUntilCanceled(Application.exitCancellationToken);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,7 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using Cysharp.Threading.Tasks;
|
||||
using JetBrains.Annotations;
|
||||
|
||||
namespace RebootKit.Engine.Foundation {
|
||||
public interface IController : IDisposable {
|
||||
@@ -25,6 +26,16 @@ namespace RebootKit.Engine.Foundation {
|
||||
}
|
||||
}
|
||||
|
||||
public T Get<T>() where T : class, IController {
|
||||
foreach (TController controller in _controllers) {
|
||||
if (controller is T res) {
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public bool TryFind<T>(out T outController) where T : IController {
|
||||
foreach (TController controller in _controllers) {
|
||||
if (controller is T res) {
|
||||
|
||||
@@ -74,7 +74,7 @@ namespace RebootKit.Engine.Foundation {
|
||||
case LogLevel.Warning:
|
||||
return $"[W][<b>{name}</b>] <color=#ffffff>{message}</color>";
|
||||
case LogLevel.Error:
|
||||
return $"[<b><color=#ff0000>ERROR</color></b>][<b>{name}</b>] <color=#ffffff>{message}</color>";
|
||||
return $"[<b><color=#e83f25>ERROR</color></b>][<b>{name}</b>] <color=#ffffff>{message}</color>";
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException(nameof(level), level, null);
|
||||
}
|
||||
|
||||
@@ -11,19 +11,22 @@ namespace RebootKit.Engine.Foundation {
|
||||
}
|
||||
|
||||
[DefaultExecutionOrder(-1000)]
|
||||
public class SceneDI : MonoBehaviour, IDependencyInstaller {
|
||||
static readonly Logger s_logger = new(nameof(SceneDI));
|
||||
public class SceneContext : MonoBehaviour, IDependencyInstaller {
|
||||
static readonly Logger s_logger = new(nameof(SceneContext));
|
||||
|
||||
[SerializeField] SceneDependencyInstaller[] m_Installers;
|
||||
|
||||
void Awake() {
|
||||
DIContext context = RR.DIContext;
|
||||
|
||||
foreach (GameObject root in gameObject.scene.GetRootGameObjects()) {
|
||||
s_logger.Info("Injecting root game object: " + root.name);
|
||||
context.InjectGameObject(root);
|
||||
}
|
||||
}
|
||||
|
||||
public void Install(DIContext context) {
|
||||
s_logger.Info("Installing scene dependency installers");
|
||||
foreach (SceneDependencyInstaller installer in m_Installers) {
|
||||
installer.Install(context);
|
||||
}
|
||||
@@ -1,17 +1,15 @@
|
||||
using RebootKit.Engine.Foundation;
|
||||
using RebootKit.Engine.Graphics;
|
||||
using RebootKit.Engine.Services.ConsoleUI;
|
||||
using UnityEngine;
|
||||
|
||||
namespace RebootKit.Engine {
|
||||
public class MainSceneInstaller : SceneDependencyInstaller {
|
||||
[SerializeField] MainCameraService _mainCameraService;
|
||||
|
||||
[SerializeField] ConsoleUIService _consoleUIService;
|
||||
|
||||
public override void Install(DIContext context) {
|
||||
context.Bind(_mainCameraService);
|
||||
context.Bind(_consoleUIService);
|
||||
foreach (GameObject rootGameObject in gameObject.scene.GetRootGameObjects()) {
|
||||
IService[] services = rootGameObject.GetComponentsInParent<IService>();
|
||||
foreach (IService service in services) {
|
||||
context.Bind(service.GetType(), service);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,13 +1,20 @@
|
||||
namespace RebootKit.Engine {
|
||||
public static class RConsts {
|
||||
public const int k_MainSceneBuildIndex = 0;
|
||||
public const int k_BootSceneBuildIndex = 0;
|
||||
public const int k_MainSceneBuildIndex = 1;
|
||||
public const string k_FilenamePrefix = "rr_";
|
||||
|
||||
public const string k_EngineConfigAssetName = "RealityRebootKit";
|
||||
public const string k_EngineConfigResourcesPath = "TheGame/" + k_EngineConfigAssetName;
|
||||
public const string k_EngineConfigAssetPath = "Assets/TheGame/" + k_EngineConfigAssetName + ".asset";
|
||||
|
||||
internal const string k_AddComponentMenu = "Reboot Reality/";
|
||||
internal const string k_ServiceAssetMenu = k_AddComponentMenu + "Services/";
|
||||
internal const string k_WorldAssetMenu = k_AddComponentMenu + "World/";
|
||||
|
||||
internal const string k_CreateAssetMenu = "Reboot Reality/";
|
||||
internal const string k_ServiceAssetMenu = k_CreateAssetMenu + "Services/";
|
||||
internal const string k_WorldAssetMenu = k_CreateAssetMenu + "World/";
|
||||
|
||||
internal const string k_CVarsFilename = k_FilenamePrefix + "cvars.txt";
|
||||
|
||||
internal const string k_BuildFlagDebug = "RR_DEBUG";
|
||||
}
|
||||
|
||||
@@ -13,38 +13,36 @@ namespace RebootKit.Engine {
|
||||
public static GameService Game => s_Shared.m_GameService;
|
||||
public static DIContext DIContext => s_Shared.m_DIContext;
|
||||
|
||||
public static UnityEvent<string, CVarValue> CVarChanged => s_Shared.m_CVarChanged;
|
||||
|
||||
public static CVar CVarIndex(string name, int defaultValue = -1) {
|
||||
CVar cvar = Console.GetCVar(name);
|
||||
public static ConfigVar CVarIndex(string name, int defaultValue = -1) {
|
||||
ConfigVar cvar = ConfigVarsContainer.Get(name);
|
||||
if (cvar != null) {
|
||||
return cvar;
|
||||
}
|
||||
|
||||
cvar = new CVar(name, defaultValue);
|
||||
Console.Replace(cvar);
|
||||
cvar = new ConfigVar(name, defaultValue);
|
||||
ConfigVarsContainer.Register(cvar);
|
||||
return cvar;
|
||||
}
|
||||
|
||||
public static CVar CVarNumber(string name, double defaultValue = 0) {
|
||||
CVar cvar = Console.GetCVar(name);
|
||||
public static ConfigVar CVarNumber(string name, double defaultValue = 0) {
|
||||
ConfigVar cvar = ConfigVarsContainer.Get(name);
|
||||
if (cvar != null) {
|
||||
return cvar;
|
||||
}
|
||||
|
||||
cvar = new CVar(name, defaultValue);
|
||||
Console.Replace(cvar);
|
||||
cvar = new ConfigVar(name, defaultValue);
|
||||
ConfigVarsContainer.Register(cvar);
|
||||
return cvar;
|
||||
}
|
||||
|
||||
public static CVar CVarString(string name, string defaultValue = "") {
|
||||
CVar cvar = Console.GetCVar(name);
|
||||
public static ConfigVar CVarString(string name, string defaultValue = "") {
|
||||
ConfigVar cvar = ConfigVarsContainer.Get(name);
|
||||
if (cvar != null) {
|
||||
return cvar;
|
||||
}
|
||||
|
||||
cvar = new CVar(name, defaultValue);
|
||||
Console.Replace(cvar);
|
||||
cvar = new ConfigVar(name, defaultValue);
|
||||
ConfigVarsContainer.Register(cvar);
|
||||
return cvar;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,52 +0,0 @@
|
||||
using RebootKit.Engine.Foundation;
|
||||
|
||||
namespace RebootKit.Engine {
|
||||
class MainMenuState : IState {
|
||||
readonly MainMenuConfig m_Config;
|
||||
|
||||
public MainMenuState(MainMenuConfig config) {
|
||||
m_Config = config;
|
||||
}
|
||||
|
||||
public void Enter() {
|
||||
}
|
||||
|
||||
public void Exit() {
|
||||
}
|
||||
}
|
||||
|
||||
class PlayState : IState {
|
||||
readonly GameConfig m_Config;
|
||||
|
||||
public PlayState(GameConfig config) {
|
||||
m_Config = config;
|
||||
}
|
||||
|
||||
public void Enter() {
|
||||
}
|
||||
|
||||
public void Exit() {
|
||||
}
|
||||
}
|
||||
|
||||
public partial class RR {
|
||||
StateMachine<IState> m_AppStateMachine;
|
||||
|
||||
void InitializeAppStateMachine() {
|
||||
m_AppStateMachine = new StateMachine<IState>();
|
||||
m_AppStateMachine.AddState(m_DIContext.Create<MainMenuState>(m_EngineConfigAsset.appConfig.mainMenuConfig));
|
||||
m_AppStateMachine.AddState(m_DIContext.Create<PlayState>(m_EngineConfigAsset.appConfig.gameConfig));
|
||||
}
|
||||
|
||||
void OpenMainMenu() {
|
||||
m_AppStateMachine.TransitionTo<MainMenuState>();
|
||||
}
|
||||
|
||||
void StartGame() {
|
||||
m_AppStateMachine.TransitionTo<PlayState>();
|
||||
}
|
||||
|
||||
bool IsMainMenuOpen() => m_AppStateMachine.IsStateActive<MainMenuState>();
|
||||
bool IsPlaying() => m_AppStateMachine.IsStateActive<PlayState>();
|
||||
}
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d7b1b5cbd7e04f38ba5f61a04709336b
|
||||
timeCreated: 1743213081
|
||||
14
Runtime/Engine/Code/RR.Game.cs
Normal file
14
Runtime/Engine/Code/RR.Game.cs
Normal file
@@ -0,0 +1,14 @@
|
||||
using System;
|
||||
using RebootKit.Engine.Services.Game;
|
||||
|
||||
namespace RebootKit.Engine {
|
||||
public partial class RR {
|
||||
public static void StartGameMode(GameModeAsset gameMode) {
|
||||
if (gameMode == null) {
|
||||
throw new ArgumentNullException(nameof(gameMode));
|
||||
}
|
||||
|
||||
s_Shared.m_GameService.Start(gameMode);
|
||||
}
|
||||
}
|
||||
}
|
||||
3
Runtime/Engine/Code/RR.Game.cs.meta
Normal file
3
Runtime/Engine/Code/RR.Game.cs.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c614fae80bc84ae8b7f3ee034a42f074
|
||||
timeCreated: 1743437396
|
||||
@@ -1,14 +1,13 @@
|
||||
using System;
|
||||
using System.Threading;
|
||||
using Cysharp.Threading.Tasks;
|
||||
using R3;
|
||||
using RebootKit.Engine.Foundation;
|
||||
using RebootKit.Engine.Services.Console;
|
||||
using RebootKit.Engine.Services.Game;
|
||||
using RebootKit.Engine.Services.Input;
|
||||
using RebootKit.Engine.Services.Simulation;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Assertions;
|
||||
using UnityEngine.Events;
|
||||
using Logger = RebootKit.Engine.Foundation.Logger;
|
||||
|
||||
namespace RebootKit.Engine {
|
||||
@@ -17,42 +16,49 @@ namespace RebootKit.Engine {
|
||||
|
||||
static readonly Logger s_logger = new("RR");
|
||||
|
||||
ConsoleService m_ConsoleService;
|
||||
DIContext m_DIContext;
|
||||
|
||||
ConsoleService m_ConsoleService;
|
||||
|
||||
EngineConfigAsset m_EngineConfigAsset;
|
||||
GameService m_GameService;
|
||||
InputService m_InputService;
|
||||
WorldService m_WorldService;
|
||||
|
||||
readonly UnityEvent<string, CVarValue> m_CVarChanged = new();
|
||||
DisposableBag m_DisposableBag;
|
||||
|
||||
public RR() {
|
||||
m_DisposableBag = new DisposableBag();
|
||||
|
||||
m_DIContext = new DIContext();
|
||||
// m_DIContext.AddInjector(new CVarFieldInjector());
|
||||
}
|
||||
|
||||
public void Dispose() {
|
||||
m_CVarChanged.RemoveAllListeners();
|
||||
s_logger.Info("Shutting down");
|
||||
m_DisposableBag.Dispose();
|
||||
}
|
||||
|
||||
public async UniTask Init(EngineConfigAsset configAsset, CancellationToken cancellationToken) {
|
||||
Assert.IsNotNull(configAsset, "Config asset is required");
|
||||
|
||||
s_logger.Info("Waking up");
|
||||
|
||||
s_logger.Info("Initializing");
|
||||
m_EngineConfigAsset = configAsset;
|
||||
|
||||
m_DIContext = new DIContext();
|
||||
m_DIContext.AddInjector(new CVarFieldInjector());
|
||||
|
||||
CreateCoreServices();
|
||||
InitializeAppStateMachine();
|
||||
CreateServices();
|
||||
|
||||
await UniTask.Yield(cancellationToken);
|
||||
}
|
||||
|
||||
public void Run() {
|
||||
OpenMainMenu();
|
||||
StartGameMode(m_EngineConfigAsset.appConfig.gameConfig.defaultGameMode);
|
||||
}
|
||||
|
||||
TService CreateService<TService>(ServiceAsset<TService> asset) where TService : class, IService {
|
||||
TService service = asset.Create(m_DIContext);
|
||||
m_DIContext.Bind(service);
|
||||
m_DisposableBag.Add(service);
|
||||
return service;
|
||||
}
|
||||
|
||||
@@ -64,5 +70,11 @@ namespace RebootKit.Engine {
|
||||
m_WorldService = CreateService(m_EngineConfigAsset.coreServices.worldService);
|
||||
m_GameService = CreateService(m_EngineConfigAsset.coreServices.gameService);
|
||||
}
|
||||
|
||||
void CreateServices() {
|
||||
foreach (ServiceAsset serviceAsset in m_EngineConfigAsset.services) {
|
||||
CreateService(serviceAsset);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace RebootKit.Engine.Services.Console {
|
||||
[CreateAssetMenu(menuName = RConsts.k_AddComponentMenu + "cvar", fileName = "cvar")]
|
||||
public class CVarAsset : ScriptableObject {
|
||||
[SerializeField] CVar m_CVar;
|
||||
|
||||
public CVar Create(string cvarName = null) {
|
||||
CVar cvar = new(m_CVar);
|
||||
|
||||
if (cvarName != null) cvar.name = cvarName;
|
||||
|
||||
return cvar;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 443a66c3a441450d96d222872a567df0
|
||||
timeCreated: 1741639598
|
||||
@@ -1,57 +0,0 @@
|
||||
using System;
|
||||
using System.Reflection;
|
||||
using RebootKit.Engine.Foundation;
|
||||
|
||||
namespace RebootKit.Engine.Services.Console {
|
||||
[AttributeUsage(AttributeTargets.Field)]
|
||||
public class CVarAttribute : Attribute {
|
||||
public CVarAttribute(string name, float defaultValue) {
|
||||
Name = name;
|
||||
Value = new CVarValue(defaultValue);
|
||||
}
|
||||
|
||||
public CVarAttribute(string name, double defaultValue) {
|
||||
Name = name;
|
||||
Value = new CVarValue(defaultValue);
|
||||
}
|
||||
|
||||
public CVarAttribute(string name, string defaultValue) {
|
||||
Name = name;
|
||||
Value = new CVarValue(defaultValue);
|
||||
}
|
||||
|
||||
public CVarAttribute(string name, int defaultValue) {
|
||||
Name = name;
|
||||
Value = new CVarValue(defaultValue);
|
||||
}
|
||||
|
||||
public string Name { get; }
|
||||
public CVarValue Value { get; }
|
||||
}
|
||||
|
||||
public class CVarFieldInjector : DIContext.IFieldInjector {
|
||||
static readonly Logger s_logger = new(nameof(CVarFieldInjector));
|
||||
|
||||
public bool Inject(FieldInfo field, object target, DIContext context) {
|
||||
if (!Attribute.IsDefined(field, typeof(CVarAttribute))) return false;
|
||||
|
||||
ConsoleService console = context.Resolve<ConsoleService>();
|
||||
if (console == null) {
|
||||
s_logger.Error($"Cannot inject field because cannot resolve `{nameof(ConsoleService)}`");
|
||||
return false;
|
||||
}
|
||||
|
||||
CVarAttribute cvarAttribute = field.GetCustomAttribute<CVarAttribute>();
|
||||
CVar cvar = console.GetCVar(cvarAttribute.Name);
|
||||
|
||||
if (cvar == null) {
|
||||
cvar = new CVar(cvarAttribute.Name, cvarAttribute.Value);
|
||||
console.Replace(cvar);
|
||||
}
|
||||
|
||||
field.SetValue(target, cvar);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,10 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using RebootKit.Engine.Foundation;
|
||||
using UnityEngine;
|
||||
using Logger = RebootKit.Engine.Foundation.Logger;
|
||||
|
||||
namespace RebootKit.Engine.Services.Console {
|
||||
@@ -21,104 +23,136 @@ namespace RebootKit.Engine.Services.Console {
|
||||
}
|
||||
}
|
||||
|
||||
public class ConsoleService : IService {
|
||||
static readonly Logger _logger = new(nameof(ConsoleService));
|
||||
public class PrintCVarsCommand : IConsoleCommand {
|
||||
public string Name { get; } = "print_cvars";
|
||||
public string Description { get; } = "Prints all cvars and their values.";
|
||||
|
||||
readonly List<IConsoleCommand> _commands = new();
|
||||
readonly List<CVar> _cvars = new();
|
||||
public void Execute(string[] args) {
|
||||
RR.Console.PrintCVars();
|
||||
}
|
||||
}
|
||||
|
||||
public class ConsoleService : IService {
|
||||
static readonly Logger s_logger = new(nameof(ConsoleService));
|
||||
|
||||
readonly List<IConsoleCommand> m_ConsoleCommands = new();
|
||||
|
||||
FileStream m_LogFileStream;
|
||||
TextWriter m_LogFileWriter;
|
||||
|
||||
bool m_IsLoading;
|
||||
|
||||
public ConsoleService() {
|
||||
_logger.Info("Waking up");
|
||||
ConfigVar.StateChanged += OnCVarStateChanged;
|
||||
|
||||
m_LogFileStream = new FileStream(Application.persistentDataPath + "/rr_logs.txt", FileMode.Append, FileAccess.Write);
|
||||
m_LogFileWriter = new StreamWriter(m_LogFileStream);
|
||||
|
||||
m_LogFileWriter.WriteLine("============================");
|
||||
m_LogFileWriter.WriteLine("Starting new log");
|
||||
m_LogFileWriter.WriteLine($" > Game: {Application.productName}");
|
||||
m_LogFileWriter.WriteLine($" > Version: {Application.version}");
|
||||
m_LogFileWriter.WriteLine($" > Date: {DateTime.Now}");
|
||||
m_LogFileWriter.WriteLine("============================");
|
||||
m_LogFileWriter.Flush();
|
||||
|
||||
s_logger.Info("Waking up");
|
||||
|
||||
Load();
|
||||
|
||||
RegisterCommand(new PrintCVarsCommand());
|
||||
RegisterCommand(new HelpCommand());
|
||||
}
|
||||
|
||||
public void Dispose() {
|
||||
s_logger.Info("Shutting down");
|
||||
|
||||
ConfigVar.StateChanged -= OnCVarStateChanged;
|
||||
|
||||
m_LogFileWriter.Dispose();
|
||||
m_LogFileStream.Dispose();
|
||||
|
||||
m_LogFileStream = null;
|
||||
m_LogFileWriter = null;
|
||||
}
|
||||
|
||||
void OnCVarStateChanged(ConfigVar cvar) {
|
||||
if (m_IsLoading) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!cvar.flags.HasFlag(CVarFlags.ReadOnly)) {
|
||||
Save();
|
||||
}
|
||||
}
|
||||
|
||||
public event Action<string> OnOutputMessage = _ => { };
|
||||
|
||||
public void WriteToOutput(string message) {
|
||||
if (m_LogFileWriter != null) {
|
||||
m_LogFileWriter.WriteLine(message);
|
||||
m_LogFileWriter.Flush();
|
||||
}
|
||||
|
||||
OnOutputMessage?.Invoke(message);
|
||||
}
|
||||
|
||||
public bool CVarExists(string name) {
|
||||
foreach (CVar cvar in _cvars)
|
||||
if (cvar.name.Equals(name))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public CVar GetCVar(string name) {
|
||||
foreach (CVar cvar in _cvars)
|
||||
if (cvar.name.Equals(name))
|
||||
return cvar;
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public CVar ReplaceOrDefault(CVar cvar) {
|
||||
CVar foundCVar = GetCVar(cvar.name);
|
||||
if (foundCVar != null) return foundCVar;
|
||||
|
||||
_cvars.Add(cvar);
|
||||
return cvar;
|
||||
}
|
||||
|
||||
public void Replace(CVar cvar) {
|
||||
CVar foundCVar = GetCVar(cvar.name);
|
||||
if (foundCVar != null) _cvars.Remove(foundCVar);
|
||||
|
||||
_cvars.Add(cvar);
|
||||
}
|
||||
|
||||
string[] ParseCommandInputArguments(string text) {
|
||||
if (text.Length == 0) return Array.Empty<string>();
|
||||
if (text.Length == 0) {
|
||||
return Array.Empty<string>();
|
||||
}
|
||||
|
||||
return new[] {text};
|
||||
}
|
||||
|
||||
public void Execute(string input) {
|
||||
if (input.Length == 0) return;
|
||||
if (input.Length == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
string commandName = input;
|
||||
if (input.IndexOf(' ') != -1) commandName = input.Substring(0, input.IndexOf(' '));
|
||||
if (input.IndexOf(' ') != -1) {
|
||||
commandName = input.Substring(0, input.IndexOf(' '));
|
||||
}
|
||||
|
||||
string[] arguments = ParseCommandInputArguments(input.Substring(commandName.Length));
|
||||
|
||||
foreach (IConsoleCommand command in _commands)
|
||||
foreach (IConsoleCommand command in m_ConsoleCommands) {
|
||||
if (command.Name.Equals(commandName)) {
|
||||
command.Execute(arguments);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
foreach (CVar cvar in _cvars)
|
||||
foreach (ConfigVar cvar in ConfigVarsContainer.All()) {
|
||||
if (cvar.name.Equals(commandName)) {
|
||||
if (arguments.Length == 1) cvar.ParseFromString(arguments[0]);
|
||||
if (arguments.Length == 1) {
|
||||
cvar.ParseFromString(arguments[0]);
|
||||
}
|
||||
|
||||
WriteToOutput($"<b>{cvar.name}</b> - {cvar}\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
WriteToOutput($"ERROR: Command/CVar `{commandName}` not found.");
|
||||
}
|
||||
|
||||
public void RegisterCommand(IConsoleCommand command) {
|
||||
if (_commands.Any(t => t.Name.Equals(command.Name))) {
|
||||
_logger.Error($"`{command.Name}` command is already registered");
|
||||
if (m_ConsoleCommands.Any(t => t.Name.Equals(command.Name))) {
|
||||
s_logger.Error($"`{command.Name}` command is already registered");
|
||||
return;
|
||||
}
|
||||
|
||||
_commands.Add(command);
|
||||
_logger.Info($"Registered command: {command.Name}");
|
||||
m_ConsoleCommands.Add(command);
|
||||
s_logger.Info($"Registered command: {command.Name}");
|
||||
}
|
||||
|
||||
public void PrintHelp() {
|
||||
StringBuilder message = new();
|
||||
|
||||
message.AppendLine("Available commands:");
|
||||
foreach (IConsoleCommand command in _commands) {
|
||||
foreach (IConsoleCommand command in m_ConsoleCommands) {
|
||||
message.Append(" ");
|
||||
message.Append(command.Name);
|
||||
message.Append(" - ");
|
||||
@@ -127,7 +161,7 @@ namespace RebootKit.Engine.Services.Console {
|
||||
}
|
||||
|
||||
message.AppendLine("Available cvars:");
|
||||
foreach (CVar cvar in _cvars) {
|
||||
foreach (ConfigVar cvar in ConfigVarsContainer.All()) {
|
||||
message.Append(" ");
|
||||
message.Append(cvar.name);
|
||||
message.Append(" - ");
|
||||
@@ -137,5 +171,60 @@ namespace RebootKit.Engine.Services.Console {
|
||||
|
||||
WriteToOutput(message.ToString());
|
||||
}
|
||||
|
||||
public void PrintCVars() {
|
||||
StringBuilder message = new();
|
||||
|
||||
foreach (ConfigVar cvar in ConfigVarsContainer.All()) {
|
||||
message.AppendLine($"{cvar.name} - {cvar}");
|
||||
}
|
||||
|
||||
WriteToOutput(message.ToString());
|
||||
}
|
||||
|
||||
void Save() {
|
||||
string path = Application.persistentDataPath + "/" + RConsts.k_CVarsFilename;
|
||||
|
||||
s_logger.Info("Saving cvars to file: " + path);
|
||||
|
||||
StringBuilder sb = new();
|
||||
|
||||
foreach (ConfigVar cvar in ConfigVarsContainer.All()) {
|
||||
if (!cvar.flags.HasFlag(CVarFlags.ReadOnly)) {
|
||||
sb.AppendFormat("{0} {1}\n", cvar.name, cvar);
|
||||
}
|
||||
}
|
||||
|
||||
File.WriteAllText(path, sb.ToString());
|
||||
}
|
||||
|
||||
void Load() {
|
||||
string path = Application.persistentDataPath + "/" + RConsts.k_CVarsFilename;
|
||||
if (!File.Exists(path)) {
|
||||
s_logger.Info("CVar file not found, skipping load");
|
||||
return;
|
||||
}
|
||||
|
||||
m_IsLoading = true;
|
||||
ExecuteFile(path);
|
||||
m_IsLoading = false;
|
||||
}
|
||||
|
||||
bool ExecuteFile(string path) {
|
||||
if (!File.Exists(path)) {
|
||||
s_logger.Error($"Cannot load file '{path}', file not found");
|
||||
return false;
|
||||
}
|
||||
|
||||
s_logger.Info($"Executing file '{path}'");
|
||||
|
||||
string[] lines = File.ReadAllLines(path);
|
||||
foreach (string line in lines) {
|
||||
WriteToOutput(path + " > " + line);
|
||||
Execute(line);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,30 +1,15 @@
|
||||
using RebootKit.Engine.Foundation;
|
||||
using UnityEngine;
|
||||
using Logger = RebootKit.Engine.Foundation.Logger;
|
||||
|
||||
namespace RebootKit.Engine.Services.Console {
|
||||
[CreateAssetMenu(menuName = RConsts.k_ServiceAssetMenu + "Console")]
|
||||
public class ConsoleServiceAsset : ServiceAsset<ConsoleService> {
|
||||
[SerializeField] CVar[] _initialCVars;
|
||||
|
||||
[SerializeField] bool _loadCVarsFromResources = true;
|
||||
static readonly Logger s_logger = new(nameof(ConsoleServiceAsset));
|
||||
|
||||
public override ConsoleService Create(DIContext context) {
|
||||
ConsoleService service = new();
|
||||
context.Inject(service);
|
||||
|
||||
foreach (CVar cvar in _initialCVars) {
|
||||
service.Replace(cvar);
|
||||
cvar.Reset();
|
||||
}
|
||||
|
||||
if (_loadCVarsFromResources) {
|
||||
CVarAsset[] cvarsAssets = Resources.LoadAll<CVarAsset>("cvar");
|
||||
foreach (CVarAsset cvarAsset in cvarsAssets) {
|
||||
CVar cvar = cvarAsset.Create();
|
||||
service.Replace(cvar);
|
||||
}
|
||||
}
|
||||
|
||||
return service;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,6 +57,7 @@ namespace RebootKit.Engine.Services.ConsoleUI {
|
||||
}
|
||||
|
||||
void OnUserInput(string input) {
|
||||
RR.Console.WriteToOutput("> " + input);
|
||||
RR.Console.Execute(input);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,28 +1,39 @@
|
||||
using System.Threading;
|
||||
using Cysharp.Threading.Tasks;
|
||||
using System;
|
||||
using RebootKit.Engine.UI;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
namespace RebootKit.Engine.Services.Development {
|
||||
public class DebugOverlayView : MonoBehaviour, IView {
|
||||
[SerializeField] UIDocument m_Document;
|
||||
|
||||
void Start() {
|
||||
}
|
||||
|
||||
public async UniTask Show(CancellationToken cancellationToken) {
|
||||
gameObject.SetActive(true);
|
||||
await UniTask.Yield(cancellationToken);
|
||||
}
|
||||
|
||||
public async UniTask Hide(CancellationToken cancellationToken) {
|
||||
gameObject.SetActive(false);
|
||||
await UniTask.Yield(cancellationToken);
|
||||
}
|
||||
public class DebugOverlayView : UIDocumentView {
|
||||
const string k_DebugLabelClassName = "rr__debug-label";
|
||||
|
||||
void SetOverlayModeChanged(int mode) {
|
||||
VisualElement m_RootElement;
|
||||
|
||||
Label m_FPSLabel;
|
||||
|
||||
void Update() {
|
||||
if (m_RootElement == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_FPSLabel.text = $"fps: {Mathf.RoundToInt(1f / Time.deltaTime)} | dt: {Time.deltaTime:F4}ms | runtime: {Time.time:F4}s";
|
||||
}
|
||||
|
||||
public override VisualElement Build() {
|
||||
m_RootElement = new VisualElement();
|
||||
|
||||
CreateLabel($"Toggle Overlay [F3] | RebootKit | game: {Application.productName}, version: {Application.version}");
|
||||
m_FPSLabel = CreateLabel($"FPS: {Application.targetFrameRate}");
|
||||
|
||||
return m_RootElement;
|
||||
}
|
||||
|
||||
Label CreateLabel(string text) {
|
||||
Label label = (Label)LabelBuilder.New(text).Build();
|
||||
label.AddToClassList(k_DebugLabelClassName);
|
||||
|
||||
m_RootElement.Add(label);
|
||||
return label;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,24 +1,23 @@
|
||||
using System;
|
||||
using Cysharp.Threading.Tasks;
|
||||
using RebootKit.Engine.Foundation;
|
||||
using RebootKit.Engine.Services.Console;
|
||||
using UnityEngine;
|
||||
using UnityEngine.InputSystem;
|
||||
|
||||
namespace RebootKit.Engine.Services.Development {
|
||||
static class DebugCVars {
|
||||
public const string k_OverlayMode = "debug.mode";
|
||||
static class DebugConfig {
|
||||
[ConfigVar("debug.overlay", 1, "Controls overlay visibility. 0 - hidden, 1 - visible")] public static ConfigVar s_OverlayMode;
|
||||
}
|
||||
|
||||
public class DevToolsService : ServiceMonoBehaviour {
|
||||
[SerializeField] DebugOverlayView m_DebugOverlayView;
|
||||
|
||||
[CVar(DebugCVars.k_OverlayMode, 1)] CVar m_OverlayMode;
|
||||
|
||||
IDisposable m_CVarChangedListener;
|
||||
|
||||
void OnEnable() {
|
||||
m_CVarChangedListener = RR.CVarChanged.Listen(OnCVarChanged);
|
||||
OnOverlayModeChanged(m_OverlayMode.IndexValue);
|
||||
void Start() {
|
||||
ConfigVar.StateChanged += OnCVarChanged;
|
||||
// OnOverlayModeChanged(m_OverlayMode.IndexValue);
|
||||
}
|
||||
|
||||
void OnDisable() {
|
||||
@@ -26,20 +25,26 @@ namespace RebootKit.Engine.Services.Development {
|
||||
}
|
||||
|
||||
public override void Dispose() {
|
||||
m_CVarChangedListener.Dispose();
|
||||
ConfigVar.StateChanged -= OnCVarChanged;
|
||||
}
|
||||
|
||||
void Update() {
|
||||
if (InputSystem.GetDevice<Keyboard>().f3Key.wasReleasedThisFrame) {
|
||||
DebugConfig.s_OverlayMode.Set(DebugConfig.s_OverlayMode.IndexValue == 1 ? 0 : 1);
|
||||
}
|
||||
}
|
||||
|
||||
void OnOverlayModeChanged(int mode) {
|
||||
if (mode == 1) {
|
||||
m_DebugOverlayView.Show(destroyCancellationToken).Forget();
|
||||
m_DebugOverlayView.gameObject.SetActive(true);
|
||||
} else {
|
||||
m_DebugOverlayView.Hide(destroyCancellationToken).Forget();
|
||||
m_DebugOverlayView.gameObject.SetActive(false);
|
||||
}
|
||||
}
|
||||
|
||||
void OnCVarChanged(string cvarName, CVarValue value) {
|
||||
if (cvarName == DebugCVars.k_OverlayMode) {
|
||||
OnOverlayModeChanged((int)value.numberValue);
|
||||
void OnCVarChanged(ConfigVar cvar) {
|
||||
if (cvar == DebugConfig.s_OverlayMode) {
|
||||
OnOverlayModeChanged(cvar.IndexValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,78 +0,0 @@
|
||||
using System;
|
||||
using System.Threading;
|
||||
using RebootKit.Engine.Foundation;
|
||||
using UnityEngine;
|
||||
|
||||
namespace RebootKit.Engine.Services.Game {
|
||||
public abstract class GameModeAsset : FactoryAsset<GameMode> {
|
||||
[field: SerializeField]
|
||||
public GameMode.Config GameModeConfig { get; private set; }
|
||||
|
||||
public override GameMode Create(DIContext context) {
|
||||
GameMode gameMode = new(GameModeConfig);
|
||||
context.Inject(gameMode);
|
||||
ConfigureGameMode(gameMode);
|
||||
return gameMode;
|
||||
}
|
||||
|
||||
public abstract void ConfigureGameMode(GameMode gameMode);
|
||||
}
|
||||
|
||||
public class GameMode : IDisposable {
|
||||
[Serializable]
|
||||
public class Config {
|
||||
public ControllerAsset[] controllers;
|
||||
}
|
||||
|
||||
readonly Config m_Config;
|
||||
readonly ControllersManager<IController> m_Controllers;
|
||||
|
||||
readonly CancellationTokenSource m_DestroyCancellationTokenSource;
|
||||
|
||||
[Inject] DIContext m_DIContext;
|
||||
bool m_IsRunning;
|
||||
|
||||
public GameMode(Config config) {
|
||||
m_Config = config;
|
||||
m_IsRunning = false;
|
||||
|
||||
m_DestroyCancellationTokenSource = new CancellationTokenSource();
|
||||
m_Controllers = new ControllersManager<IController>(m_DestroyCancellationTokenSource.Token);
|
||||
}
|
||||
|
||||
public void Dispose() {
|
||||
m_DestroyCancellationTokenSource.Cancel();
|
||||
m_Controllers.Dispose();
|
||||
}
|
||||
|
||||
public async Awaitable<bool> Start(CancellationToken cancellationToken) {
|
||||
m_Controllers.Add(m_Config.controllers, m_DIContext);
|
||||
await m_Controllers.Start(cancellationToken);
|
||||
|
||||
m_IsRunning = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
public void Stop() {
|
||||
m_IsRunning = false;
|
||||
|
||||
m_Controllers.Stop();
|
||||
}
|
||||
|
||||
public void Tick() {
|
||||
m_Controllers.Tick();
|
||||
}
|
||||
|
||||
public void AddController(IController controller) {
|
||||
m_Controllers.Add(controller);
|
||||
}
|
||||
|
||||
public T FindController<T>() where T : class, IController {
|
||||
if (m_Controllers.TryFind<T>(out T controller)) {
|
||||
return controller;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,2 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 73f15dc489209cc4a9ff6963e0fbd2c6
|
||||
@@ -1,47 +1,57 @@
|
||||
using System.Threading;
|
||||
using Cysharp.Threading.Tasks;
|
||||
using R3;
|
||||
using RebootKit.Engine.Foundation;
|
||||
using UnityEngine.Assertions;
|
||||
|
||||
namespace RebootKit.Engine.Services.Game {
|
||||
public class GameService : IService {
|
||||
static readonly Logger s_logger = new(nameof(GameService));
|
||||
|
||||
[Inject] DIContext m_DIContext;
|
||||
GameMode m_GameMode;
|
||||
|
||||
GameModeAsset m_GameModeAsset;
|
||||
bool m_isRunning;
|
||||
|
||||
CancellationTokenSource m_DestroyCancellationTokenSource = new();
|
||||
DisposableBag m_ActiveGameModeDisposableBag;
|
||||
IGameMode m_ActiveGameMode;
|
||||
|
||||
public void Dispose() {
|
||||
m_isRunning = false;
|
||||
m_GameMode.Dispose();
|
||||
m_DestroyCancellationTokenSource.Cancel();
|
||||
m_DestroyCancellationTokenSource.Dispose();
|
||||
m_ActiveGameModeDisposableBag.Dispose();
|
||||
}
|
||||
|
||||
public async UniTask Start(GameModeAsset asset, CancellationToken cancellationToken) {
|
||||
Assert.IsNotNull(asset);
|
||||
|
||||
m_GameMode = asset.Create(m_DIContext);
|
||||
await m_GameMode.Start(cancellationToken);
|
||||
|
||||
Run(cancellationToken).Forget();
|
||||
}
|
||||
|
||||
async UniTask Run(CancellationToken cancellationToken) {
|
||||
if (m_GameMode == null) {
|
||||
s_logger.Error("Trying to run game without game mode");
|
||||
public void Start(GameModeAsset asset) {
|
||||
if (m_ActiveGameMode != null) {
|
||||
s_logger.Warning("Game is already running");
|
||||
return;
|
||||
}
|
||||
|
||||
m_isRunning = true;
|
||||
while (m_isRunning) {
|
||||
await UniTask.Yield(PlayerLoopTiming.Update, cancellationToken);
|
||||
m_GameMode.Tick();
|
||||
Stop();
|
||||
|
||||
if (cancellationToken.IsCancellationRequested) {
|
||||
return;
|
||||
}
|
||||
m_ActiveGameModeDisposableBag = new DisposableBag();
|
||||
m_ActiveGameMode = asset.Create(m_DIContext);
|
||||
m_ActiveGameModeDisposableBag.Add(m_ActiveGameMode);
|
||||
|
||||
InitializeGameModeAsync().Forget();
|
||||
}
|
||||
|
||||
async UniTask InitializeGameModeAsync() {
|
||||
await m_ActiveGameMode.OnInit(m_DestroyCancellationTokenSource.Token);
|
||||
|
||||
m_ActiveGameMode.OnStart();
|
||||
Observable.EveryUpdate().Subscribe(_ => { m_ActiveGameMode?.OnTick(); }).AddTo(ref m_ActiveGameModeDisposableBag);
|
||||
}
|
||||
|
||||
public void Stop() {
|
||||
if (m_ActiveGameMode == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_ActiveGameMode.OnStop();
|
||||
m_ActiveGameMode = null;
|
||||
|
||||
m_ActiveGameModeDisposableBag.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
18
Runtime/Engine/Code/Services/Game/IGameMode.cs
Normal file
18
Runtime/Engine/Code/Services/Game/IGameMode.cs
Normal file
@@ -0,0 +1,18 @@
|
||||
using System;
|
||||
using System.Threading;
|
||||
using Cysharp.Threading.Tasks;
|
||||
using RebootKit.Engine.Foundation;
|
||||
|
||||
namespace RebootKit.Engine.Services.Game {
|
||||
public interface IGameMode : IDisposable {
|
||||
UniTask OnInit(CancellationToken cancellationToken);
|
||||
|
||||
void OnStart();
|
||||
void OnStop();
|
||||
|
||||
void OnTick();
|
||||
}
|
||||
|
||||
public abstract class GameModeAsset : FactoryAsset<IGameMode> {
|
||||
}
|
||||
}
|
||||
3
Runtime/Engine/Code/Services/Game/IGameMode.cs.meta
Normal file
3
Runtime/Engine/Code/Services/Game/IGameMode.cs.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 562c4ff92afe4949b468003a0e997522
|
||||
timeCreated: 1743456239
|
||||
5
Runtime/Engine/Code/Services/Game/Player.cs
Normal file
5
Runtime/Engine/Code/Services/Game/Player.cs
Normal file
@@ -0,0 +1,5 @@
|
||||
namespace RebootKit.Engine.Services.Game {
|
||||
public class Player {
|
||||
|
||||
}
|
||||
}
|
||||
3
Runtime/Engine/Code/Services/Game/Player.cs.meta
Normal file
3
Runtime/Engine/Code/Services/Game/Player.cs.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: be94d631484b4bd2a2c9825290b74b36
|
||||
timeCreated: 1744413325
|
||||
@@ -1,6 +1,66 @@
|
||||
using UnityEngine;
|
||||
using System;
|
||||
using System.Threading;
|
||||
using Cysharp.Threading.Tasks;
|
||||
using RebootKit.Engine.Foundation;
|
||||
using UnityEngine;
|
||||
|
||||
namespace RebootKit.Engine.Services.Simulation {
|
||||
public class Actor : MonoBehaviour {
|
||||
[field: SerializeField]
|
||||
public SerializableGuid ActorGuid { get; private set; } = SerializableGuid.New();
|
||||
|
||||
public bool IsInitialized { get; private set; }
|
||||
|
||||
bool m_Simulate;
|
||||
public bool Simulate {
|
||||
get => m_Simulate;
|
||||
|
||||
set {
|
||||
if (m_Simulate == value) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_Simulate = value;
|
||||
|
||||
if (!IsInitialized) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_Simulate) {
|
||||
OnBeginPlay();
|
||||
} else {
|
||||
OnEndPlay();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async void Start() {
|
||||
IsInitialized = false;
|
||||
await InitAsync(destroyCancellationToken);
|
||||
IsInitialized = true;
|
||||
|
||||
if (Simulate) {
|
||||
OnBeginPlay();
|
||||
}
|
||||
}
|
||||
|
||||
void Update() {
|
||||
if (m_Simulate && IsInitialized) {
|
||||
OnTick();
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual async UniTask InitAsync(CancellationToken cancellationToken) {
|
||||
await UniTask.Yield(cancellationToken);
|
||||
}
|
||||
|
||||
public virtual void OnBeginPlay() {
|
||||
}
|
||||
|
||||
public virtual void OnEndPlay() {
|
||||
}
|
||||
|
||||
public virtual void OnTick() {
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
using RebootKit.Engine.Extensions;
|
||||
using System;
|
||||
using RebootKit.Engine.Extensions;
|
||||
using UnityEngine;
|
||||
|
||||
namespace RebootKit.Engine.Services.Simulation {
|
||||
@@ -14,12 +15,15 @@ namespace RebootKit.Engine.Services.Simulation {
|
||||
|
||||
public Rigidbody Current { get; private set; }
|
||||
|
||||
[field: SerializeField]
|
||||
public Vector3 TargetWorldPosition { get; set; }
|
||||
|
||||
public bool IsDragging => Current != null;
|
||||
|
||||
public void FixedUpdate() {
|
||||
if (Current.OrNull() == null) return;
|
||||
if (Current.OrNull() == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
Vector3 direction = (TargetWorldPosition - Current.position).normalized;
|
||||
float distance = Vector3.Distance(TargetWorldPosition, Current.position);
|
||||
@@ -32,13 +36,22 @@ namespace RebootKit.Engine.Services.Simulation {
|
||||
Current.angularVelocity = Vector3.MoveTowards(Current.angularVelocity, Vector3.zero, Time.fixedDeltaTime * AngularSlowdown);
|
||||
}
|
||||
|
||||
void OnDrawGizmosSelected() {
|
||||
Gizmos.color = Color.green;
|
||||
Gizmos.DrawSphere(TargetWorldPosition, 0.1f);
|
||||
}
|
||||
|
||||
public void Grab(Rigidbody physicsObject) {
|
||||
Drop();
|
||||
|
||||
Current = physicsObject;
|
||||
Current.linearDamping = 5.0f;
|
||||
}
|
||||
|
||||
public void Drop() {
|
||||
if (Current == null) return;
|
||||
if (Current == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
Current.linearDamping = 0.0f;
|
||||
Current = null;
|
||||
|
||||
@@ -20,9 +20,17 @@ namespace RebootKit.Engine.Services.Simulation {
|
||||
public async UniTask Load(WorldConfig worldConfig) {
|
||||
m_Config = worldConfig;
|
||||
|
||||
AsyncOperationHandle<SceneInstance> handle = worldConfig.mainScene.LoadSceneAsync(LoadSceneMode.Additive);
|
||||
AsyncOperationHandle<SceneInstance> handle = worldConfig.mainScene.LoadSceneAsync(LoadSceneMode.Additive, false);
|
||||
await handle.ToUniTask();
|
||||
|
||||
await handle.Result.ActivateAsync();
|
||||
SceneManager.SetActiveScene(handle.Result.Scene);
|
||||
|
||||
foreach (GameObject root in handle.Result.Scene.GetRootGameObjects()) {
|
||||
foreach (Actor actor in root.GetComponentsInChildren<Actor>()) {
|
||||
RegisterActor(actor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public async UniTask<TActor> SpawnActor<TActor>(AssetReferenceT<GameObject> asset, CancellationToken cancellationToken) where TActor : Actor {
|
||||
@@ -32,15 +40,16 @@ namespace RebootKit.Engine.Services.Simulation {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (gameObject.TryGetComponent(out TActor actor)) return actor;
|
||||
if (gameObject.TryGetComponent(out TActor actor)) {
|
||||
return actor;
|
||||
}
|
||||
|
||||
asset.ReleaseInstance(gameObject);
|
||||
return null;
|
||||
}
|
||||
|
||||
public async UniTask RegisterActor(Actor actor) {
|
||||
public void RegisterActor(Actor actor) {
|
||||
m_Actors.Add(actor);
|
||||
await UniTask.Yield();
|
||||
}
|
||||
|
||||
public void KillActor(Actor actor) {
|
||||
@@ -48,7 +57,9 @@ namespace RebootKit.Engine.Services.Simulation {
|
||||
}
|
||||
|
||||
public void KillAllActors() {
|
||||
foreach (Actor actor in m_Actors) Addressables.ReleaseInstance(actor.gameObject);
|
||||
foreach (Actor actor in m_Actors) {
|
||||
Addressables.ReleaseInstance(actor.gameObject);
|
||||
}
|
||||
|
||||
m_Actors.Clear();
|
||||
}
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 01849df87c1948778a9155b635cb0a8f
|
||||
timeCreated: 1743252918
|
||||
@@ -1,9 +1,11 @@
|
||||
using System.Threading;
|
||||
using Cysharp.Threading.Tasks;
|
||||
using System;
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
namespace RebootKit.Engine.UI {
|
||||
public interface IView {
|
||||
UniTask Show(CancellationToken cancellationToken);
|
||||
UniTask Hide(CancellationToken cancellationToken);
|
||||
public interface IViewBuilder {
|
||||
VisualElement Build();
|
||||
}
|
||||
|
||||
public interface IView : IDisposable, IViewBuilder {
|
||||
}
|
||||
}
|
||||
@@ -84,7 +84,7 @@ namespace RebootKit.Engine.UI {
|
||||
label.AddToClassList(Classes.k_Label);
|
||||
return label;
|
||||
}
|
||||
|
||||
|
||||
public static LabelBuilder New(string text) => new(text);
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,4 @@
|
||||
using System.Threading;
|
||||
using Cysharp.Threading.Tasks;
|
||||
using UnityEngine;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Profiling;
|
||||
using UnityEngine.UIElements;
|
||||
using Logger = RebootKit.Engine.Foundation.Logger;
|
||||
@@ -12,18 +10,9 @@ namespace RebootKit.Engine.UI {
|
||||
[SerializeField] UIDocument m_Document;
|
||||
|
||||
void OnEnable() {
|
||||
s_logger.Debug("START");
|
||||
Rebuild();
|
||||
}
|
||||
|
||||
public async UniTask Show(CancellationToken cancellationToken) {
|
||||
await UniTask.Yield(cancellationToken);
|
||||
}
|
||||
|
||||
public async UniTask Hide(CancellationToken cancellationToken) {
|
||||
await UniTask.Yield(cancellationToken);
|
||||
}
|
||||
|
||||
protected void Rebuild() {
|
||||
Profiler.BeginSample("UI Tree Build");
|
||||
VisualElement child = Build();
|
||||
@@ -34,5 +23,13 @@ namespace RebootKit.Engine.UI {
|
||||
}
|
||||
|
||||
public abstract VisualElement Build();
|
||||
public void Show() {
|
||||
}
|
||||
|
||||
public void Hide() {
|
||||
}
|
||||
|
||||
public void Dispose() {
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user