fix?
This commit is contained in:
0
Editor/Build.meta
Normal file → Executable file
0
Editor/Build.meta
Normal file → Executable file
142
Editor/Build/BuildVersionBumper.cs
Normal file → Executable file
142
Editor/Build/BuildVersionBumper.cs
Normal file → Executable file
@@ -1,72 +1,72 @@
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
using UnityEditor.Build;
|
||||
using UnityEditor.Build.Reporting;
|
||||
|
||||
namespace RebootKitEditor.Build {
|
||||
class BuildVersionBumper : IPostprocessBuildWithReport {
|
||||
public int callbackOrder => 0;
|
||||
|
||||
public void OnPostprocessBuild(BuildReport report) {
|
||||
VersionUpdater.IncrementPatch();
|
||||
}
|
||||
}
|
||||
|
||||
static class VersionUpdater {
|
||||
public static bool IncrementVersion(int incrementMajor = 0, int incrementMinor = 0, int incrementPatch = 0) {
|
||||
if (TryParseVersion(PlayerSettings.bundleVersion, out int major, out int minor, out int patch)) {
|
||||
major += incrementMajor;
|
||||
minor += incrementMinor;
|
||||
patch += incrementPatch;
|
||||
string newVersion = $"{major}.{minor}.{patch}";
|
||||
|
||||
if (SetVersion(newVersion)) {
|
||||
Debug.Log($"Updated version to: {newVersion}");
|
||||
} else {
|
||||
Debug.LogError($"Failed to update version to: {newVersion}");
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
Debug.LogError($"Failed to parse current version: {PlayerSettings.bundleVersion}");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static bool IncrementMajor() => IncrementVersion(incrementMajor: 1);
|
||||
public static bool IncrementMinor() => IncrementVersion(incrementMinor: 1);
|
||||
public static bool IncrementPatch() => IncrementVersion(incrementPatch: 1);
|
||||
|
||||
static bool SetVersion(string newVersion) {
|
||||
if (!IsValidVersionFormat(newVersion)) {
|
||||
Debug.LogError($"Invalid version format: {newVersion}. Expected format: maj.min.ver");
|
||||
return false;
|
||||
}
|
||||
|
||||
PlayerSettings.bundleVersion = newVersion;
|
||||
Debug.Log($"Application version updated to: {newVersion}");
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool IsValidVersionFormat(string version) {
|
||||
string[] parts = version.Split('.');
|
||||
return parts.Length == 3 && int.TryParse(parts[0], out _) && int.TryParse(parts[1], out _) && int.TryParse(parts[2], out _);
|
||||
}
|
||||
|
||||
static bool TryParseVersion(string version, out int major, out int minor, out int patch) {
|
||||
major = 0;
|
||||
minor = 0;
|
||||
patch = 0;
|
||||
|
||||
string[] parts = version.Split('.');
|
||||
if (parts.Length != 3) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return int.TryParse(parts[0], out major) &&
|
||||
int.TryParse(parts[1], out minor) &&
|
||||
int.TryParse(parts[2], out patch);
|
||||
}
|
||||
}
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
using UnityEditor.Build;
|
||||
using UnityEditor.Build.Reporting;
|
||||
|
||||
namespace RebootKitEditor.Build {
|
||||
class BuildVersionBumper : IPostprocessBuildWithReport {
|
||||
public int callbackOrder => 0;
|
||||
|
||||
public void OnPostprocessBuild(BuildReport report) {
|
||||
VersionUpdater.IncrementPatch();
|
||||
}
|
||||
}
|
||||
|
||||
static class VersionUpdater {
|
||||
public static bool IncrementVersion(int incrementMajor = 0, int incrementMinor = 0, int incrementPatch = 0) {
|
||||
if (TryParseVersion(PlayerSettings.bundleVersion, out int major, out int minor, out int patch)) {
|
||||
major += incrementMajor;
|
||||
minor += incrementMinor;
|
||||
patch += incrementPatch;
|
||||
string newVersion = $"{major}.{minor}.{patch}";
|
||||
|
||||
if (SetVersion(newVersion)) {
|
||||
Debug.Log($"Updated version to: {newVersion}");
|
||||
} else {
|
||||
Debug.LogError($"Failed to update version to: {newVersion}");
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
Debug.LogError($"Failed to parse current version: {PlayerSettings.bundleVersion}");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static bool IncrementMajor() => IncrementVersion(incrementMajor: 1);
|
||||
public static bool IncrementMinor() => IncrementVersion(incrementMinor: 1);
|
||||
public static bool IncrementPatch() => IncrementVersion(incrementPatch: 1);
|
||||
|
||||
static bool SetVersion(string newVersion) {
|
||||
if (!IsValidVersionFormat(newVersion)) {
|
||||
Debug.LogError($"Invalid version format: {newVersion}. Expected format: maj.min.ver");
|
||||
return false;
|
||||
}
|
||||
|
||||
PlayerSettings.bundleVersion = newVersion;
|
||||
Debug.Log($"Application version updated to: {newVersion}");
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool IsValidVersionFormat(string version) {
|
||||
string[] parts = version.Split('.');
|
||||
return parts.Length == 3 && int.TryParse(parts[0], out _) && int.TryParse(parts[1], out _) && int.TryParse(parts[2], out _);
|
||||
}
|
||||
|
||||
static bool TryParseVersion(string version, out int major, out int minor, out int patch) {
|
||||
major = 0;
|
||||
minor = 0;
|
||||
patch = 0;
|
||||
|
||||
string[] parts = version.Split('.');
|
||||
if (parts.Length != 3) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return int.TryParse(parts[0], out major) &&
|
||||
int.TryParse(parts[1], out minor) &&
|
||||
int.TryParse(parts[2], out patch);
|
||||
}
|
||||
}
|
||||
}
|
||||
0
Editor/Build/BuildVersionBumper.cs.meta
Normal file → Executable file
0
Editor/Build/BuildVersionBumper.cs.meta
Normal file → Executable file
74
Editor/CommonEditorActions.cs
Normal file → Executable file
74
Editor/CommonEditorActions.cs
Normal file → Executable file
@@ -1,38 +1,38 @@
|
||||
using System.IO;
|
||||
using RebootKitEditor.Build;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace RebootKitEditor {
|
||||
static class CommonEditorActions {
|
||||
[MenuItem(REditorConsts.k_EditorMenu + "Bump minor version", false, 0)]
|
||||
static void BumpMinorVersion() {
|
||||
if (VersionUpdater.IncrementMinor()) {
|
||||
Debug.Log("Bumped minor version.");
|
||||
} else {
|
||||
Debug.LogError("Failed to bump minor version.");
|
||||
}
|
||||
}
|
||||
|
||||
[MenuItem(REditorConsts.k_EditorMenu + "Open Persistent Data Folder", false, 100)]
|
||||
static void OpenPersistentDataFolder() {
|
||||
string path = Application.persistentDataPath;
|
||||
if (Directory.Exists(path)) {
|
||||
EditorUtility.RevealInFinder(path);
|
||||
} else {
|
||||
Debug.LogError($"Persistent data folder does not exist: {path}");
|
||||
}
|
||||
}
|
||||
|
||||
[MenuItem(REditorConsts.k_EditorMenu + "Remove Persistent Data Folder", false, 1000)]
|
||||
static void RemovePersistentDataFolder() {
|
||||
string path = Application.persistentDataPath;
|
||||
if (Directory.Exists(path)) {
|
||||
Directory.Delete(path, true);
|
||||
Debug.Log($"Removed persistent data folder: {path}");
|
||||
} else {
|
||||
Debug.LogError($"Persistent data folder does not exist: {path}");
|
||||
}
|
||||
}
|
||||
}
|
||||
using System.IO;
|
||||
using RebootKitEditor.Build;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace RebootKitEditor {
|
||||
static class CommonEditorActions {
|
||||
[MenuItem(REditorConsts.k_EditorMenu + "Bump minor version", false, 0)]
|
||||
static void BumpMinorVersion() {
|
||||
if (VersionUpdater.IncrementMinor()) {
|
||||
Debug.Log("Bumped minor version.");
|
||||
} else {
|
||||
Debug.LogError("Failed to bump minor version.");
|
||||
}
|
||||
}
|
||||
|
||||
[MenuItem(REditorConsts.k_EditorMenu + "Open Persistent Data Folder", false, 100)]
|
||||
static void OpenPersistentDataFolder() {
|
||||
string path = Application.persistentDataPath;
|
||||
if (Directory.Exists(path)) {
|
||||
EditorUtility.RevealInFinder(path);
|
||||
} else {
|
||||
Debug.LogError($"Persistent data folder does not exist: {path}");
|
||||
}
|
||||
}
|
||||
|
||||
[MenuItem(REditorConsts.k_EditorMenu + "Remove Persistent Data Folder", false, 1000)]
|
||||
static void RemovePersistentDataFolder() {
|
||||
string path = Application.persistentDataPath;
|
||||
if (Directory.Exists(path)) {
|
||||
Directory.Delete(path, true);
|
||||
Debug.Log($"Removed persistent data folder: {path}");
|
||||
} else {
|
||||
Debug.LogError($"Persistent data folder does not exist: {path}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
0
Editor/CommonEditorActions.cs.meta
Normal file → Executable file
0
Editor/CommonEditorActions.cs.meta
Normal file → Executable file
0
Editor/PropertyDrawers.meta
Normal file → Executable file
0
Editor/PropertyDrawers.meta
Normal file → Executable file
0
Editor/PropertyDrawers/CVarDrawer.cs
Normal file → Executable file
0
Editor/PropertyDrawers/CVarDrawer.cs
Normal file → Executable file
0
Editor/PropertyDrawers/CVarDrawer.cs.meta
Normal file → Executable file
0
Editor/PropertyDrawers/CVarDrawer.cs.meta
Normal file → Executable file
74
Editor/PropertyDrawers/ConstsPropertyDrawer.cs
Normal file → Executable file
74
Editor/PropertyDrawers/ConstsPropertyDrawer.cs
Normal file → Executable file
@@ -1,38 +1,38 @@
|
||||
using RebootKit.Engine.Foundation;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace RebootKitEditor.PropertyDrawers {
|
||||
[CustomPropertyDrawer(typeof(ConstsProperty<>))]
|
||||
public class ConstsPropertyDrawer : PropertyDrawer {
|
||||
const string k_InlineValue = "m_InlineValue";
|
||||
const string k_Asset = "m_Asset";
|
||||
const string k_UseInlineValue = "m_UseInlineValue";
|
||||
|
||||
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) {
|
||||
SerializedProperty useInlineValue = property.FindPropertyRelative(k_UseInlineValue);
|
||||
SerializedProperty inlineValue = property.FindPropertyRelative(k_InlineValue);
|
||||
SerializedProperty asset = property.FindPropertyRelative(k_Asset);
|
||||
|
||||
EditorGUI.BeginProperty(position, label, property);
|
||||
|
||||
GUILayout.BeginHorizontal();
|
||||
|
||||
EditorGUILayout.LabelField(label, EditorStyles.miniBoldLabel);
|
||||
|
||||
if (useInlineValue.boolValue) {
|
||||
EditorGUILayout.PropertyField(inlineValue, GUIContent.none);
|
||||
} else {
|
||||
EditorGUILayout.PropertyField(asset, GUIContent.none);
|
||||
}
|
||||
|
||||
if (GUILayout.Button(useInlineValue.boolValue ? "Inline" : "Asset", GUILayout.MaxWidth(100))) {
|
||||
useInlineValue.boolValue = !useInlineValue.boolValue;
|
||||
}
|
||||
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
EditorGUI.EndProperty();
|
||||
}
|
||||
}
|
||||
using RebootKit.Engine.Foundation;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace RebootKitEditor.PropertyDrawers {
|
||||
[CustomPropertyDrawer(typeof(ConstsProperty<>))]
|
||||
public class ConstsPropertyDrawer : PropertyDrawer {
|
||||
const string k_InlineValue = "m_InlineValue";
|
||||
const string k_Asset = "m_Asset";
|
||||
const string k_UseInlineValue = "m_UseInlineValue";
|
||||
|
||||
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) {
|
||||
SerializedProperty useInlineValue = property.FindPropertyRelative(k_UseInlineValue);
|
||||
SerializedProperty inlineValue = property.FindPropertyRelative(k_InlineValue);
|
||||
SerializedProperty asset = property.FindPropertyRelative(k_Asset);
|
||||
|
||||
EditorGUI.BeginProperty(position, label, property);
|
||||
|
||||
GUILayout.BeginHorizontal();
|
||||
|
||||
EditorGUILayout.LabelField(label, EditorStyles.miniBoldLabel);
|
||||
|
||||
if (useInlineValue.boolValue) {
|
||||
EditorGUILayout.PropertyField(inlineValue, GUIContent.none);
|
||||
} else {
|
||||
EditorGUILayout.PropertyField(asset, GUIContent.none);
|
||||
}
|
||||
|
||||
if (GUILayout.Button(useInlineValue.boolValue ? "Inline" : "Asset", GUILayout.MaxWidth(100))) {
|
||||
useInlineValue.boolValue = !useInlineValue.boolValue;
|
||||
}
|
||||
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
EditorGUI.EndProperty();
|
||||
}
|
||||
}
|
||||
}
|
||||
0
Editor/PropertyDrawers/ConstsPropertyDrawer.cs.meta
Normal file → Executable file
0
Editor/PropertyDrawers/ConstsPropertyDrawer.cs.meta
Normal file → Executable file
0
Editor/PropertyDrawers/SerializableGuidDrawer.cs
Normal file → Executable file
0
Editor/PropertyDrawers/SerializableGuidDrawer.cs
Normal file → Executable file
0
Editor/PropertyDrawers/SerializableGuidDrawer.cs.meta
Normal file → Executable file
0
Editor/PropertyDrawers/SerializableGuidDrawer.cs.meta
Normal file → Executable file
0
Editor/PropertyDrawers/ValueRangeDrawer.cs
Normal file → Executable file
0
Editor/PropertyDrawers/ValueRangeDrawer.cs
Normal file → Executable file
0
Editor/PropertyDrawers/ValueRangeDrawer.cs.meta
Normal file → Executable file
0
Editor/PropertyDrawers/ValueRangeDrawer.cs.meta
Normal file → Executable file
12
Editor/REditorConsts.cs
Normal file → Executable file
12
Editor/REditorConsts.cs
Normal file → Executable file
@@ -1,7 +1,7 @@
|
||||
namespace RebootKitEditor {
|
||||
static class REditorConsts {
|
||||
internal const string k_EditorMenu = "Reboot Reality/";
|
||||
|
||||
internal const string k_OnGameRunScriptContentKey = "RebootKitEditor.OnGameRunScriptContent";
|
||||
}
|
||||
namespace RebootKitEditor {
|
||||
static class REditorConsts {
|
||||
internal const string k_EditorMenu = "Reboot Reality/";
|
||||
|
||||
internal const string k_OnGameRunScriptContentKey = "RebootKitEditor.OnGameRunScriptContent";
|
||||
}
|
||||
}
|
||||
0
Editor/REditorConsts.cs.meta
Normal file → Executable file
0
Editor/REditorConsts.cs.meta
Normal file → Executable file
0
Editor/RebootKitEditor.asmdef
Normal file → Executable file
0
Editor/RebootKitEditor.asmdef
Normal file → Executable file
0
Editor/RebootKitEditor.asmdef.meta
Normal file → Executable file
0
Editor/RebootKitEditor.asmdef.meta
Normal file → Executable file
0
Editor/RebootWindow.meta
Normal file → Executable file
0
Editor/RebootWindow.meta
Normal file → Executable file
208
Editor/RebootWindow/ConfigVarsView.cs
Normal file → Executable file
208
Editor/RebootWindow/ConfigVarsView.cs
Normal file → Executable file
@@ -1,105 +1,105 @@
|
||||
using RebootKit.Engine.Foundation;
|
||||
using RebootKit.Engine.Services.Console;
|
||||
using RebootKit.Engine.UI;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
namespace RebootKitEditor.RebootWindow {
|
||||
public class ConfigVarsView : IView {
|
||||
public void Dispose() {
|
||||
}
|
||||
|
||||
public VisualElement Build() {
|
||||
ScrollView scrollView = new() {
|
||||
style = {
|
||||
flexGrow = 1
|
||||
}
|
||||
};
|
||||
|
||||
ConfigVarsContainer.Init();
|
||||
|
||||
foreach (ConfigVar cvar in ConfigVarsContainer.All()) {
|
||||
VisualElement varContainer = new() {
|
||||
style = {
|
||||
marginBottom = 8,
|
||||
paddingBottom = 8,
|
||||
borderBottomWidth = 1,
|
||||
borderBottomColor = new Color(0.3f, 0.3f, 0.3f),
|
||||
}
|
||||
};
|
||||
|
||||
VisualElement valueContainer = new() {
|
||||
style = {
|
||||
flexDirection = FlexDirection.Row
|
||||
}
|
||||
};
|
||||
varContainer.Add(valueContainer);
|
||||
|
||||
Label nameLabel = new(cvar.name) {
|
||||
style = {
|
||||
color = new Color(0.7f, 0.9f, 0.9f),
|
||||
unityFontStyleAndWeight = FontStyle.Bold
|
||||
}
|
||||
};
|
||||
valueContainer.Add(nameLabel);
|
||||
|
||||
Label valueLabel = new(cvar.ToString()) {
|
||||
style = {
|
||||
color = RTheme.s_FirstColor
|
||||
}
|
||||
};
|
||||
valueContainer.Add(valueLabel);
|
||||
|
||||
if (cvar.flags.HasFlag(CVarFlags.User)) {
|
||||
valueContainer.Add(CreateFlagLabel("User", new Color(0.36f, 0.41f, 0.42f)));
|
||||
}
|
||||
|
||||
if (cvar.flags.HasFlag(CVarFlags.Client)) {
|
||||
valueContainer.Add(CreateFlagLabel("Client", new Color(0.81f, 0.29f, 0.15f)));
|
||||
}
|
||||
|
||||
if (cvar.flags.HasFlag(CVarFlags.Server)) {
|
||||
valueContainer.Add(CreateFlagLabel("Server", new Color(0.18f, 0.64f, 0.18f)));
|
||||
}
|
||||
|
||||
if (cvar.flags.HasFlag(CVarFlags.ReadOnly)) {
|
||||
valueContainer.Add(CreateFlagLabel("ReadOnly", new Color(0.13f, 0.07f, 0.47f)));
|
||||
}
|
||||
|
||||
Label descLabel = new(cvar.description) {
|
||||
style = {
|
||||
fontSize = 10,
|
||||
color = new Color(0.7f, 0.7f, 0.7f)
|
||||
}
|
||||
};
|
||||
varContainer.Add(descLabel);
|
||||
|
||||
scrollView.Add(varContainer);
|
||||
}
|
||||
|
||||
return scrollView;
|
||||
}
|
||||
|
||||
VisualElement CreateFlagLabel(string text, Color color) {
|
||||
Label label = new(text) {
|
||||
style = {
|
||||
fontSize = 12,
|
||||
color = new Color(0.7f, 0.7f, 0.7f),
|
||||
backgroundColor = color,
|
||||
paddingLeft = 4,
|
||||
paddingRight = 4,
|
||||
paddingTop = 4,
|
||||
paddingBottom = 4,
|
||||
marginLeft = 4,
|
||||
marginRight = 4,
|
||||
borderTopLeftRadius = 8,
|
||||
borderTopRightRadius = 8,
|
||||
borderBottomLeftRadius = 8,
|
||||
borderBottomRightRadius = 8,
|
||||
unityFontStyleAndWeight = FontStyle.Bold,
|
||||
}
|
||||
};
|
||||
return label;
|
||||
}
|
||||
}
|
||||
using RebootKit.Engine.Foundation;
|
||||
using RebootKit.Engine.Services.Console;
|
||||
using RebootKit.Engine.UI;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
namespace RebootKitEditor.RebootWindow {
|
||||
public class ConfigVarsView : IView {
|
||||
public void Dispose() {
|
||||
}
|
||||
|
||||
public VisualElement Build() {
|
||||
ScrollView scrollView = new() {
|
||||
style = {
|
||||
flexGrow = 1
|
||||
}
|
||||
};
|
||||
|
||||
ConfigVarsContainer.Init();
|
||||
|
||||
foreach (ConfigVar cvar in ConfigVarsContainer.All()) {
|
||||
VisualElement varContainer = new() {
|
||||
style = {
|
||||
marginBottom = 8,
|
||||
paddingBottom = 8,
|
||||
borderBottomWidth = 1,
|
||||
borderBottomColor = new Color(0.3f, 0.3f, 0.3f),
|
||||
}
|
||||
};
|
||||
|
||||
VisualElement valueContainer = new() {
|
||||
style = {
|
||||
flexDirection = FlexDirection.Row
|
||||
}
|
||||
};
|
||||
varContainer.Add(valueContainer);
|
||||
|
||||
Label nameLabel = new(cvar.name) {
|
||||
style = {
|
||||
color = new Color(0.7f, 0.9f, 0.9f),
|
||||
unityFontStyleAndWeight = FontStyle.Bold
|
||||
}
|
||||
};
|
||||
valueContainer.Add(nameLabel);
|
||||
|
||||
Label valueLabel = new(cvar.ToString()) {
|
||||
style = {
|
||||
color = RTheme.s_FirstColor
|
||||
}
|
||||
};
|
||||
valueContainer.Add(valueLabel);
|
||||
|
||||
if (cvar.flags.HasFlag(CVarFlags.User)) {
|
||||
valueContainer.Add(CreateFlagLabel("User", new Color(0.36f, 0.41f, 0.42f)));
|
||||
}
|
||||
|
||||
if (cvar.flags.HasFlag(CVarFlags.Client)) {
|
||||
valueContainer.Add(CreateFlagLabel("Client", new Color(0.81f, 0.29f, 0.15f)));
|
||||
}
|
||||
|
||||
if (cvar.flags.HasFlag(CVarFlags.Server)) {
|
||||
valueContainer.Add(CreateFlagLabel("Server", new Color(0.18f, 0.64f, 0.18f)));
|
||||
}
|
||||
|
||||
if (cvar.flags.HasFlag(CVarFlags.ReadOnly)) {
|
||||
valueContainer.Add(CreateFlagLabel("ReadOnly", new Color(0.13f, 0.07f, 0.47f)));
|
||||
}
|
||||
|
||||
Label descLabel = new(cvar.description) {
|
||||
style = {
|
||||
fontSize = 10,
|
||||
color = new Color(0.7f, 0.7f, 0.7f)
|
||||
}
|
||||
};
|
||||
varContainer.Add(descLabel);
|
||||
|
||||
scrollView.Add(varContainer);
|
||||
}
|
||||
|
||||
return scrollView;
|
||||
}
|
||||
|
||||
VisualElement CreateFlagLabel(string text, Color color) {
|
||||
Label label = new(text) {
|
||||
style = {
|
||||
fontSize = 12,
|
||||
color = new Color(0.7f, 0.7f, 0.7f),
|
||||
backgroundColor = color,
|
||||
paddingLeft = 4,
|
||||
paddingRight = 4,
|
||||
paddingTop = 4,
|
||||
paddingBottom = 4,
|
||||
marginLeft = 4,
|
||||
marginRight = 4,
|
||||
borderTopLeftRadius = 8,
|
||||
borderTopRightRadius = 8,
|
||||
borderBottomLeftRadius = 8,
|
||||
borderBottomRightRadius = 8,
|
||||
unityFontStyleAndWeight = FontStyle.Bold,
|
||||
}
|
||||
};
|
||||
return label;
|
||||
}
|
||||
}
|
||||
}
|
||||
0
Editor/RebootWindow/ConfigVarsView.cs.meta
Normal file → Executable file
0
Editor/RebootWindow/ConfigVarsView.cs.meta
Normal file → Executable file
208
Editor/RebootWindow/GameServicesView.cs
Normal file → Executable file
208
Editor/RebootWindow/GameServicesView.cs
Normal file → Executable file
@@ -1,105 +1,105 @@
|
||||
using System.Collections.Generic;
|
||||
using RebootKit.Engine;
|
||||
using RebootKit.Engine.Foundation;
|
||||
using RebootKit.Engine.UI;
|
||||
using UnityEditor;
|
||||
using UnityEditor.UIElements;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
namespace RebootKitEditor.RebootWindow {
|
||||
public class GameServicesView : IView {
|
||||
VisualElement m_RootElement;
|
||||
|
||||
readonly List<Editor> m_ServiceEditors = new();
|
||||
|
||||
[Inject] EngineConfigAsset m_EngineConfigAsset;
|
||||
|
||||
public void Dispose() {
|
||||
foreach (Editor editor in m_ServiceEditors) {
|
||||
if (editor != null) {
|
||||
Object.DestroyImmediate(editor);
|
||||
}
|
||||
}
|
||||
m_ServiceEditors.Clear();
|
||||
}
|
||||
|
||||
public VisualElement Build() {
|
||||
m_RootElement = new ScrollView();
|
||||
|
||||
// int servicesLength = m_EngineConfigAsset.services?.Length ?? 0;
|
||||
//
|
||||
// Label servicesAmountLabel = new($"Game services: {servicesLength}") {
|
||||
// style = {
|
||||
// color = new Color(0.7f, 0.9f, 0.9f),
|
||||
// unityFontStyleAndWeight = FontStyle.Bold
|
||||
// }
|
||||
// };
|
||||
// m_RootElement.Add(servicesAmountLabel);
|
||||
//
|
||||
// for (int i = 0; i < servicesLength; i++) {
|
||||
// ServiceAsset serviceAsset = m_EngineConfigAsset.services[i];
|
||||
//
|
||||
// VisualElement serviceView = CreateServicesView(serviceAsset);
|
||||
// serviceView.style.backgroundColor = i % 2 == 0 ? new Color(0.1f, 0.1f, 0.1f) : new Color(0.2f, 0.2f, 0.2f);
|
||||
// m_RootElement.Add(serviceView);
|
||||
// }
|
||||
|
||||
return m_RootElement;
|
||||
}
|
||||
|
||||
VisualElement CreateServicesView<T>(ServiceAsset<T> serviceAsset) where T : class, IService {
|
||||
VisualElement root = new() {
|
||||
style = {
|
||||
paddingBottom = 4,
|
||||
paddingTop = 4,
|
||||
paddingLeft = 4,
|
||||
paddingRight = 4,
|
||||
borderBottomLeftRadius = 4,
|
||||
borderBottomRightRadius = 4
|
||||
}
|
||||
};
|
||||
|
||||
VisualElement header = new() {
|
||||
style = {
|
||||
backgroundColor = new Color(0.2f, 0.2f, 0.2f),
|
||||
paddingLeft = 8,
|
||||
paddingRight = 8,
|
||||
paddingTop = 4,
|
||||
paddingBottom = 4,
|
||||
borderTopLeftRadius = 4,
|
||||
borderTopRightRadius = 4,
|
||||
}
|
||||
};
|
||||
root.Add(header);
|
||||
|
||||
Label nameLabel = new(serviceAsset.name) {
|
||||
style = {
|
||||
color = new Color(0.7f, 0.9f, 0.9f),
|
||||
unityFontStyleAndWeight = FontStyle.Bold
|
||||
}
|
||||
};
|
||||
header.Add(nameLabel);
|
||||
|
||||
VisualElement editorView = new() {
|
||||
style = {
|
||||
backgroundColor = new Color(0.3f, 0.3f, 0.3f),
|
||||
paddingLeft = 10,
|
||||
paddingRight = 10,
|
||||
paddingTop = 5,
|
||||
paddingBottom = 5,
|
||||
minHeight = 50
|
||||
}
|
||||
};
|
||||
root.Add(editorView);
|
||||
|
||||
Editor editor = Editor.CreateEditor(serviceAsset);
|
||||
m_ServiceEditors.Add(editor);
|
||||
|
||||
InspectorElement inspectorElement = new(editor);
|
||||
editorView.Add(inspectorElement);
|
||||
|
||||
return root;
|
||||
}
|
||||
}
|
||||
using System.Collections.Generic;
|
||||
using RebootKit.Engine;
|
||||
using RebootKit.Engine.Foundation;
|
||||
using RebootKit.Engine.UI;
|
||||
using UnityEditor;
|
||||
using UnityEditor.UIElements;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
namespace RebootKitEditor.RebootWindow {
|
||||
public class GameServicesView : IView {
|
||||
VisualElement m_RootElement;
|
||||
|
||||
readonly List<Editor> m_ServiceEditors = new();
|
||||
|
||||
[Inject] EngineConfigAsset m_EngineConfigAsset;
|
||||
|
||||
public void Dispose() {
|
||||
foreach (Editor editor in m_ServiceEditors) {
|
||||
if (editor != null) {
|
||||
Object.DestroyImmediate(editor);
|
||||
}
|
||||
}
|
||||
m_ServiceEditors.Clear();
|
||||
}
|
||||
|
||||
public VisualElement Build() {
|
||||
m_RootElement = new ScrollView();
|
||||
|
||||
// int servicesLength = m_EngineConfigAsset.services?.Length ?? 0;
|
||||
//
|
||||
// Label servicesAmountLabel = new($"Game services: {servicesLength}") {
|
||||
// style = {
|
||||
// color = new Color(0.7f, 0.9f, 0.9f),
|
||||
// unityFontStyleAndWeight = FontStyle.Bold
|
||||
// }
|
||||
// };
|
||||
// m_RootElement.Add(servicesAmountLabel);
|
||||
//
|
||||
// for (int i = 0; i < servicesLength; i++) {
|
||||
// ServiceAsset serviceAsset = m_EngineConfigAsset.services[i];
|
||||
//
|
||||
// VisualElement serviceView = CreateServicesView(serviceAsset);
|
||||
// serviceView.style.backgroundColor = i % 2 == 0 ? new Color(0.1f, 0.1f, 0.1f) : new Color(0.2f, 0.2f, 0.2f);
|
||||
// m_RootElement.Add(serviceView);
|
||||
// }
|
||||
|
||||
return m_RootElement;
|
||||
}
|
||||
|
||||
VisualElement CreateServicesView<T>(ServiceAsset<T> serviceAsset) where T : class, IService {
|
||||
VisualElement root = new() {
|
||||
style = {
|
||||
paddingBottom = 4,
|
||||
paddingTop = 4,
|
||||
paddingLeft = 4,
|
||||
paddingRight = 4,
|
||||
borderBottomLeftRadius = 4,
|
||||
borderBottomRightRadius = 4
|
||||
}
|
||||
};
|
||||
|
||||
VisualElement header = new() {
|
||||
style = {
|
||||
backgroundColor = new Color(0.2f, 0.2f, 0.2f),
|
||||
paddingLeft = 8,
|
||||
paddingRight = 8,
|
||||
paddingTop = 4,
|
||||
paddingBottom = 4,
|
||||
borderTopLeftRadius = 4,
|
||||
borderTopRightRadius = 4,
|
||||
}
|
||||
};
|
||||
root.Add(header);
|
||||
|
||||
Label nameLabel = new(serviceAsset.name) {
|
||||
style = {
|
||||
color = new Color(0.7f, 0.9f, 0.9f),
|
||||
unityFontStyleAndWeight = FontStyle.Bold
|
||||
}
|
||||
};
|
||||
header.Add(nameLabel);
|
||||
|
||||
VisualElement editorView = new() {
|
||||
style = {
|
||||
backgroundColor = new Color(0.3f, 0.3f, 0.3f),
|
||||
paddingLeft = 10,
|
||||
paddingRight = 10,
|
||||
paddingTop = 5,
|
||||
paddingBottom = 5,
|
||||
minHeight = 50
|
||||
}
|
||||
};
|
||||
root.Add(editorView);
|
||||
|
||||
Editor editor = Editor.CreateEditor(serviceAsset);
|
||||
m_ServiceEditors.Add(editor);
|
||||
|
||||
InspectorElement inspectorElement = new(editor);
|
||||
editorView.Add(inspectorElement);
|
||||
|
||||
return root;
|
||||
}
|
||||
}
|
||||
}
|
||||
0
Editor/RebootWindow/GameServicesView.cs.meta
Normal file → Executable file
0
Editor/RebootWindow/GameServicesView.cs.meta
Normal file → Executable file
250
Editor/RebootWindow/HomeView.cs
Normal file → Executable file
250
Editor/RebootWindow/HomeView.cs
Normal file → Executable file
@@ -1,126 +1,126 @@
|
||||
using RebootKit.Engine.Main;
|
||||
using RebootKit.Engine.Services.Console;
|
||||
using RebootKit.Engine.UI;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
namespace RebootKitEditor.RebootWindow {
|
||||
public class HomeView : IView {
|
||||
public void Dispose() {
|
||||
}
|
||||
|
||||
public VisualElement Build() {
|
||||
VisualElement rootContainer = new() {
|
||||
style = {
|
||||
flexGrow = 1,
|
||||
fontSize = 14
|
||||
}
|
||||
};
|
||||
|
||||
Label label = new($"{Application.productName} {Application.version}") {
|
||||
style = {
|
||||
fontSize = 18,
|
||||
unityFontStyleAndWeight = FontStyle.Bold
|
||||
}
|
||||
};
|
||||
rootContainer.Add(label);
|
||||
|
||||
VisualElement persistentPathContainer = new() {
|
||||
style = {
|
||||
marginTop = 8,
|
||||
marginBottom = 8,
|
||||
paddingLeft = 4,
|
||||
paddingRight = 4,
|
||||
paddingTop = 4,
|
||||
paddingBottom = 4,
|
||||
borderLeftWidth = 1,
|
||||
borderLeftColor = new Color(0.3f, 0.3f, 0.3f),
|
||||
flexDirection = FlexDirection.Row,
|
||||
}
|
||||
};
|
||||
|
||||
Label persistentPathLabel = new($"Persistent Path: {Application.persistentDataPath}") {
|
||||
style = {
|
||||
fontSize = 12,
|
||||
color = new Color(0.7f, 0.9f, 0.9f)
|
||||
}
|
||||
};
|
||||
persistentPathContainer.Add(persistentPathLabel);
|
||||
|
||||
Button openPersistentPathButton = new(() => { Application.OpenURL(Application.persistentDataPath); }) {
|
||||
style = {
|
||||
fontSize = 12,
|
||||
width = 48
|
||||
},
|
||||
text = "Open"
|
||||
};
|
||||
persistentPathContainer.Add(openPersistentPathButton);
|
||||
|
||||
rootContainer.Add(persistentPathContainer);
|
||||
|
||||
Label onGameRunScriptLabel = new("On Game Run Script (User):") {
|
||||
style = {
|
||||
fontSize = 12,
|
||||
color = new Color(0.7f, 0.9f, 0.9f)
|
||||
}
|
||||
};
|
||||
rootContainer.Add(onGameRunScriptLabel);
|
||||
|
||||
TextField onGameRunScriptTextField = new() {
|
||||
style = {
|
||||
fontSize = 12,
|
||||
},
|
||||
multiline = true,
|
||||
value = EditorPrefs.GetString(REditorConsts.k_OnGameRunScriptContentKey, "")
|
||||
};
|
||||
|
||||
onGameRunScriptTextField.RegisterValueChangedCallback(evt => {
|
||||
EditorPrefs.SetString(REditorConsts.k_OnGameRunScriptContentKey, evt.newValue);
|
||||
});
|
||||
rootContainer.Add(onGameRunScriptTextField);
|
||||
|
||||
Label consoleCommandsLabel = new("Console Commands:") {
|
||||
style = {
|
||||
fontSize = 12,
|
||||
color = new Color(0.7f, 0.9f, 0.9f)
|
||||
}
|
||||
};
|
||||
rootContainer.Add(consoleCommandsLabel);
|
||||
|
||||
ConsoleService.ConsoleCommand[] consoleCommands = ConsoleService.GenerateCommandsToRegister();
|
||||
foreach (ConsoleService.ConsoleCommand consoleCommand in consoleCommands) {
|
||||
VisualElement commandContainer = new() {
|
||||
style = {
|
||||
flexDirection = FlexDirection.Row,
|
||||
marginTop = 4,
|
||||
marginBottom = 4,
|
||||
paddingLeft = 4,
|
||||
paddingRight = 4,
|
||||
paddingTop = 4,
|
||||
paddingBottom = 4,
|
||||
}
|
||||
};
|
||||
Label commandLabel = new(consoleCommand.name) {
|
||||
style = {
|
||||
fontSize = 12,
|
||||
color = new Color(0.7f, 0.9f, 0.9f)
|
||||
}
|
||||
};
|
||||
commandContainer.Add(commandLabel);
|
||||
|
||||
Label descriptionLabel = new(consoleCommand.description) {
|
||||
style = {
|
||||
fontSize = 12,
|
||||
color = new Color(0.5f, 0.7f, 0.7f)
|
||||
}
|
||||
};
|
||||
commandContainer.Add(descriptionLabel);
|
||||
|
||||
rootContainer.Add(commandContainer);
|
||||
}
|
||||
|
||||
return rootContainer;
|
||||
}
|
||||
}
|
||||
using RebootKit.Engine.Main;
|
||||
using RebootKit.Engine.Services.Console;
|
||||
using RebootKit.Engine.UI;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
namespace RebootKitEditor.RebootWindow {
|
||||
public class HomeView : IView {
|
||||
public void Dispose() {
|
||||
}
|
||||
|
||||
public VisualElement Build() {
|
||||
VisualElement rootContainer = new() {
|
||||
style = {
|
||||
flexGrow = 1,
|
||||
fontSize = 14
|
||||
}
|
||||
};
|
||||
|
||||
Label label = new($"{Application.productName} {Application.version}") {
|
||||
style = {
|
||||
fontSize = 18,
|
||||
unityFontStyleAndWeight = FontStyle.Bold
|
||||
}
|
||||
};
|
||||
rootContainer.Add(label);
|
||||
|
||||
VisualElement persistentPathContainer = new() {
|
||||
style = {
|
||||
marginTop = 8,
|
||||
marginBottom = 8,
|
||||
paddingLeft = 4,
|
||||
paddingRight = 4,
|
||||
paddingTop = 4,
|
||||
paddingBottom = 4,
|
||||
borderLeftWidth = 1,
|
||||
borderLeftColor = new Color(0.3f, 0.3f, 0.3f),
|
||||
flexDirection = FlexDirection.Row,
|
||||
}
|
||||
};
|
||||
|
||||
Label persistentPathLabel = new($"Persistent Path: {Application.persistentDataPath}") {
|
||||
style = {
|
||||
fontSize = 12,
|
||||
color = new Color(0.7f, 0.9f, 0.9f)
|
||||
}
|
||||
};
|
||||
persistentPathContainer.Add(persistentPathLabel);
|
||||
|
||||
Button openPersistentPathButton = new(() => { Application.OpenURL(Application.persistentDataPath); }) {
|
||||
style = {
|
||||
fontSize = 12,
|
||||
width = 48
|
||||
},
|
||||
text = "Open"
|
||||
};
|
||||
persistentPathContainer.Add(openPersistentPathButton);
|
||||
|
||||
rootContainer.Add(persistentPathContainer);
|
||||
|
||||
Label onGameRunScriptLabel = new("On Game Run Script (User):") {
|
||||
style = {
|
||||
fontSize = 12,
|
||||
color = new Color(0.7f, 0.9f, 0.9f)
|
||||
}
|
||||
};
|
||||
rootContainer.Add(onGameRunScriptLabel);
|
||||
|
||||
TextField onGameRunScriptTextField = new() {
|
||||
style = {
|
||||
fontSize = 12,
|
||||
},
|
||||
multiline = true,
|
||||
value = EditorPrefs.GetString(REditorConsts.k_OnGameRunScriptContentKey, "")
|
||||
};
|
||||
|
||||
onGameRunScriptTextField.RegisterValueChangedCallback(evt => {
|
||||
EditorPrefs.SetString(REditorConsts.k_OnGameRunScriptContentKey, evt.newValue);
|
||||
});
|
||||
rootContainer.Add(onGameRunScriptTextField);
|
||||
|
||||
Label consoleCommandsLabel = new("Console Commands:") {
|
||||
style = {
|
||||
fontSize = 12,
|
||||
color = new Color(0.7f, 0.9f, 0.9f)
|
||||
}
|
||||
};
|
||||
rootContainer.Add(consoleCommandsLabel);
|
||||
|
||||
ConsoleService.ConsoleCommand[] consoleCommands = ConsoleService.GenerateCommandsToRegister();
|
||||
foreach (ConsoleService.ConsoleCommand consoleCommand in consoleCommands) {
|
||||
VisualElement commandContainer = new() {
|
||||
style = {
|
||||
flexDirection = FlexDirection.Row,
|
||||
marginTop = 4,
|
||||
marginBottom = 4,
|
||||
paddingLeft = 4,
|
||||
paddingRight = 4,
|
||||
paddingTop = 4,
|
||||
paddingBottom = 4,
|
||||
}
|
||||
};
|
||||
Label commandLabel = new(consoleCommand.name) {
|
||||
style = {
|
||||
fontSize = 12,
|
||||
color = new Color(0.7f, 0.9f, 0.9f)
|
||||
}
|
||||
};
|
||||
commandContainer.Add(commandLabel);
|
||||
|
||||
Label descriptionLabel = new(consoleCommand.description) {
|
||||
style = {
|
||||
fontSize = 12,
|
||||
color = new Color(0.5f, 0.7f, 0.7f)
|
||||
}
|
||||
};
|
||||
commandContainer.Add(descriptionLabel);
|
||||
|
||||
rootContainer.Add(commandContainer);
|
||||
}
|
||||
|
||||
return rootContainer;
|
||||
}
|
||||
}
|
||||
}
|
||||
0
Editor/RebootWindow/HomeView.cs.meta
Normal file → Executable file
0
Editor/RebootWindow/HomeView.cs.meta
Normal file → Executable file
150
Editor/RebootWindow/RebootEditorWindow.cs
Normal file → Executable file
150
Editor/RebootWindow/RebootEditorWindow.cs
Normal file → Executable file
@@ -1,76 +1,76 @@
|
||||
using RebootKit.Engine;
|
||||
using RebootKit.Engine.Foundation;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UIElements;
|
||||
using Logger = RebootKit.Engine.Foundation.Logger;
|
||||
|
||||
namespace RebootKitEditor.RebootWindow {
|
||||
static class RTheme {
|
||||
public static readonly Color s_FirstColor = ColorFromHex("#B9B8B9");
|
||||
public static readonly Color s_SecondColor = ColorFromHex("#6B6B6B");
|
||||
public static readonly Color s_BackgroundPrimaryColor = EditorGUIUtility.isProSkin ? ColorFromHex("#1E1E1E") : ColorFromHex("#F0F0F0");
|
||||
public static readonly Color s_BackgroundSecondaryColor = ColorFromHex("#242126");
|
||||
public static readonly Color s_TextColor = ColorFromHex("#696969");
|
||||
|
||||
static Color ColorFromHex(string hex) {
|
||||
if (ColorUtility.TryParseHtmlString(hex, out Color color)) {
|
||||
return color;
|
||||
} else {
|
||||
Debug.LogError($"Failed to parse color from hex: {hex}");
|
||||
return Color.white;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class RebootEditorWindow : EditorWindow {
|
||||
static readonly Logger s_logger = new(nameof(RebootEditorWindow));
|
||||
|
||||
EngineConfigAsset m_EngineConfigAsset;
|
||||
DIContext m_DIContext;
|
||||
|
||||
VisualElement m_RootElement;
|
||||
TabView m_TabView;
|
||||
|
||||
[MenuItem(REditorConsts.k_EditorMenu + "RebootKit")]
|
||||
public static void ShowWindow() {
|
||||
RebootEditorWindow window = GetWindow<RebootEditorWindow>($"RebootKit - {Application.productName}");
|
||||
window.Show();
|
||||
}
|
||||
|
||||
void OnEnable() {
|
||||
m_EngineConfigAsset = Resources.Load<EngineConfigAsset>(RConsts.k_EngineConfigResourcesPath);
|
||||
if (m_EngineConfigAsset == null) {
|
||||
EngineConfigAsset newConfig = CreateInstance<EngineConfigAsset>();
|
||||
newConfig.name = RConsts.k_EngineConfigAssetName;
|
||||
AssetDatabase.CreateAsset(newConfig, RConsts.k_EngineConfigAssetPath);
|
||||
AssetDatabase.SaveAssets();
|
||||
AssetDatabase.Refresh();
|
||||
s_logger.Info($"Created new engine config asset at: {RConsts.k_EngineConfigAssetPath}");
|
||||
|
||||
m_EngineConfigAsset = Resources.Load<EngineConfigAsset>(RConsts.k_EngineConfigResourcesPath);
|
||||
if (m_EngineConfigAsset == null) {
|
||||
s_logger.Error($"Couldn't load engine config from resources: {RConsts.k_EngineConfigResourcesPath}");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
m_DIContext = new DIContext();
|
||||
m_DIContext.Bind(this);
|
||||
m_DIContext.Bind(m_EngineConfigAsset);
|
||||
|
||||
m_TabView = m_DIContext.Create<TabView>();
|
||||
m_TabView.AddTab("Home", m_DIContext.Create<HomeView>());
|
||||
m_TabView.AddTab("Config Vars", m_DIContext.Create<ConfigVarsView>());
|
||||
m_TabView.AddTab("Game Services", m_DIContext.Create<GameServicesView>());
|
||||
m_TabView.AddTab("Worlds", m_DIContext.Create<WorldsView>());
|
||||
}
|
||||
|
||||
void CreateGUI() {
|
||||
m_RootElement = rootVisualElement;
|
||||
m_RootElement.Clear();
|
||||
|
||||
m_RootElement.Add(m_TabView.Build());
|
||||
}
|
||||
}
|
||||
using RebootKit.Engine;
|
||||
using RebootKit.Engine.Foundation;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UIElements;
|
||||
using Logger = RebootKit.Engine.Foundation.Logger;
|
||||
|
||||
namespace RebootKitEditor.RebootWindow {
|
||||
static class RTheme {
|
||||
public static readonly Color s_FirstColor = ColorFromHex("#B9B8B9");
|
||||
public static readonly Color s_SecondColor = ColorFromHex("#6B6B6B");
|
||||
public static readonly Color s_BackgroundPrimaryColor = EditorGUIUtility.isProSkin ? ColorFromHex("#1E1E1E") : ColorFromHex("#F0F0F0");
|
||||
public static readonly Color s_BackgroundSecondaryColor = ColorFromHex("#242126");
|
||||
public static readonly Color s_TextColor = ColorFromHex("#696969");
|
||||
|
||||
static Color ColorFromHex(string hex) {
|
||||
if (ColorUtility.TryParseHtmlString(hex, out Color color)) {
|
||||
return color;
|
||||
} else {
|
||||
Debug.LogError($"Failed to parse color from hex: {hex}");
|
||||
return Color.white;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class RebootEditorWindow : EditorWindow {
|
||||
static readonly Logger s_logger = new(nameof(RebootEditorWindow));
|
||||
|
||||
EngineConfigAsset m_EngineConfigAsset;
|
||||
DIContext m_DIContext;
|
||||
|
||||
VisualElement m_RootElement;
|
||||
TabView m_TabView;
|
||||
|
||||
[MenuItem(REditorConsts.k_EditorMenu + "RebootKit")]
|
||||
public static void ShowWindow() {
|
||||
RebootEditorWindow window = GetWindow<RebootEditorWindow>($"RebootKit - {Application.productName}");
|
||||
window.Show();
|
||||
}
|
||||
|
||||
void OnEnable() {
|
||||
m_EngineConfigAsset = Resources.Load<EngineConfigAsset>(RConsts.k_EngineConfigResourcesPath);
|
||||
if (m_EngineConfigAsset == null) {
|
||||
EngineConfigAsset newConfig = CreateInstance<EngineConfigAsset>();
|
||||
newConfig.name = RConsts.k_EngineConfigAssetName;
|
||||
AssetDatabase.CreateAsset(newConfig, RConsts.k_EngineConfigAssetPath);
|
||||
AssetDatabase.SaveAssets();
|
||||
AssetDatabase.Refresh();
|
||||
s_logger.Info($"Created new engine config asset at: {RConsts.k_EngineConfigAssetPath}");
|
||||
|
||||
m_EngineConfigAsset = Resources.Load<EngineConfigAsset>(RConsts.k_EngineConfigResourcesPath);
|
||||
if (m_EngineConfigAsset == null) {
|
||||
s_logger.Error($"Couldn't load engine config from resources: {RConsts.k_EngineConfigResourcesPath}");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
m_DIContext = new DIContext();
|
||||
m_DIContext.Bind(this);
|
||||
m_DIContext.Bind(m_EngineConfigAsset);
|
||||
|
||||
m_TabView = m_DIContext.Create<TabView>();
|
||||
m_TabView.AddTab("Home", m_DIContext.Create<HomeView>());
|
||||
m_TabView.AddTab("Config Vars", m_DIContext.Create<ConfigVarsView>());
|
||||
m_TabView.AddTab("Game Services", m_DIContext.Create<GameServicesView>());
|
||||
m_TabView.AddTab("Worlds", m_DIContext.Create<WorldsView>());
|
||||
}
|
||||
|
||||
void CreateGUI() {
|
||||
m_RootElement = rootVisualElement;
|
||||
m_RootElement.Clear();
|
||||
|
||||
m_RootElement.Add(m_TabView.Build());
|
||||
}
|
||||
}
|
||||
}
|
||||
0
Editor/RebootWindow/RebootEditorWindow.cs.meta
Normal file → Executable file
0
Editor/RebootWindow/RebootEditorWindow.cs.meta
Normal file → Executable file
252
Editor/RebootWindow/TabView.cs
Normal file → Executable file
252
Editor/RebootWindow/TabView.cs
Normal file → Executable file
@@ -1,127 +1,127 @@
|
||||
using System.Collections.Generic;
|
||||
using RebootKit.Engine.UI;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Assertions;
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
namespace RebootKitEditor.RebootWindow {
|
||||
public class TabView : IView {
|
||||
struct Tab {
|
||||
public string name;
|
||||
public IView view;
|
||||
public VisualElement container;
|
||||
}
|
||||
|
||||
readonly List<Tab> m_Tabs = new();
|
||||
readonly List<VisualElement> m_TabContents = new();
|
||||
readonly List<Button> m_TabButtons = new();
|
||||
int m_CurrentTabIndex = -1;
|
||||
|
||||
public void Dispose() {
|
||||
}
|
||||
|
||||
public VisualElement Build() {
|
||||
VisualElement rootContainer = new() {
|
||||
style = {
|
||||
flexDirection = FlexDirection.Row,
|
||||
flexGrow = 1,
|
||||
width = new StyleLength(new Length(100, LengthUnit.Percent)),
|
||||
height = new StyleLength(new Length(100, LengthUnit.Percent)),
|
||||
backgroundColor = RTheme.s_BackgroundPrimaryColor
|
||||
}
|
||||
};
|
||||
|
||||
VisualElement tabContainer = new() {
|
||||
style = {
|
||||
flexDirection = FlexDirection.Row,
|
||||
width = new StyleLength(new Length(100, LengthUnit.Percent)),
|
||||
}
|
||||
};
|
||||
rootContainer.Add(tabContainer);
|
||||
|
||||
VisualElement tabButtonsContainer = new() {
|
||||
style = {
|
||||
flexDirection = FlexDirection.Column,
|
||||
borderRightWidth = 1,
|
||||
borderRightColor = new Color(0.1f, 0.1f, 0.1f),
|
||||
width = 100,
|
||||
fontSize = 24,
|
||||
backgroundColor = RTheme.s_BackgroundSecondaryColor
|
||||
}
|
||||
};
|
||||
tabContainer.Add(tabButtonsContainer);
|
||||
|
||||
VisualElement contentContainer = new() {
|
||||
style = {
|
||||
flexGrow = 1,
|
||||
paddingLeft = 4,
|
||||
paddingRight = 4,
|
||||
paddingTop = 4,
|
||||
paddingBottom = 4,
|
||||
}
|
||||
};
|
||||
tabContainer.Add(contentContainer);
|
||||
|
||||
for (int i = 0; i < m_Tabs.Count; i++) {
|
||||
Tab tab = m_Tabs[i];
|
||||
int index = i;
|
||||
|
||||
Button button = new(() => SetActiveTab(index)) {
|
||||
text = tab.name,
|
||||
style = {
|
||||
paddingLeft = 8,
|
||||
paddingRight = 8,
|
||||
paddingTop = 4,
|
||||
paddingBottom = 4,
|
||||
borderTopLeftRadius = 0,
|
||||
borderTopRightRadius = 0,
|
||||
borderBottomLeftRadius = 0,
|
||||
borderBottomRightRadius = 0,
|
||||
backgroundColor = new Color(0.2f, 0.2f, 0.2f)
|
||||
}
|
||||
};
|
||||
tabButtonsContainer.Add(button);
|
||||
m_TabButtons.Add(button);
|
||||
|
||||
VisualElement tabContent = tab.container;
|
||||
tabContent.style.display = DisplayStyle.None;
|
||||
contentContainer.Add(tabContent);
|
||||
m_TabContents.Add(tabContent);
|
||||
}
|
||||
|
||||
SetActiveTab(0);
|
||||
return rootContainer;
|
||||
}
|
||||
|
||||
public void AddTab(string name, IView view) {
|
||||
VisualElement tabContainer = new() {
|
||||
name = "rr_tab__container",
|
||||
style = {
|
||||
flexGrow = 1
|
||||
}
|
||||
};
|
||||
|
||||
VisualElement viewVisualElement = view.Build();
|
||||
Assert.IsNotNull(viewVisualElement);
|
||||
|
||||
tabContainer.Add(viewVisualElement);
|
||||
|
||||
m_Tabs.Add(new Tab {
|
||||
name = name,
|
||||
view = view,
|
||||
container = tabContainer
|
||||
});
|
||||
}
|
||||
|
||||
void SetActiveTab(int index) {
|
||||
if (m_CurrentTabIndex >= 0) {
|
||||
m_TabContents[m_CurrentTabIndex].style.display = DisplayStyle.None;
|
||||
m_TabButtons[m_CurrentTabIndex].style.backgroundColor = new Color(0.2f, 0.2f, 0.2f);
|
||||
}
|
||||
|
||||
m_CurrentTabIndex = index;
|
||||
m_TabContents[index].style.display = DisplayStyle.Flex;
|
||||
m_TabButtons[index].style.backgroundColor = new Color(0.3f, 0.3f, 0.3f);
|
||||
}
|
||||
}
|
||||
using System.Collections.Generic;
|
||||
using RebootKit.Engine.UI;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Assertions;
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
namespace RebootKitEditor.RebootWindow {
|
||||
public class TabView : IView {
|
||||
struct Tab {
|
||||
public string name;
|
||||
public IView view;
|
||||
public VisualElement container;
|
||||
}
|
||||
|
||||
readonly List<Tab> m_Tabs = new();
|
||||
readonly List<VisualElement> m_TabContents = new();
|
||||
readonly List<Button> m_TabButtons = new();
|
||||
int m_CurrentTabIndex = -1;
|
||||
|
||||
public void Dispose() {
|
||||
}
|
||||
|
||||
public VisualElement Build() {
|
||||
VisualElement rootContainer = new() {
|
||||
style = {
|
||||
flexDirection = FlexDirection.Row,
|
||||
flexGrow = 1,
|
||||
width = new StyleLength(new Length(100, LengthUnit.Percent)),
|
||||
height = new StyleLength(new Length(100, LengthUnit.Percent)),
|
||||
backgroundColor = RTheme.s_BackgroundPrimaryColor
|
||||
}
|
||||
};
|
||||
|
||||
VisualElement tabContainer = new() {
|
||||
style = {
|
||||
flexDirection = FlexDirection.Row,
|
||||
width = new StyleLength(new Length(100, LengthUnit.Percent)),
|
||||
}
|
||||
};
|
||||
rootContainer.Add(tabContainer);
|
||||
|
||||
VisualElement tabButtonsContainer = new() {
|
||||
style = {
|
||||
flexDirection = FlexDirection.Column,
|
||||
borderRightWidth = 1,
|
||||
borderRightColor = new Color(0.1f, 0.1f, 0.1f),
|
||||
width = 100,
|
||||
fontSize = 24,
|
||||
backgroundColor = RTheme.s_BackgroundSecondaryColor
|
||||
}
|
||||
};
|
||||
tabContainer.Add(tabButtonsContainer);
|
||||
|
||||
VisualElement contentContainer = new() {
|
||||
style = {
|
||||
flexGrow = 1,
|
||||
paddingLeft = 4,
|
||||
paddingRight = 4,
|
||||
paddingTop = 4,
|
||||
paddingBottom = 4,
|
||||
}
|
||||
};
|
||||
tabContainer.Add(contentContainer);
|
||||
|
||||
for (int i = 0; i < m_Tabs.Count; i++) {
|
||||
Tab tab = m_Tabs[i];
|
||||
int index = i;
|
||||
|
||||
Button button = new(() => SetActiveTab(index)) {
|
||||
text = tab.name,
|
||||
style = {
|
||||
paddingLeft = 8,
|
||||
paddingRight = 8,
|
||||
paddingTop = 4,
|
||||
paddingBottom = 4,
|
||||
borderTopLeftRadius = 0,
|
||||
borderTopRightRadius = 0,
|
||||
borderBottomLeftRadius = 0,
|
||||
borderBottomRightRadius = 0,
|
||||
backgroundColor = new Color(0.2f, 0.2f, 0.2f)
|
||||
}
|
||||
};
|
||||
tabButtonsContainer.Add(button);
|
||||
m_TabButtons.Add(button);
|
||||
|
||||
VisualElement tabContent = tab.container;
|
||||
tabContent.style.display = DisplayStyle.None;
|
||||
contentContainer.Add(tabContent);
|
||||
m_TabContents.Add(tabContent);
|
||||
}
|
||||
|
||||
SetActiveTab(0);
|
||||
return rootContainer;
|
||||
}
|
||||
|
||||
public void AddTab(string name, IView view) {
|
||||
VisualElement tabContainer = new() {
|
||||
name = "rr_tab__container",
|
||||
style = {
|
||||
flexGrow = 1
|
||||
}
|
||||
};
|
||||
|
||||
VisualElement viewVisualElement = view.Build();
|
||||
Assert.IsNotNull(viewVisualElement);
|
||||
|
||||
tabContainer.Add(viewVisualElement);
|
||||
|
||||
m_Tabs.Add(new Tab {
|
||||
name = name,
|
||||
view = view,
|
||||
container = tabContainer
|
||||
});
|
||||
}
|
||||
|
||||
void SetActiveTab(int index) {
|
||||
if (m_CurrentTabIndex >= 0) {
|
||||
m_TabContents[m_CurrentTabIndex].style.display = DisplayStyle.None;
|
||||
m_TabButtons[m_CurrentTabIndex].style.backgroundColor = new Color(0.2f, 0.2f, 0.2f);
|
||||
}
|
||||
|
||||
m_CurrentTabIndex = index;
|
||||
m_TabContents[index].style.display = DisplayStyle.Flex;
|
||||
m_TabButtons[index].style.backgroundColor = new Color(0.3f, 0.3f, 0.3f);
|
||||
}
|
||||
}
|
||||
}
|
||||
0
Editor/RebootWindow/TabView.cs.meta
Normal file → Executable file
0
Editor/RebootWindow/TabView.cs.meta
Normal file → Executable file
210
Editor/RebootWindow/WorldsView.cs
Normal file → Executable file
210
Editor/RebootWindow/WorldsView.cs
Normal file → Executable file
@@ -1,106 +1,106 @@
|
||||
using RebootKit.Engine;
|
||||
using RebootKit.Engine.Services.Simulation;
|
||||
using RebootKit.Engine.UI;
|
||||
using RebootKitEditor.Utils;
|
||||
using UnityEditor;
|
||||
using UnityEditor.SceneManagement;
|
||||
using UnityEngine;
|
||||
using UnityEngine.SceneManagement;
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
namespace RebootKitEditor.RebootWindow {
|
||||
public class WorldsView : IView {
|
||||
public void Dispose() {
|
||||
}
|
||||
|
||||
public VisualElement Build() {
|
||||
VisualElement root = new() {
|
||||
style = {
|
||||
paddingBottom = 4,
|
||||
paddingTop = 4,
|
||||
paddingLeft = 4,
|
||||
paddingRight = 4,
|
||||
}
|
||||
};
|
||||
|
||||
WorldConfigAsset[] worlds = AssetDatabaseEx.LoadAllAssets<WorldConfigAsset>();
|
||||
foreach (WorldConfigAsset worldConfigAsset in worlds) {
|
||||
VisualElement worldView = CreateWorldView(worldConfigAsset);
|
||||
root.Add(worldView);
|
||||
}
|
||||
|
||||
return root;
|
||||
}
|
||||
|
||||
VisualElement CreateWorldView(WorldConfigAsset worldConfigAsset) {
|
||||
VisualElement root = new() {
|
||||
style = {
|
||||
backgroundColor = new Color(0.1f, 0.1f, 0.1f),
|
||||
paddingBottom = 4,
|
||||
paddingTop = 4,
|
||||
paddingLeft = 4,
|
||||
paddingRight = 4,
|
||||
borderBottomLeftRadius = 4,
|
||||
borderBottomRightRadius = 4
|
||||
}
|
||||
};
|
||||
|
||||
Label label = new(worldConfigAsset.name) {
|
||||
style = {
|
||||
color = new Color(0.7f, 0.9f, 0.9f),
|
||||
unityFontStyleAndWeight = FontStyle.Bold
|
||||
}
|
||||
};
|
||||
root.Add(label);
|
||||
|
||||
Button openButton = new(() => OpenWorldScenes(worldConfigAsset)) {
|
||||
text = "Open",
|
||||
style = {
|
||||
backgroundColor = new Color(0.2f, 0.2f, 0.2f),
|
||||
paddingBottom = 4,
|
||||
paddingTop = 4,
|
||||
paddingLeft = 4,
|
||||
paddingRight = 4,
|
||||
borderBottomLeftRadius = 4,
|
||||
borderBottomRightRadius = 4
|
||||
}
|
||||
};
|
||||
root.Add(openButton);
|
||||
|
||||
return root;
|
||||
}
|
||||
|
||||
static void OpenWorldScenes(WorldConfigAsset worldConfigAsset) {
|
||||
if (worldConfigAsset == null) {
|
||||
Debug.LogError("WorldConfigAsset is null");
|
||||
return;
|
||||
}
|
||||
|
||||
// Load first scene from build settings
|
||||
string mainScenePath = GetScenePathByBuildIndex(RConsts.k_MainSceneBuildIndex);
|
||||
if (mainScenePath == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
EditorSceneManager.OpenScene(mainScenePath, OpenSceneMode.Single);
|
||||
|
||||
// Load world scene
|
||||
string worldScenePath = AssetDatabase.GUIDToAssetPath(worldConfigAsset.Config.mainScene.AssetGUID);
|
||||
if (string.IsNullOrEmpty(worldScenePath)) {
|
||||
Debug.LogError($"WorldConfigAsset {worldConfigAsset.name} has invalid main scene path");
|
||||
return;
|
||||
}
|
||||
|
||||
SceneManager.SetActiveScene(EditorSceneManager.OpenScene(worldScenePath, OpenSceneMode.Additive));
|
||||
}
|
||||
|
||||
static string GetScenePathByBuildIndex(int buildIndex) {
|
||||
if (buildIndex < 0 || buildIndex >= EditorBuildSettings.scenes.Length) {
|
||||
Debug.LogError($"Build index {buildIndex} out of range. Total scenes in build: {EditorBuildSettings.scenes.Length}");
|
||||
return null;
|
||||
}
|
||||
|
||||
return EditorBuildSettings.scenes[buildIndex].path;
|
||||
}
|
||||
}
|
||||
using RebootKit.Engine;
|
||||
using RebootKit.Engine.Services.Simulation;
|
||||
using RebootKit.Engine.UI;
|
||||
using RebootKitEditor.Utils;
|
||||
using UnityEditor;
|
||||
using UnityEditor.SceneManagement;
|
||||
using UnityEngine;
|
||||
using UnityEngine.SceneManagement;
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
namespace RebootKitEditor.RebootWindow {
|
||||
public class WorldsView : IView {
|
||||
public void Dispose() {
|
||||
}
|
||||
|
||||
public VisualElement Build() {
|
||||
VisualElement root = new() {
|
||||
style = {
|
||||
paddingBottom = 4,
|
||||
paddingTop = 4,
|
||||
paddingLeft = 4,
|
||||
paddingRight = 4,
|
||||
}
|
||||
};
|
||||
|
||||
WorldConfigAsset[] worlds = AssetDatabaseEx.LoadAllAssets<WorldConfigAsset>();
|
||||
foreach (WorldConfigAsset worldConfigAsset in worlds) {
|
||||
VisualElement worldView = CreateWorldView(worldConfigAsset);
|
||||
root.Add(worldView);
|
||||
}
|
||||
|
||||
return root;
|
||||
}
|
||||
|
||||
VisualElement CreateWorldView(WorldConfigAsset worldConfigAsset) {
|
||||
VisualElement root = new() {
|
||||
style = {
|
||||
backgroundColor = new Color(0.1f, 0.1f, 0.1f),
|
||||
paddingBottom = 4,
|
||||
paddingTop = 4,
|
||||
paddingLeft = 4,
|
||||
paddingRight = 4,
|
||||
borderBottomLeftRadius = 4,
|
||||
borderBottomRightRadius = 4
|
||||
}
|
||||
};
|
||||
|
||||
Label label = new(worldConfigAsset.name) {
|
||||
style = {
|
||||
color = new Color(0.7f, 0.9f, 0.9f),
|
||||
unityFontStyleAndWeight = FontStyle.Bold
|
||||
}
|
||||
};
|
||||
root.Add(label);
|
||||
|
||||
Button openButton = new(() => OpenWorldScenes(worldConfigAsset)) {
|
||||
text = "Open",
|
||||
style = {
|
||||
backgroundColor = new Color(0.2f, 0.2f, 0.2f),
|
||||
paddingBottom = 4,
|
||||
paddingTop = 4,
|
||||
paddingLeft = 4,
|
||||
paddingRight = 4,
|
||||
borderBottomLeftRadius = 4,
|
||||
borderBottomRightRadius = 4
|
||||
}
|
||||
};
|
||||
root.Add(openButton);
|
||||
|
||||
return root;
|
||||
}
|
||||
|
||||
static void OpenWorldScenes(WorldConfigAsset worldConfigAsset) {
|
||||
if (worldConfigAsset == null) {
|
||||
Debug.LogError("WorldConfigAsset is null");
|
||||
return;
|
||||
}
|
||||
|
||||
// Load first scene from build settings
|
||||
string mainScenePath = GetScenePathByBuildIndex(RConsts.k_MainSceneBuildIndex);
|
||||
if (mainScenePath == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
EditorSceneManager.OpenScene(mainScenePath, OpenSceneMode.Single);
|
||||
|
||||
// Load world scene
|
||||
string worldScenePath = AssetDatabase.GUIDToAssetPath(worldConfigAsset.Config.mainScene.AssetGUID);
|
||||
if (string.IsNullOrEmpty(worldScenePath)) {
|
||||
Debug.LogError($"WorldConfigAsset {worldConfigAsset.name} has invalid main scene path");
|
||||
return;
|
||||
}
|
||||
|
||||
SceneManager.SetActiveScene(EditorSceneManager.OpenScene(worldScenePath, OpenSceneMode.Additive));
|
||||
}
|
||||
|
||||
static string GetScenePathByBuildIndex(int buildIndex) {
|
||||
if (buildIndex < 0 || buildIndex >= EditorBuildSettings.scenes.Length) {
|
||||
Debug.LogError($"Build index {buildIndex} out of range. Total scenes in build: {EditorBuildSettings.scenes.Length}");
|
||||
return null;
|
||||
}
|
||||
|
||||
return EditorBuildSettings.scenes[buildIndex].path;
|
||||
}
|
||||
}
|
||||
}
|
||||
0
Editor/RebootWindow/WorldsView.cs.meta
Normal file → Executable file
0
Editor/RebootWindow/WorldsView.cs.meta
Normal file → Executable file
0
Editor/Utils.meta
Normal file → Executable file
0
Editor/Utils.meta
Normal file → Executable file
32
Editor/Utils/AssetDatabaseEx.cs
Normal file → Executable file
32
Editor/Utils/AssetDatabaseEx.cs
Normal file → Executable file
@@ -1,17 +1,17 @@
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace RebootKitEditor.Utils {
|
||||
public static class AssetDatabaseEx {
|
||||
public static T[] LoadAllAssets<T>() where T : Object {
|
||||
string[] guids = AssetDatabase.FindAssets($"t:{typeof(T).Name}");
|
||||
T[] assets = new T[guids.Length];
|
||||
for (int i = 0; i < guids.Length; i++) {
|
||||
string path = AssetDatabase.GUIDToAssetPath(guids[i]);
|
||||
assets[i] = AssetDatabase.LoadAssetAtPath<T>(path);
|
||||
}
|
||||
|
||||
return assets;
|
||||
}
|
||||
}
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace RebootKitEditor.Utils {
|
||||
public static class AssetDatabaseEx {
|
||||
public static T[] LoadAllAssets<T>() where T : Object {
|
||||
string[] guids = AssetDatabase.FindAssets($"t:{typeof(T).Name}");
|
||||
T[] assets = new T[guids.Length];
|
||||
for (int i = 0; i < guids.Length; i++) {
|
||||
string path = AssetDatabase.GUIDToAssetPath(guids[i]);
|
||||
assets[i] = AssetDatabase.LoadAssetAtPath<T>(path);
|
||||
}
|
||||
|
||||
return assets;
|
||||
}
|
||||
}
|
||||
}
|
||||
0
Editor/Utils/AssetDatabaseEx.cs.meta
Normal file → Executable file
0
Editor/Utils/AssetDatabaseEx.cs.meta
Normal file → Executable file
0
Editor/Utils/CVarSerializedPropertiesFinder.cs
Normal file → Executable file
0
Editor/Utils/CVarSerializedPropertiesFinder.cs
Normal file → Executable file
0
Editor/Utils/CVarSerializedPropertiesFinder.cs.meta
Normal file → Executable file
0
Editor/Utils/CVarSerializedPropertiesFinder.cs.meta
Normal file → Executable file
0
Editor/VisualElements.meta
Normal file → Executable file
0
Editor/VisualElements.meta
Normal file → Executable file
0
Editor/VisualElements/CVarPropertyField.cs
Normal file → Executable file
0
Editor/VisualElements/CVarPropertyField.cs
Normal file → Executable file
0
Editor/VisualElements/CVarPropertyField.cs.meta
Normal file → Executable file
0
Editor/VisualElements/CVarPropertyField.cs.meta
Normal file → Executable file
0
Runtime/Engine.meta
Normal file → Executable file
0
Runtime/Engine.meta
Normal file → Executable file
0
Runtime/Engine/Code.meta
Normal file → Executable file
0
Runtime/Engine/Code.meta
Normal file → Executable file
0
Runtime/Engine/Code/Components.meta
Normal file → Executable file
0
Runtime/Engine/Code/Components.meta
Normal file → Executable file
101
Runtime/Engine/Code/Components/CopyTransform.cs
Normal file → Executable file
101
Runtime/Engine/Code/Components/CopyTransform.cs
Normal file → Executable file
@@ -1,39 +1,64 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace RebootKit.Engine.Components {
|
||||
[Flags]
|
||||
public enum TransformComponents {
|
||||
None = 0,
|
||||
Position = 1 << 0,
|
||||
Rotation = 1 << 1,
|
||||
Scale = 1 << 2,
|
||||
All = Position | Rotation | Scale
|
||||
}
|
||||
|
||||
[DefaultExecutionOrder(100)]
|
||||
public class CopyTransform : MonoBehaviour {
|
||||
[SerializeField] TransformComponents m_Components = TransformComponents.All;
|
||||
[SerializeField] Transform m_Source;
|
||||
|
||||
Transform m_Transform;
|
||||
|
||||
void Awake() {
|
||||
m_Transform = transform;
|
||||
}
|
||||
|
||||
void LateUpdate() {
|
||||
if (m_Components.HasFlag(TransformComponents.Position)) {
|
||||
m_Transform.position = m_Source.position;
|
||||
}
|
||||
|
||||
if (m_Components.HasFlag(TransformComponents.Rotation)) {
|
||||
m_Transform.rotation = m_Source.rotation;
|
||||
}
|
||||
|
||||
if (m_Components.HasFlag(TransformComponents.Scale)) {
|
||||
m_Transform.localScale = m_Source.localScale;
|
||||
}
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace RebootKit.Engine.Components {
|
||||
[Flags]
|
||||
public enum TransformComponents {
|
||||
None = 0,
|
||||
Position = 1 << 0,
|
||||
Rotation = 1 << 1,
|
||||
Scale = 1 << 2,
|
||||
All = Position | Rotation | Scale
|
||||
}
|
||||
|
||||
[DefaultExecutionOrder(100)]
|
||||
public class CopyTransform : MonoBehaviour {
|
||||
enum UpdateLoop {
|
||||
Update,
|
||||
LateUpdate,
|
||||
FixedUpdate
|
||||
}
|
||||
|
||||
[SerializeField] TransformComponents m_Components = TransformComponents.All;
|
||||
[SerializeField] Transform m_Source;
|
||||
[SerializeField] UpdateLoop m_UpdateLoop = UpdateLoop.LateUpdate;
|
||||
|
||||
Transform m_Transform;
|
||||
|
||||
void Awake() {
|
||||
m_Transform = transform;
|
||||
}
|
||||
|
||||
void FixedUpdate() {
|
||||
if (m_UpdateLoop == UpdateLoop.FixedUpdate) {
|
||||
CopyTransformComponents();
|
||||
}
|
||||
}
|
||||
|
||||
void Update() {
|
||||
if (m_UpdateLoop == UpdateLoop.Update) {
|
||||
CopyTransformComponents();
|
||||
}
|
||||
}
|
||||
|
||||
void LateUpdate() {
|
||||
if (m_UpdateLoop == UpdateLoop.LateUpdate) {
|
||||
CopyTransformComponents();
|
||||
}
|
||||
}
|
||||
|
||||
void CopyTransformComponents() {
|
||||
if (m_Components.HasFlag(TransformComponents.Position)) {
|
||||
m_Transform.position = m_Source.position;
|
||||
}
|
||||
|
||||
if (m_Components.HasFlag(TransformComponents.Rotation)) {
|
||||
m_Transform.rotation = m_Source.rotation;
|
||||
}
|
||||
|
||||
if (m_Components.HasFlag(TransformComponents.Scale)) {
|
||||
m_Transform.localScale = m_Source.localScale;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
0
Runtime/Engine/Code/Components/CopyTransform.cs.meta
Normal file → Executable file
0
Runtime/Engine/Code/Components/CopyTransform.cs.meta
Normal file → Executable file
0
Runtime/Engine/Code/EngineConfigAsset.cs
Normal file → Executable file
0
Runtime/Engine/Code/EngineConfigAsset.cs
Normal file → Executable file
0
Runtime/Engine/Code/EngineConfigAsset.cs.meta
Normal file → Executable file
0
Runtime/Engine/Code/EngineConfigAsset.cs.meta
Normal file → Executable file
2
Runtime/Engine/Code/EngineCoreServicesAsset.cs
Normal file → Executable file
2
Runtime/Engine/Code/EngineCoreServicesAsset.cs
Normal file → Executable file
@@ -1,6 +1,5 @@
|
||||
using RebootKit.Engine.Foundation;
|
||||
using RebootKit.Engine.Services.Console;
|
||||
using RebootKit.Engine.Services.GameMode;
|
||||
using RebootKit.Engine.Services.Input;
|
||||
using RebootKit.Engine.Services.Simulation;
|
||||
using UnityEngine;
|
||||
@@ -11,6 +10,5 @@ namespace RebootKit.Engine {
|
||||
public ServiceAsset<ConsoleService> consoleService;
|
||||
public ServiceAsset<InputService> inputService;
|
||||
public ServiceAsset<WorldService> worldService;
|
||||
public ServiceAsset<GameModesService> gameService;
|
||||
}
|
||||
}
|
||||
0
Runtime/Engine/Code/EngineCoreServicesAsset.cs.meta
Normal file → Executable file
0
Runtime/Engine/Code/EngineCoreServicesAsset.cs.meta
Normal file → Executable file
0
Runtime/Engine/Code/Extensions.meta
Normal file → Executable file
0
Runtime/Engine/Code/Extensions.meta
Normal file → Executable file
0
Runtime/Engine/Code/Extensions/ColorEx.cs
Normal file → Executable file
0
Runtime/Engine/Code/Extensions/ColorEx.cs
Normal file → Executable file
0
Runtime/Engine/Code/Extensions/ColorEx.cs.meta
Normal file → Executable file
0
Runtime/Engine/Code/Extensions/ColorEx.cs.meta
Normal file → Executable file
0
Runtime/Engine/Code/Extensions/GameObjectEx.cs
Normal file → Executable file
0
Runtime/Engine/Code/Extensions/GameObjectEx.cs
Normal file → Executable file
0
Runtime/Engine/Code/Extensions/GameObjectEx.cs.meta
Normal file → Executable file
0
Runtime/Engine/Code/Extensions/GameObjectEx.cs.meta
Normal file → Executable file
0
Runtime/Engine/Code/Extensions/LayerMaskEx.cs
Normal file → Executable file
0
Runtime/Engine/Code/Extensions/LayerMaskEx.cs
Normal file → Executable file
0
Runtime/Engine/Code/Extensions/LayerMaskEx.cs.meta
Normal file → Executable file
0
Runtime/Engine/Code/Extensions/LayerMaskEx.cs.meta
Normal file → Executable file
0
Runtime/Engine/Code/Extensions/ListEx.cs
Normal file → Executable file
0
Runtime/Engine/Code/Extensions/ListEx.cs
Normal file → Executable file
0
Runtime/Engine/Code/Extensions/ListEx.cs.meta
Normal file → Executable file
0
Runtime/Engine/Code/Extensions/ListEx.cs.meta
Normal file → Executable file
0
Runtime/Engine/Code/Extensions/TransformEx.cs
Normal file → Executable file
0
Runtime/Engine/Code/Extensions/TransformEx.cs
Normal file → Executable file
0
Runtime/Engine/Code/Extensions/TransformEx.cs.meta
Normal file → Executable file
0
Runtime/Engine/Code/Extensions/TransformEx.cs.meta
Normal file → Executable file
0
Runtime/Engine/Code/Extensions/Vector3Ex.cs
Normal file → Executable file
0
Runtime/Engine/Code/Extensions/Vector3Ex.cs
Normal file → Executable file
0
Runtime/Engine/Code/Extensions/Vector3Ex.cs.meta
Normal file → Executable file
0
Runtime/Engine/Code/Extensions/Vector3Ex.cs.meta
Normal file → Executable file
0
Runtime/Engine/Code/Foundation.meta
Normal file → Executable file
0
Runtime/Engine/Code/Foundation.meta
Normal file → Executable file
0
Runtime/Engine/Code/Foundation/ConfigVar.cs
Normal file → Executable file
0
Runtime/Engine/Code/Foundation/ConfigVar.cs
Normal file → Executable file
0
Runtime/Engine/Code/Foundation/ConfigVar.cs.meta
Normal file → Executable file
0
Runtime/Engine/Code/Foundation/ConfigVar.cs.meta
Normal file → Executable file
0
Runtime/Engine/Code/Foundation/ConfigVarsContainer.cs
Normal file → Executable file
0
Runtime/Engine/Code/Foundation/ConfigVarsContainer.cs
Normal file → Executable file
0
Runtime/Engine/Code/Foundation/ConfigVarsContainer.cs.meta
Normal file → Executable file
0
Runtime/Engine/Code/Foundation/ConfigVarsContainer.cs.meta
Normal file → Executable file
16
Runtime/Engine/Code/Foundation/ConstantsAsset.cs
Normal file → Executable file
16
Runtime/Engine/Code/Foundation/ConstantsAsset.cs
Normal file → Executable file
@@ -1,9 +1,9 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace RebootKit.Engine.Foundation {
|
||||
public class ConstantsAsset<T> : RAsset {
|
||||
[SerializeField] T m_Value;
|
||||
|
||||
public T Value => m_Value;
|
||||
}
|
||||
using UnityEngine;
|
||||
|
||||
namespace RebootKit.Engine.Foundation {
|
||||
public class ConstantsAsset<T> : RAsset {
|
||||
[SerializeField] T m_Value;
|
||||
|
||||
public T Value => m_Value;
|
||||
}
|
||||
}
|
||||
0
Runtime/Engine/Code/Foundation/ConstantsAsset.cs.meta
Normal file → Executable file
0
Runtime/Engine/Code/Foundation/ConstantsAsset.cs.meta
Normal file → Executable file
12
Runtime/Engine/Code/Foundation/ConstsColorAsset.cs
Normal file → Executable file
12
Runtime/Engine/Code/Foundation/ConstsColorAsset.cs
Normal file → Executable file
@@ -1,7 +1,7 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace RebootKit.Engine.Foundation {
|
||||
[CreateAssetMenu(menuName = RConsts.k_CreateAssetMenu + "Constants/Consts Color")]
|
||||
public class ConstsColorAsset : ConstantsAsset<Color> {
|
||||
}
|
||||
using UnityEngine;
|
||||
|
||||
namespace RebootKit.Engine.Foundation {
|
||||
[CreateAssetMenu(menuName = RConsts.k_CreateAssetMenu + "Constants/Consts Color")]
|
||||
public class ConstsColorAsset : ConstantsAsset<Color> {
|
||||
}
|
||||
}
|
||||
0
Runtime/Engine/Code/Foundation/ConstsColorAsset.cs.meta
Normal file → Executable file
0
Runtime/Engine/Code/Foundation/ConstsColorAsset.cs.meta
Normal file → Executable file
12
Runtime/Engine/Code/Foundation/ConstsFloatAsset.cs
Normal file → Executable file
12
Runtime/Engine/Code/Foundation/ConstsFloatAsset.cs
Normal file → Executable file
@@ -1,7 +1,7 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace RebootKit.Engine.Foundation {
|
||||
[CreateAssetMenu(menuName = RConsts.k_CreateAssetMenu + "Constants/Consts Float")]
|
||||
public class ConstsFloatAsset : ConstantsAsset<float> {
|
||||
}
|
||||
using UnityEngine;
|
||||
|
||||
namespace RebootKit.Engine.Foundation {
|
||||
[CreateAssetMenu(menuName = RConsts.k_CreateAssetMenu + "Constants/Consts Float")]
|
||||
public class ConstsFloatAsset : ConstantsAsset<float> {
|
||||
}
|
||||
}
|
||||
0
Runtime/Engine/Code/Foundation/ConstsFloatAsset.cs.meta
Normal file → Executable file
0
Runtime/Engine/Code/Foundation/ConstsFloatAsset.cs.meta
Normal file → Executable file
12
Runtime/Engine/Code/Foundation/ConstsIntAsset.cs
Normal file → Executable file
12
Runtime/Engine/Code/Foundation/ConstsIntAsset.cs
Normal file → Executable file
@@ -1,7 +1,7 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace RebootKit.Engine.Foundation {
|
||||
[CreateAssetMenu(menuName = RConsts.k_CreateAssetMenu + "Constants/Consts Int")]
|
||||
public class ConstsIntAsset : ConfigAsset<int> {
|
||||
}
|
||||
using UnityEngine;
|
||||
|
||||
namespace RebootKit.Engine.Foundation {
|
||||
[CreateAssetMenu(menuName = RConsts.k_CreateAssetMenu + "Constants/Consts Int")]
|
||||
public class ConstsIntAsset : ConfigAsset<int> {
|
||||
}
|
||||
}
|
||||
0
Runtime/Engine/Code/Foundation/ConstsIntAsset.cs.meta
Normal file → Executable file
0
Runtime/Engine/Code/Foundation/ConstsIntAsset.cs.meta
Normal file → Executable file
72
Runtime/Engine/Code/Foundation/ConstsProperty.cs
Normal file → Executable file
72
Runtime/Engine/Code/Foundation/ConstsProperty.cs
Normal file → Executable file
@@ -1,37 +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;
|
||||
}
|
||||
}
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
0
Runtime/Engine/Code/Foundation/ConstsProperty.cs.meta
Normal file → Executable file
0
Runtime/Engine/Code/Foundation/ConstsProperty.cs.meta
Normal file → Executable file
0
Runtime/Engine/Code/Foundation/ControllerAsset.cs
Normal file → Executable file
0
Runtime/Engine/Code/Foundation/ControllerAsset.cs
Normal file → Executable file
0
Runtime/Engine/Code/Foundation/ControllerAsset.cs.meta
Normal file → Executable file
0
Runtime/Engine/Code/Foundation/ControllerAsset.cs.meta
Normal file → Executable file
0
Runtime/Engine/Code/Foundation/DIContext.cs
Normal file → Executable file
0
Runtime/Engine/Code/Foundation/DIContext.cs
Normal file → Executable file
0
Runtime/Engine/Code/Foundation/DIContext.cs.meta
Normal file → Executable file
0
Runtime/Engine/Code/Foundation/DIContext.cs.meta
Normal file → Executable file
0
Runtime/Engine/Code/Foundation/DisposableListener.cs
Normal file → Executable file
0
Runtime/Engine/Code/Foundation/DisposableListener.cs
Normal file → Executable file
0
Runtime/Engine/Code/Foundation/DisposableListener.cs.meta
Normal file → Executable file
0
Runtime/Engine/Code/Foundation/DisposableListener.cs.meta
Normal file → Executable file
0
Runtime/Engine/Code/Foundation/Either.cs
Normal file → Executable file
0
Runtime/Engine/Code/Foundation/Either.cs
Normal file → Executable file
0
Runtime/Engine/Code/Foundation/Either.cs.meta
Normal file → Executable file
0
Runtime/Engine/Code/Foundation/Either.cs.meta
Normal file → Executable file
0
Runtime/Engine/Code/Foundation/FloatRange.cs
Normal file → Executable file
0
Runtime/Engine/Code/Foundation/FloatRange.cs
Normal file → Executable file
0
Runtime/Engine/Code/Foundation/FloatRange.cs.meta
Normal file → Executable file
0
Runtime/Engine/Code/Foundation/FloatRange.cs.meta
Normal file → Executable file
12
Runtime/Engine/Code/Foundation/IController.cs
Normal file → Executable file
12
Runtime/Engine/Code/Foundation/IController.cs
Normal file → Executable file
@@ -96,21 +96,21 @@ namespace RebootKit.Engine.Foundation {
|
||||
}
|
||||
|
||||
public static class ControllersManagerUtils {
|
||||
public static void Add(this ControllersManager<IController> manager, ControllerAsset asset, DIContext context) {
|
||||
IController controller = asset.Create(context);
|
||||
public static void Add(this ControllersManager<IController> manager, ControllerAsset asset) {
|
||||
IController controller = asset.Create();
|
||||
manager.Add(controller);
|
||||
}
|
||||
|
||||
public static void Add(this ControllersManager<IController> manager, List<ControllerAsset> controllerAsset, DIContext context) {
|
||||
public static void Add(this ControllersManager<IController> manager, List<ControllerAsset> controllerAsset) {
|
||||
foreach (ControllerAsset asset in controllerAsset) {
|
||||
IController controller = asset.Create(context);
|
||||
IController controller = asset.Create();
|
||||
manager.Add(controller);
|
||||
}
|
||||
}
|
||||
|
||||
public static void Add(this ControllersManager<IController> manager, ControllerAsset[] controllerAsset, DIContext context) {
|
||||
public static void Add(this ControllersManager<IController> manager, ControllerAsset[] controllerAsset) {
|
||||
foreach (ControllerAsset asset in controllerAsset) {
|
||||
IController controller = asset.Create(context);
|
||||
IController controller = asset.Create();
|
||||
manager.Add(controller);
|
||||
}
|
||||
}
|
||||
|
||||
0
Runtime/Engine/Code/Foundation/IController.cs.meta
Normal file → Executable file
0
Runtime/Engine/Code/Foundation/IController.cs.meta
Normal file → Executable file
8
Runtime/Engine/Code/Foundation/IFactory.cs
Normal file → Executable file
8
Runtime/Engine/Code/Foundation/IFactory.cs
Normal file → Executable file
@@ -1,11 +1,15 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace RebootKit.Engine.Foundation {
|
||||
public interface IFactory<out TProd> {
|
||||
TProd Create();
|
||||
}
|
||||
|
||||
public interface IFactoryDI<out TProd> {
|
||||
TProd Create(DIContext context);
|
||||
}
|
||||
|
||||
public abstract class FactoryAsset<TProd> : ScriptableObject, IFactoryDI<TProd> where TProd : class {
|
||||
public abstract TProd Create(DIContext context);
|
||||
public abstract class FactoryAsset<TProd> : ScriptableObject, IFactory<TProd> where TProd : class {
|
||||
public abstract TProd Create();
|
||||
}
|
||||
}
|
||||
0
Runtime/Engine/Code/Foundation/IFactory.cs.meta
Normal file → Executable file
0
Runtime/Engine/Code/Foundation/IFactory.cs.meta
Normal file → Executable file
0
Runtime/Engine/Code/Foundation/IPredicate.cs
Normal file → Executable file
0
Runtime/Engine/Code/Foundation/IPredicate.cs
Normal file → Executable file
0
Runtime/Engine/Code/Foundation/IPredicate.cs.meta
Normal file → Executable file
0
Runtime/Engine/Code/Foundation/IPredicate.cs.meta
Normal file → Executable file
0
Runtime/Engine/Code/Foundation/IService.cs
Normal file → Executable file
0
Runtime/Engine/Code/Foundation/IService.cs
Normal file → Executable file
0
Runtime/Engine/Code/Foundation/IService.cs.meta
Normal file → Executable file
0
Runtime/Engine/Code/Foundation/IService.cs.meta
Normal file → Executable file
0
Runtime/Engine/Code/Foundation/Logger.cs
Normal file → Executable file
0
Runtime/Engine/Code/Foundation/Logger.cs
Normal file → Executable file
0
Runtime/Engine/Code/Foundation/Logger.cs.meta
Normal file → Executable file
0
Runtime/Engine/Code/Foundation/Logger.cs.meta
Normal file → Executable file
22
Runtime/Engine/Code/Foundation/SceneContext.cs
Normal file → Executable file
22
Runtime/Engine/Code/Foundation/SceneContext.cs
Normal file → Executable file
@@ -1,5 +1,4 @@
|
||||
using RebootKit.Engine.Main;
|
||||
using UnityEngine;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Assertions;
|
||||
|
||||
namespace RebootKit.Engine.Foundation {
|
||||
@@ -12,24 +11,23 @@ namespace RebootKit.Engine.Foundation {
|
||||
}
|
||||
|
||||
[DefaultExecutionOrder(-1000)]
|
||||
public class SceneContext : MonoBehaviour, IDependencyInstaller {
|
||||
public class SceneContext : MonoBehaviour {
|
||||
static readonly Logger s_logger = new(nameof(SceneContext));
|
||||
|
||||
[SerializeField] SceneDependencyInstaller[] m_Installers;
|
||||
|
||||
DIContext m_DIContext;
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
m_DIContext = new DIContext();
|
||||
|
||||
public void Install(DIContext context) {
|
||||
s_logger.Info("Installing scene dependency installers");
|
||||
foreach (SceneDependencyInstaller installer in m_Installers) {
|
||||
installer.Install(context);
|
||||
installer.Install(m_DIContext);
|
||||
}
|
||||
|
||||
foreach (GameObject root in gameObject.scene.GetRootGameObjects()) {
|
||||
m_DIContext.InjectGameObject(root);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
0
Runtime/Engine/Code/Foundation/SceneContext.cs.meta
Normal file → Executable file
0
Runtime/Engine/Code/Foundation/SceneContext.cs.meta
Normal file → Executable file
0
Runtime/Engine/Code/Foundation/SerializableGuid.cs
Normal file → Executable file
0
Runtime/Engine/Code/Foundation/SerializableGuid.cs
Normal file → Executable file
0
Runtime/Engine/Code/Foundation/SerializableGuid.cs.meta
Normal file → Executable file
0
Runtime/Engine/Code/Foundation/SerializableGuid.cs.meta
Normal file → Executable file
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user