This commit is contained in:
2025-03-30 16:06:57 +02:00
parent e62bd2aa6d
commit 623ba3f621
148 changed files with 2773 additions and 1441 deletions

View File

@@ -1,55 +0,0 @@
using RebootKit.Engine.Services.Console;
using UnityEditor;
using UnityEditor.UIElements;
using UnityEngine.UIElements;
namespace RebootKitEditor.Inspectors {
[CustomEditor(typeof(CVarAsset))]
public class CVarAssetInspector : Editor {
public override VisualElement CreateInspectorGUI() {
SerializedProperty cvarProperty = serializedObject.FindProperty("_cvar");
CVarSerializedProperties properties = CVarSerializedPropertiesFinder.Find(cvarProperty);
VisualElement container = new();
container.Add(new PropertyField(properties.Flags));
container.Add(new PropertyField(properties.Name));
PropertyField descriptionField = new PropertyField(properties.Description);
container.Add(descriptionField);
container.Add(new PropertyField(properties.ValueKind));
container.Add(new PropertyField(properties.ValueNumber));
container.Add(new PropertyField(properties.ValueString));
return container;
}
}
public struct CVarSerializedProperties {
public SerializedProperty Flags;
public SerializedProperty Name;
public SerializedProperty Description;
public SerializedProperty ValueKind;
public SerializedProperty ValueNumber;
public SerializedProperty ValueString;
}
public static class CVarSerializedPropertiesFinder {
public static CVarSerializedProperties Find(SerializedProperty cvar) {
CVarSerializedProperties properties = new();
properties.Flags = cvar.FindPropertyRelative("Flags");
properties.Name = cvar.FindPropertyRelative("Name");
properties.Description = cvar.FindPropertyRelative("Description");
SerializedProperty value = cvar.FindPropertyRelative("DefaultValue");
if (value != null) {
properties.ValueKind = value.FindPropertyRelative("Kind");
properties.ValueNumber = value.FindPropertyRelative("NumberValue");
properties.ValueString = value.FindPropertyRelative("StringValue");
}
return properties;
}
}
}

View File

@@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: 43a78b204a01438ea8e99757046c213d
timeCreated: 1741641043

View File

@@ -1,23 +0,0 @@
using UnityEditor;
using UnityEngine;
using UnityEngine.UIElements;
namespace SzafaKitEditor.Oracle {
public class OracleWindow : EditorWindow {
[SerializeField]
private VisualTreeAsset m_VisualTreeAsset = default;
[MenuItem("Szafa/Oracle")]
public static void ShowWindow() {
OracleWindow wnd = GetWindow<OracleWindow>();
wnd.titleContent = new GUIContent("OracleWindow");
}
public void CreateGUI() {
VisualElement root = rootVisualElement;
VisualElement labelFromUXML = m_VisualTreeAsset.Instantiate();
root.Add(labelFromUXML);
}
}
}

View File

@@ -1,13 +0,0 @@
fileFormatVersion: 2
guid: e2bd75a497487ee49a0a51cc223c552d
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences:
- m_VisualTreeAsset: {fileID: 9197481963319205126, guid: 852055ed179f6f546b9f0ff34d97f4fb,
type: 3}
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,5 +0,0 @@
.custom-label {
font-size: 20px;
-unity-font-style: bold;
color: rgb(68, 138, 255);
}

View File

@@ -1,10 +0,0 @@
<engine:UXML xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:engine="UnityEngine.UIElements" xmlns:editor="UnityEditor.UIElements" noNamespaceSchemaLocation="../../../../UIElementsSchema/UIElements.xsd" editor-extension-mode="False">
<Style src="project://database/Packages/com.szafastudio.szafakit/Editor/Oracle/OracleWindow.uss?fileID=7433441132597879392&amp;guid=56459608f8e71f140b0933d6689a0846&amp;type=3#OracleWindow" />
<engine:TabView>
<engine:Tab label="General">
<engine:Label text="Welcome to my szafa" style="-unity-font-style: bold; font-size: 48px;" />
</engine:Tab>
<engine:Tab label="Startup" />
<engine:Tab label="Build" />
</engine:TabView>
</engine:UXML>

View File

@@ -1,26 +0,0 @@
using RebootKit.Engine;
using UnityEditor;
using UnityEditor.UIElements;
using UnityEngine;
using UnityEngine.UIElements;
namespace SzafaKitEditor.Oracle {
[CustomEditor(typeof(RR))]
public class SzKEngineEditor : Editor {
private EngineConfigAsset _engineConfigAsset;
public override VisualElement CreateInspectorGUI() {
VisualElement inspector = new VisualElement();
_engineConfigAsset = Resources.Load<EngineConfigAsset>(RConsts.EngineConfigResourcesPath);
if (_engineConfigAsset == null) {
inspector.Add(new Label($"Couldn't load engine config from resources: {RConsts.EngineConfigResourcesPath}"));
return inspector;
}
inspector.Add(new Label("Config:"));
InspectorElement.FillDefaultInspector(inspector, new SerializedObject(_engineConfigAsset), this);
return inspector;
}
}
}

View File

@@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: 6f2d98247b7f40e88946af3956c54a5e
timeCreated: 1741081201

View File

@@ -1,61 +0,0 @@
using RebootKit.Engine.Services.Console;
using SzafaKitEditor.VisualElements;
using UnityEditor;
using UnityEngine;
namespace SzafaKitEditor.PropertyDrawers {
[CustomPropertyDrawer(typeof(CVar))]
public class CVarPropertyDrawer : PropertyDrawer {
private bool _expand;
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) {
SerializedProperty nameProperty = property.FindPropertyRelative("Name");
SerializedProperty descriptionProperty = property.FindPropertyRelative("Description");
SerializedProperty defaultValueProperty = property.FindPropertyRelative("DefaultValue");
SerializedProperty defaultValueKindProperty = defaultValueProperty.FindPropertyRelative("Kind");
SerializedProperty defaultValueNumberProperty = defaultValueProperty.FindPropertyRelative("NumberValue");
SerializedProperty defaultValueStringProperty = defaultValueProperty.FindPropertyRelative("StringValue");
EditorGUILayout.BeginHorizontal();
GUILayout.Label(label, EditorStyles.miniBoldLabel);
nameProperty.stringValue = EditorGUILayout.TextField(nameProperty.stringValue);
bool isNumber = defaultValueKindProperty.enumValueIndex == (int) CVarValueKind.Number;
string kindLabel = isNumber ? "N" : "S";
if (isNumber) {
GUI.color = Color.cyan;
} else {
GUI.color = Color.green;
}
if (GUILayout.Button(kindLabel, GUILayout.Width(32))) {
defaultValueKindProperty.enumValueIndex = isNumber ? (int) CVarValueKind.String : (int) CVarValueKind.Number;
}
GUI.color = Color.white;
if (isNumber) {
defaultValueNumberProperty.doubleValue = EditorGUILayout.DoubleField(defaultValueNumberProperty.doubleValue);
} else {
defaultValueStringProperty.stringValue = EditorGUILayout.TextField(defaultValueStringProperty.stringValue);
}
if (GUILayout.Button(_expand ? "H" : "S", GUILayout.MaxWidth(24))) {
_expand = !_expand;
}
EditorGUILayout.EndHorizontal();
if (_expand) {
EditorGUILayout.PropertyField(nameProperty, new GUIContent("Name"));
EditorGUILayout.PropertyField(descriptionProperty, new GUIContent("Description"));
EditorGUILayout.PropertyField(defaultValueKindProperty, new GUIContent("Value Kind"));
EditorGUILayout.PropertyField(defaultValueNumberProperty, new GUIContent("Number"));
EditorGUILayout.PropertyField(defaultValueStringProperty, new GUIContent("String"));
}
}
}
}

View File

@@ -0,0 +1,50 @@
using RebootKit.Engine.Services.Console;
using RebootKitEditor.Utils;
using UnityEditor;
using UnityEngine;
namespace RebootKitEditor.PropertyDrawers {
[CustomPropertyDrawer(typeof(CVar))]
public class CVarDrawer : PropertyDrawer {
bool m_Expand;
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) {
CVarSerializedProperties properties = CVarSerializedPropertiesFinder.Find(property);
EditorGUILayout.BeginHorizontal();
GUILayout.Label(label, EditorStyles.miniBoldLabel);
properties.name.stringValue = EditorGUILayout.TextField(properties.name.stringValue);
bool isNumber = properties.defaultValueKind.enumValueIndex == (int) CVarValueKind.Number;
string kindLabel = isNumber ? "N" : "S";
if (isNumber)
GUI.color = Color.cyan;
else
GUI.color = Color.green;
if (GUILayout.Button(kindLabel, GUILayout.Width(32))) properties.defaultValueKind.enumValueIndex = isNumber ? (int) CVarValueKind.String : (int) CVarValueKind.Number;
GUI.color = Color.white;
if (isNumber)
properties.defaultValueNumber.doubleValue = EditorGUILayout.DoubleField(properties.defaultValueNumber.doubleValue);
else
properties.defaultValueString.stringValue = EditorGUILayout.TextField(properties.defaultValueString.stringValue);
if (GUILayout.Button(m_Expand ? "H" : "S", GUILayout.MaxWidth(24))) m_Expand = !m_Expand;
EditorGUILayout.EndHorizontal();
if (m_Expand) {
EditorGUILayout.PropertyField(properties.name, new GUIContent("Name"));
EditorGUILayout.PropertyField(properties.description, new GUIContent("Description"));
EditorGUILayout.PropertyField(properties.defaultValueKind, new GUIContent("Value Kind"));
EditorGUILayout.PropertyField(properties.defaultValueNumber, new GUIContent("Number"));
EditorGUILayout.PropertyField(properties.defaultValueString, new GUIContent("String"));
}
}
}
}

View File

@@ -0,0 +1,23 @@
using RebootKit.Engine.Foundation;
using UnityEditor;
using UnityEngine;
namespace RebootKitEditor.PropertyDrawers {
[CustomPropertyDrawer(typeof(FloatRange))]
public class ValueRangeDrawer : PropertyDrawer {
const string k_minPropertyName = "min";
const string k_maxPropertyName = "max";
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) {
SerializedProperty minProperty = property.FindPropertyRelative(k_minPropertyName);
SerializedProperty maxProperty = property.FindPropertyRelative(k_maxPropertyName);
Vector2 minMax = EditorGUILayout.Vector2Field(label, new Vector2(minProperty.floatValue, maxProperty.floatValue));
if (minMax.x > minMax.y) minMax.y = minMax.x;
minProperty.floatValue = minMax.x;
maxProperty.floatValue = minMax.y;
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 0e847dcc2c154c10b7a3d00b9f6f49e5
timeCreated: 1742636936

View File

@@ -1,18 +1,18 @@
{
"name": "SzafaKitEditor",
"rootNamespace": "RebootKitEditor",
"references": [
"GUID:284059c7949783646b281a1b815580e6"
],
"includePlatforms": [
"Editor"
],
"excludePlatforms": [],
"allowUnsafeCode": false,
"overrideReferences": false,
"precompiledReferences": [],
"autoReferenced": true,
"defineConstraints": [],
"versionDefines": [],
"noEngineReferences": false
"name": "SzafaKitEditor",
"rootNamespace": "RebootKitEditor",
"references": [
"GUID:284059c7949783646b281a1b815580e6"
],
"includePlatforms": [
"Editor"
],
"excludePlatforms": [],
"allowUnsafeCode": false,
"overrideReferences": false,
"precompiledReferences": [],
"autoReferenced": true,
"defineConstraints": [],
"versionDefines": [],
"noEngineReferences": false
}

3
Editor/Utils.meta Normal file
View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 1201995b5ab64155bcd531cf153892e5
timeCreated: 1742499685

View File

@@ -0,0 +1,39 @@
using UnityEditor;
namespace RebootKitEditor.Utils {
public struct CVarSerializedProperties {
public SerializedProperty flags;
public SerializedProperty name;
public SerializedProperty description;
public SerializedProperty defaultValueKind;
public SerializedProperty defaultValueNumber;
public SerializedProperty defaultValueString;
}
public static class CVarSerializedPropertiesFinder {
const string k_CVarFlagsProperty = "name";
const string k_CVarNameProperty = "name";
const string k_CVarDescriptionProperty = "description";
const string k_CVarDefaultValueProperty = "defaultValue";
const string k_CVarDefaultValueKindProperty = "kind";
const string k_CVarDefaultValueNumberValueProperty = "numberValue";
const string k_CVarDefaultValueStringValueProperty = "stringValue";
public static CVarSerializedProperties Find(SerializedProperty cvar) {
CVarSerializedProperties properties = new();
properties.flags = cvar.FindPropertyRelative(k_CVarFlagsProperty);
properties.name = cvar.FindPropertyRelative(k_CVarNameProperty);
properties.description = cvar.FindPropertyRelative(k_CVarDescriptionProperty);
SerializedProperty value = cvar.FindPropertyRelative(k_CVarDefaultValueProperty);
if (value != null) {
properties.defaultValueKind = value.FindPropertyRelative(k_CVarDefaultValueKindProperty);
properties.defaultValueNumber = value.FindPropertyRelative(k_CVarDefaultValueNumberValueProperty);
properties.defaultValueString = value.FindPropertyRelative(k_CVarDefaultValueStringValueProperty);
}
return properties;
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: b244cfd75ae64aeebe0299f28ec08267
timeCreated: 1742499696

View File

@@ -5,16 +5,16 @@ using UnityEngine.UIElements;
namespace SzafaKitEditor.VisualElements {
public class CVarPropertyField : VisualElement {
private SerializedProperty _cvarProperty;
private SerializedProperty _nameProperty;
private SerializedProperty _defaultValueProperty;
private SerializedProperty _defaultValueKindProperty;
private SerializedProperty _defaultValueNumberProperty;
private SerializedProperty _defaultValueStringProperty;
readonly SerializedProperty _cvarProperty;
readonly SerializedProperty _defaultValueKindProperty;
readonly SerializedProperty _defaultValueNumberProperty;
readonly SerializedProperty _defaultValueProperty;
readonly SerializedProperty _defaultValueStringProperty;
private VisualElement _details;
VisualElement _details;
private bool _expand;
bool _expand;
readonly SerializedProperty _nameProperty;
public CVarPropertyField(SerializedProperty cvarProperty) {
_cvarProperty = cvarProperty;
@@ -28,14 +28,14 @@ namespace SzafaKitEditor.VisualElements {
CreateDetailsBox();
}
private void CreateInlineField() {
VisualElement box = new VisualElement() {
void CreateInlineField() {
VisualElement box = new() {
style = {
height = 48
}
};
Label nameLabel = new Label("NAME") {
Label nameLabel = new("NAME") {
style = {
unityFontStyleAndWeight = FontStyle.Bold,
backgroundColor = new Color(0.1f, 0.1f, 0.1f, 1.0f)
@@ -47,29 +47,29 @@ namespace SzafaKitEditor.VisualElements {
text = "...",
style = {
width = new StyleLength(new Length(64.0f, LengthUnit.Pixel)),
height = new StyleLength(new Length(64.0f, LengthUnit.Pixel)),
height = new StyleLength(new Length(64.0f, LengthUnit.Pixel))
}
};
box.Add(button);
Add(box);
}
private void ToggleDetails() {
void ToggleDetails() {
_expand = !_expand;
_details.visible = _expand;
_details.style.display = DisplayStyle.None;
}
private void CreateDetailsBox() {
void CreateDetailsBox() {
PropertyField nameField = new(_nameProperty);
PropertyField defaultValueKindField = new(_defaultValueKindProperty);
PropertyField numberField = new(_defaultValueNumberProperty);
PropertyField stringField = new(_defaultValueStringProperty);
_details = new VisualElement() {
_details = new VisualElement {
style = {
backgroundColor = new Color(0.1f, 0.1f, 0.1f, 1.0f),
backgroundColor = new Color(0.1f, 0.1f, 0.1f, 1.0f)
}
};
_details.Add(nameField);

View File

@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: e148f21299f99ad4fa76c50598092230
guid: a9ede814e8e155840988af362db4ecd8
folderAsset: yes
DefaultImporter:
externalObjects: {}

View File

@@ -0,0 +1,47 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &11400000
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 19101, guid: 0000000000000000e000000000000000, type: 0}
m_Name: panel_main_menu
m_EditorClassIdentifier:
themeUss: {fileID: -4733365628477956816, guid: e23ba26e2a2f5a24fbba6ba1d0d59b11,
type: 3}
m_DisableNoThemeWarning: 0
m_TargetTexture: {fileID: 0}
m_RenderMode: 0
m_WorldSpaceLayer: 0
m_ScaleMode: 1
m_ReferenceSpritePixelsPerUnit: 100
m_PixelsPerUnit: 100
m_Scale: 1
m_ReferenceDpi: 96
m_FallbackDpi: 96
m_ReferenceResolution: {x: 1200, y: 800}
m_ScreenMatchMode: 0
m_Match: 0
m_SortingOrder: 0
m_TargetDisplay: 0
m_BindingLogLevel: 0
m_ClearDepthStencil: 1
m_ClearColor: 0
m_ColorClearValue: {r: 0, g: 0, b: 0, a: 0}
m_VertexBudget: 0
m_DynamicAtlasSettings:
m_MinAtlasSize: 64
m_MaxAtlasSize: 4096
m_MaxSubTextureSize: 64
m_ActiveFilters: -1
m_AtlasBlitShader: {fileID: 9101, guid: 0000000000000000f000000000000000, type: 0}
m_RuntimeShader: {fileID: 9100, guid: 0000000000000000f000000000000000, type: 0}
m_RuntimeWorldShader: {fileID: 9102, guid: 0000000000000000f000000000000000, type: 0}
m_ICUDataAsset: {fileID: 0}
forceGammaRendering: 0
textSettings: {fileID: 0}

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 358c21fd21b91a9468509e0dd81a2f08
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 11400000
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,125 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!29 &1
OcclusionCullingSettings:
m_ObjectHideFlags: 0
serializedVersion: 2
m_OcclusionBakeSettings:
smallestOccluder: 5
smallestHole: 0.25
backfaceThreshold: 100
m_SceneGUID: 00000000000000000000000000000000
m_OcclusionCullingData: {fileID: 0}
--- !u!104 &2
RenderSettings:
m_ObjectHideFlags: 0
serializedVersion: 10
m_Fog: 0
m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1}
m_FogMode: 3
m_FogDensity: 0.01
m_LinearFogStart: 0
m_LinearFogEnd: 300
m_AmbientSkyColor: {r: 0.212, g: 0.227, b: 0.259, a: 1}
m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1}
m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1}
m_AmbientIntensity: 1
m_AmbientMode: 0
m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1}
m_SkyboxMaterial: {fileID: 10304, guid: 0000000000000000f000000000000000, type: 0}
m_HaloStrength: 0.5
m_FlareStrength: 1
m_FlareFadeSpeed: 3
m_HaloTexture: {fileID: 0}
m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0}
m_DefaultReflectionMode: 0
m_DefaultReflectionResolution: 128
m_ReflectionBounces: 1
m_ReflectionIntensity: 1
m_CustomReflection: {fileID: 0}
m_Sun: {fileID: 0}
m_UseRadianceAmbientProbe: 0
--- !u!157 &3
LightmapSettings:
m_ObjectHideFlags: 0
serializedVersion: 13
m_BakeOnSceneLoad: 0
m_GISettings:
serializedVersion: 2
m_BounceScale: 1
m_IndirectOutputScale: 1
m_AlbedoBoost: 1
m_EnvironmentLightingMode: 0
m_EnableBakedLightmaps: 1
m_EnableRealtimeLightmaps: 0
m_LightmapEditorSettings:
serializedVersion: 12
m_Resolution: 2
m_BakeResolution: 40
m_AtlasSize: 1024
m_AO: 0
m_AOMaxDistance: 1
m_CompAOExponent: 1
m_CompAOExponentDirect: 0
m_ExtractAmbientOcclusion: 0
m_Padding: 2
m_LightmapParameters: {fileID: 0}
m_LightmapsBakeMode: 1
m_TextureCompression: 1
m_ReflectionCompression: 2
m_MixedBakeMode: 2
m_BakeBackend: 1
m_PVRSampling: 1
m_PVRDirectSampleCount: 32
m_PVRSampleCount: 512
m_PVRBounces: 2
m_PVREnvironmentSampleCount: 256
m_PVREnvironmentReferencePointCount: 2048
m_PVRFilteringMode: 1
m_PVRDenoiserTypeDirect: 1
m_PVRDenoiserTypeIndirect: 1
m_PVRDenoiserTypeAO: 1
m_PVRFilterTypeDirect: 0
m_PVRFilterTypeIndirect: 0
m_PVRFilterTypeAO: 0
m_PVREnvironmentMIS: 1
m_PVRCulling: 1
m_PVRFilteringGaussRadiusDirect: 1
m_PVRFilteringGaussRadiusIndirect: 1
m_PVRFilteringGaussRadiusAO: 1
m_PVRFilteringAtrousPositionSigmaDirect: 0.5
m_PVRFilteringAtrousPositionSigmaIndirect: 2
m_PVRFilteringAtrousPositionSigmaAO: 1
m_ExportTrainingData: 0
m_TrainingDataDestination: TrainingData
m_LightProbeSampleCountMultiplier: 4
m_LightingDataAsset: {fileID: 20201, guid: 0000000000000000f000000000000000, type: 0}
m_LightingSettings: {fileID: 0}
--- !u!196 &4
NavMeshSettings:
serializedVersion: 2
m_ObjectHideFlags: 0
m_BuildSettings:
serializedVersion: 3
agentTypeID: 0
agentRadius: 0.5
agentHeight: 2
agentSlope: 45
agentClimb: 0.4
ledgeDropHeight: 0
maxJumpAcrossDistance: 0
minRegionArea: 2
manualCellSize: 0
cellSize: 0.16666667
manualTileSize: 0
tileSize: 256
buildHeightMesh: 0
maxJobWorkers: 0
preserveTilesOutsideBounds: 0
debug:
m_Flags: 0
m_NavMeshData: {fileID: 0}
--- !u!1660057539 &9223372036854775807
SceneRoots:
m_ObjectHideFlags: 0
m_Roots: []

View File

@@ -1,6 +1,6 @@
fileFormatVersion: 2
guid: f83916a033d3c4b45b40ee51f7f62a5c
PrefabImporter:
guid: 9442a2e8baed7af4c92460a3803eefbc
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:

View File

@@ -0,0 +1,11 @@
<engine:UXML xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:engine="UnityEngine.UIElements" xmlns:editor="UnityEditor.UIElements" noNamespaceSchemaLocation="../../../../../../UIElementsSchema/UIElements.xsd" editor-extension-mode="False">
<engine:VisualElement style="flex-grow: 1; background-color: rgb(0, 0, 0);">
<engine:VisualElement style="flex-grow: 1; background-image: url(&quot;project://database/Packages/com.rebootreality.rebootkit/Runtime/Engine/Assets/Sprites/logo_rr.png?fileID=2800000&amp;guid=b1c861e6353e19f48a56fff1559c1a76&amp;type=3#logo_rr&quot;); max-width: 500px; max-height: 500px; width: 500px; height: 500px; position: absolute; top: 0; left: 0;" />
<engine:VisualElement style="flex-grow: 1; position: absolute; top: 0; left: auto; right: 0; bottom: 0; justify-content: center;">
<engine:Label text="RebootKit - test menu" style="color: rgb(255, 255, 255); font-size: 72px;" />
<engine:Button text="Start" enable-rich-text="true" name="btn_start" />
<engine:Button text="Options" name="btn_options" />
<engine:Button text="Exit" name="btn_exit" />
</engine:VisualElement>
</engine:VisualElement>
</engine:UXML>

View File

@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: 852055ed179f6f546b9f0ff34d97f4fb
guid: 82e9402c7fb775a45819bd34a69e2c5f
ScriptedImporter:
internalIDToNameTable: []
externalObjects: {}

View File

@@ -33,7 +33,7 @@
"initialStateCheck": false
},
{
"name": "PhysicsDrag",
"name": "Drag",
"type": "Button",
"id": "bf3d1155-8050-482a-ae55-fa8d47c95e94",
"expectedControlType": "",
@@ -126,7 +126,7 @@
"interactions": "",
"processors": "",
"groups": "",
"action": "PhysicsDrag",
"action": "Drag",
"isComposite": false,
"isPartOfComposite": false
},

View File

@@ -1,68 +0,0 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!1 &3601716648929981382
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 1331948412974115855}
- component: {fileID: 1375678557884231458}
- component: {fileID: 8622248495270372400}
m_Layer: 5
m_Name: ConsoleUI
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!4 &1331948412974115855
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 3601716648929981382}
serializedVersion: 2
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 9, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!114 &1375678557884231458
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 3601716648929981382}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: ca844a0157054677b2f129fdbf6ddc45, type: 3}
m_Name:
m_EditorClassIdentifier:
_document: {fileID: 8622248495270372400}
--- !u!114 &8622248495270372400
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 3601716648929981382}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 19102, guid: 0000000000000000e000000000000000, type: 0}
m_Name:
m_EditorClassIdentifier:
m_PanelSettings: {fileID: 11400000, guid: c4c93f1ef3cc3324696c439305139cbb, type: 2}
m_ParentUI: {fileID: 0}
sourceAsset: {fileID: 9197481963319205126, guid: 15eee085e73feee4eba58c073b1455c5,
type: 3}
m_SortingOrder: 0
m_WorldSpaceSizeMode: 1
m_WorldSpaceWidth: 1920
m_WorldSpaceHeight: 1080

View File

@@ -12,6 +12,6 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: 8fcf71fe79ef1ed4cbfdefde09e708d9, type: 3}
m_Name: Input
m_EditorClassIdentifier:
_config:
InputAsset: {fileID: -944628639613478452, guid: f991e9abd9a53ee4b94b329a5ce96cb2,
m_Config:
inputAsset: {fileID: -944628639613478452, guid: f991e9abd9a53ee4b94b329a5ce96cb2,
type: 3}

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 1400c4f93b62de546a78716fe0ffe0bf
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

View File

@@ -0,0 +1,117 @@
fileFormatVersion: 2
guid: b1c861e6353e19f48a56fff1559c1a76
TextureImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 13
mipmaps:
mipMapMode: 0
enableMipMap: 0
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
flipGreenChannel: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
vTOnly: 0
ignoreMipmapLimit: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: 1
aniso: 1
mipBias: 0
wrapU: 1
wrapV: 1
wrapW: 0
nPOTScale: 0
lightmap: 0
compressionQuality: 50
spriteMode: 2
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 1
spriteTessellationDetail: -1
textureType: 8
textureShape: 1
singleChannelComponent: 0
flipbookRows: 1
flipbookColumns: 1
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
ignorePngGamma: 0
applyGammaDecoding: 0
swizzle: 50462976
cookieLightType: 0
platformSettings:
- serializedVersion: 4
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 4
buildTarget: Standalone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
customData:
physicsShape: []
bones: []
spriteID:
internalID: 0
vertices: []
indices:
edges: []
weights: []
secondaryTextures: []
spriteCustomMetadata:
entries: []
nameFileIdTable: {}
mipmapLimitGroupName:
pSDRemoveMatte: 0
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -12,7 +12,8 @@ MonoBehaviour:
m_Script: {fileID: 19101, guid: 0000000000000000e000000000000000, type: 0}
m_Name: Panel Settings
m_EditorClassIdentifier:
themeUss: {fileID: -4733365628477956816, guid: 5dd55e8f9f3419144b6d6fc3fcc478d0, type: 3}
themeUss: {fileID: -4733365628477956816, guid: 5dd55e8f9f3419144b6d6fc3fcc478d0,
type: 3}
m_DisableNoThemeWarning: 0
m_TargetTexture: {fileID: 0}
m_RenderMode: 0

View File

@@ -1,7 +1,5 @@
@import url("/Assets/UI Toolkit/UnityThemes/UnityDefaultRuntimeTheme.tss");
.rr-base {
color: #dedede;
}
@@ -9,8 +7,9 @@
.rr-label {
}
/* Buttons */
.rr-button {
background-color: #191919;
background-color: #1a6284;
border-color: #373737;
border-radius: 3px;
border-width: 1px;
@@ -26,31 +25,69 @@
margin: 4px;
}
.rr-button:hover {
background-color: #202020;
.rr-button:hover:enabled {
background-color: #297ba5;
border-color: #3d4545;
}
.rr-button:focus {
background-color: #333333;
.rr-button:focus:enabled {
background-color: #297ba5;
border-color: #3d4545;
}
.rr-text-field {
background-color: #191919;
.rr-button-destructive {
background-color: #e13232;
border-color: #373737;
border-radius: 3px;
border-width: 1px;
-unity-font-style: bold;
-unity-text-align: middle-center;
font-size: 13px;
-unity-text-align: middle-left;
width: 100%;
height: 32px;
padding: 4px;
margin: 4px;
}
.rr-button-destructive:hover:enabled {
background-color: #f83838;
border-color: #453d3d;
}
.rr-button-destructive:focus:enabled {
background-color: #f83838;
border-color: #453d3d;
}
/* Text Field */
.rr-text-field {
min-height: 32px;
padding: 0;
margin: 4px;
--unity-cursor-color: #dedede;
}
.rr-text-field > #unity-text-input {
background-color: #191919;
border-color: #373737;
border-radius: 3px;
border-width: 1px;
padding: 4px;
}
.rr-text-field > #unity-text-input > TextElement {
font-size: 13px;
color: #dedede;
-unity-text-align: middle-left;
}
.rr-scroll-view {
background-color: #232323;
border-color: #373737;

View File

@@ -0,0 +1,111 @@
@import url("/Assets/UI Toolkit/UnityThemes/UnityDefaultRuntimeTheme.tss");
VisualElement {
color: #dedede;
}
/* Buttons */
Button {
background-color: #1a6284;
border-color: #373737;
border-radius: 3px;
border-width: 1px;
-unity-font-style: bold;
-unity-text-align: middle-center;
font-size: 13px;
height: 32px;
padding: 4px;
margin: 4px;
}
Button:hover:enabled {
background-color: #297ba5;
border-color: #3d4545;
}
Button:focus:enabled {
background-color: #297ba5;
border-color: #3d4545;
}
.rr-button-destructive {
background-color: #e13232;
border-color: #373737;
border-radius: 3px;
border-width: 1px;
-unity-font-style: bold;
-unity-text-align: middle-center;
font-size: 13px;
height: 32px;
padding: 4px;
margin: 4px;
}
.rr-button-destructive:hover:enabled {
background-color: #f83838;
border-color: #453d3d;
}
.rr-button-destructive:focus:enabled {
background-color: #f83838;
border-color: #453d3d;
}
/* Text Field */
TextField {
min-height: 32px;
padding: 0;
margin: 4px;
--unity-cursor-color: #dedede;
}
TextField > #unity-text-input {
background-color: #191919;
border-color: #373737;
border-radius: 3px;
border-width: 1px;
padding: 4px;
}
TextField > #unity-text-input > TextElement {
font-size: 13px;
color: #dedede;
-unity-text-align: middle-left;
}
ScrollView {
background-color: #232323;
border-color: #373737;
border-radius: 3px;
border-width: 1px;
padding: 4px;
margin: 4px;
}
/* Window */
.window-bg {
border-width: 2px;
border-color: #373737;
background-color: #212121;
}
.window-content {
border-color: #373737;
border-width: 1px;
background-color: #272727;
margin: 12px;
padding: 8px;
}

View File

@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: 56459608f8e71f140b0933d6689a0846
guid: e23ba26e2a2f5a24fbba6ba1d0d59b11
ScriptedImporter:
internalIDToNameTable: []
externalObjects: {}
@@ -7,5 +7,5 @@ ScriptedImporter:
userData:
assetBundleName:
assetBundleVariant:
script: {fileID: 12385, guid: 0000000000000000e000000000000000, type: 0}
script: {fileID: 12388, guid: 0000000000000000e000000000000000, type: 0}
disableValidation: 0

View File

@@ -1,13 +1,23 @@
<engine:UXML xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:engine="UnityEngine.UIElements" xmlns:editor="UnityEditor.UIElements" noNamespaceSchemaLocation="../../../../UIElementsSchema/UIElements.xsd" editor-extension-mode="False">
<engine:VisualElement style="flex-grow: 1; background-color: rgba(176, 137, 137, 0.69); max-height: 100%; max-width: none; height: 100%;">
<engine:VisualElement name="console-window" enabled="true" class="window-bg" style="flex-grow: 1; text-shadow: 0 0 0 rgba(255, 255, 255, 0); position: relative; width: 100%; height: 50%; max-height: 50%;">
<engine:VisualElement name="VisualElement" enabled="true" class="window-content rr-base" style="flex-grow: 1; align-content: stretch; align-self: auto; justify-content: flex-start; align-items: stretch;">
<engine:ScrollView name="console-scrollview" class="rr-scroll-view" style="max-height: none; height: 100%;">
<engine:Label text="Label" name="console-window-message" />
<engine:UXML xmlns:engine="UnityEngine.UIElements"
noNamespaceSchemaLocation="../../../../UIElementsSchema/UIElements.xsd" editor-extension-mode="False">
<engine:VisualElement
style="flex-grow: 1; background-color: rgba(176, 137, 137, 0); max-height: 100%; max-width: none; height: 100%;">
<engine:VisualElement name="console-window" enabled="true" class="window-bg"
style="flex-grow: 1; text-shadow: 0 0 0 rgba(255, 255, 255, 0); position: relative; width: 100%; height: 50%; max-height: 50%; -unity-background-image-tint-color: rgb(255, 255, 255); background-color: rgb(33, 33, 33);">
<engine:VisualElement name="VisualElement" enabled="true" class="window-content rr-base"
style="flex-grow: 1; align-content: stretch; align-self: auto; justify-content: flex-start; align-items: stretch;">
<engine:ScrollView name="console-scrollview" class="rr-scroll-view"
style="max-height: none; height: 100%;">
<engine:Label
text="Label&#10;&#10;&#10;&#10;&#10;&#10;asd&#10;&#10;&#10;as&#10;asf&#10;asfasf&#10;asf&#10;asf&#10;asf&#10;afs&#10;asf&#10;asf&#10;asf&#10;"
name="console-window-message"/>
</engine:ScrollView>
<engine:VisualElement name="console-bottomrow" style="flex-grow: 1; flex-basis: auto; flex-direction: row; align-items: center; justify-content: flex-end; align-self: stretch; align-content: stretch; flex-wrap: nowrap;">
<engine:TextField name="console-text-field" class="rr-text-field" style="width: 92%;" />
<engine:Button text="Submit" name="console-btn-submit" class="rr-button" />
<engine:VisualElement name="console-bottomrow"
style="flex-grow: 1; flex-basis: auto; flex-direction: row; align-items: center; justify-content: flex-end; align-self: stretch; align-content: stretch; flex-wrap: nowrap; padding-top: 0; padding-right: 0; padding-bottom: 0; padding-left: 0; margin-top: 4px;">
<engine:TextField name="console-text-field" value="awsdsad" class="rr-text-field rr-base"
style="width: auto; flex-basis: auto; flex-grow: 1;"/>
<engine:Button text="Submit" name="console-btn-submit" class="rr-button"/>
<engine:Button text="Clear" name="console-btn-clear" class="rr-button-destructive"/>
</engine:VisualElement>
</engine:VisualElement>
</engine:VisualElement>

View File

@@ -0,0 +1,21 @@
using System;
using RebootKit.Engine.Services.Game;
using UnityEngine.AddressableAssets;
namespace RebootKit.Engine {
[Serializable]
public class AppConfig {
public MainMenuConfig mainMenuConfig;
public GameConfig gameConfig;
}
[Serializable]
public class MainMenuConfig {
public AssetReference scene;
}
[Serializable]
public class GameConfig {
public GameModeAsset defaultGameMode;
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 75a5232723f54287b48c0294a0009869
timeCreated: 1743174115

View File

@@ -1,20 +1,11 @@
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;
namespace RebootKit.Engine {
[CreateAssetMenu(menuName = RConsts.AssetMenu + RConsts.EngineConfigAssetName, fileName = RConsts.EngineConfigAssetName)]
[CreateAssetMenu(menuName = RConsts.k_AddComponentMenu + RConsts.k_EngineConfigAssetName, fileName = RConsts.k_EngineConfigAssetName)]
public class EngineConfigAsset : ScriptableObject {
[Header("<color=#ff0000>REQUIRED</color>: core assets")]
public ServiceAsset<ConsoleService> ConsoleService;
public ServiceAsset<InputService> InputService;
public ServiceAsset<WorldService> WorldService;
public ServiceAsset<GameService> GameService;
[Space]
public GameModeAsset StartingGameMode;
public bool initializeOnLoad = true;
public EngineCoreServicesAsset coreServices;
public AppConfig appConfig;
}
}
}

View File

@@ -0,0 +1,16 @@
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;
namespace RebootKit.Engine {
[CreateAssetMenu(menuName = RConsts.k_AddComponentMenu + "Engine Core Services", fileName = "Engine Core Services")]
public class EngineCoreServicesAsset : ScriptableObject {
public ServiceAsset<ConsoleService> consoleService;
public ServiceAsset<InputService> inputService;
public ServiceAsset<WorldService> worldService;
public ServiceAsset<GameService> gameService;
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 2762a1b645374b79a34aad7b8066bb9b
timeCreated: 1743173984

View File

@@ -8,10 +8,15 @@ namespace RebootKit.Engine.Extensions {
blue ?? color.b,
alpha ?? color.a);
}
public static string ToHexRGBA(this Color color) => $"#{ColorUtility.ToHtmlStringRGBA(color)}";
public static string ToHexRGB(this Color color) => $"#{ColorUtility.ToHtmlStringRGB(color)}";
public static string ToHexRGBA(this Color color) {
return $"#{ColorUtility.ToHtmlStringRGBA(color)}";
}
public static string ToHexRGB(this Color color) {
return $"#{ColorUtility.ToHtmlStringRGB(color)}";
}
public static Color Clamp01(this Color color) {
return new Color {
r = Mathf.Clamp01(color.r),

View File

@@ -1,10 +1,11 @@
using UnityEngine;
using System;
using UnityEngine;
using Object = UnityEngine.Object;
namespace RebootKit.Engine.Extensions {
public static class GameObjectEx {
public static T GetOrAdd<T>(this GameObject gameObject) where T : Component {
T component = gameObject.GetComponent<T>();
if (component == null) {
component = gameObject.AddComponent<T>();
}
@@ -12,6 +13,10 @@ namespace RebootKit.Engine.Extensions {
return component;
}
public static void ForEachChild(this GameObject gameObject, Action<GameObject> action) {
gameObject.transform.ForEachChild(transform => action(transform.gameObject));
}
public static void DestroyChildren(this GameObject gameObject) {
gameObject.transform.DestroyChildren();
}
@@ -22,9 +27,7 @@ namespace RebootKit.Engine.Extensions {
public static void SetLayersRecursively(this GameObject gameObject, int layer) {
gameObject.layer = layer;
gameObject.transform.ForEachChild(child => {
child.gameObject.SetLayersRecursively(layer);
});
gameObject.transform.ForEachChild(child => { child.gameObject.SetLayersRecursively(layer); });
}
}
}

View File

@@ -5,15 +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) Object.Destroy(child);
}
public static void ForEachChild(this Transform transform, Action<Transform> action) {
foreach (Transform child in transform) {
action(child);
}
foreach (Transform child in transform) action(child);
}
}
}

View File

@@ -1,11 +1,36 @@
using UnityEngine;
using System.Runtime.CompilerServices;
using Unity.Mathematics;
using UnityEngine;
namespace RebootKit.Engine.Extensions {
public static class Vector3Ex {
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector3 With(this Vector3 vec, float? x = null, float? y = null, float? z = null) {
return new Vector3(x ?? vec.x,
y ?? vec.y,
z ?? vec.z);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool IsZero(this Vector3 vec, float epsilon = float.Epsilon) {
return math.abs(vec.x) < epsilon && math.abs(vec.y) < epsilon && math.abs(vec.z) < epsilon;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool IsNonZero(this Vector3 vec, float epsilon = float.Epsilon) {
return !vec.IsZero(epsilon);
}
}
public static class float3Ex {
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool IsZero(this float3 vec, float epsilon = float.Epsilon) {
return math.abs(vec.x) < epsilon && math.abs(vec.y) < epsilon && math.abs(vec.z) < epsilon;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool IsNonZero(this float3 vec, float epsilon = float.Epsilon) {
return !vec.IsZero(epsilon);
}
}
}

View File

@@ -1,10 +1,7 @@
namespace RebootKit.Engine.Foundation
{
public abstract class ControllerAsset<TController> : FactoryAsset<TController> where TController : class, IController
{
namespace RebootKit.Engine.Foundation {
public abstract class ControllerAsset<TController> : FactoryAsset<TController> where TController : class, IController {
}
public abstract class ControllerAsset : ControllerAsset<IController>
{
public abstract class ControllerAsset : ControllerAsset<IController> {
}
}

View File

@@ -9,17 +9,13 @@ namespace RebootKit.Engine.Foundation {
}
public class DIContext {
private const BindingFlags k_fieldsBindingFlags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance;
private const BindingFlags k_methodsBindingFlags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance;
const BindingFlags k_fieldsBindingFlags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance;
const BindingFlags k_methodsBindingFlags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance;
public interface IFieldInjector {
bool Inject(FieldInfo field, object target, DIContext context);
}
static readonly Logger s_logger = new(nameof(DIContext));
private static readonly Logger Logger = new(nameof(DIContext));
private readonly Dictionary<Type, object> _bindingsMaps = new();
private readonly List<IFieldInjector> _fieldInjectors = new();
readonly Dictionary<Type, object> m_BindingsMaps = new();
readonly List<IFieldInjector> m_FieldInjectors = new();
public DIContext() {
Bind(this);
@@ -28,13 +24,11 @@ namespace RebootKit.Engine.Foundation {
}
public void AddInjector(IFieldInjector injector) {
_fieldInjectors.Add(injector);
m_FieldInjectors.Add(injector);
}
public void Bind(Type type, object obj) {
if (!_bindingsMaps.TryAdd(type, obj)) {
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) {
@@ -42,11 +36,9 @@ namespace RebootKit.Engine.Foundation {
}
public object Resolve(Type type) {
if (_bindingsMaps.TryGetValue(type, out object obj)) {
return obj;
}
if (m_BindingsMaps.TryGetValue(type, out object obj)) return obj;
Logger.Error($"Couldn't resolve `{type}`");
s_logger.Error($"Couldn't resolve `{type}`");
return null;
}
@@ -61,18 +53,20 @@ 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);
}
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()
.Select(t => t.ParameterType)
@@ -83,35 +77,33 @@ namespace RebootKit.Engine.Foundation {
for (int i = 0; i < paramsTypes.Length; ++i) {
instances[i] = Resolve(paramsTypes[i]);
if (instances[i] == null) {
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);
}
}
private bool InjectField(FieldInfo field, object target) {
for (int i = _fieldInjectors.Count - 1; i >= 0; i--) {
if (_fieldInjectors[i].Inject(field, target, this)) {
bool InjectField(FieldInfo field, object target) {
for (int i = m_FieldInjectors.Count - 1; i >= 0; i--)
if (m_FieldInjectors[i].Inject(field, target, this))
return true;
}
}
return false;
}
private class InjectAttributeFieldInjector : IFieldInjector {
public interface IFieldInjector {
bool Inject(FieldInfo field, object target, DIContext context);
}
class InjectAttributeFieldInjector : IFieldInjector {
public bool Inject(FieldInfo field, object target, DIContext context) {
if (!Attribute.IsDefined(field, typeof(InjectAttribute))) {
return false;
}
if (!Attribute.IsDefined(field, typeof(InjectAttribute))) return false;
object instance = context.Resolve(field.FieldType);
if (instance == null) {
Logger.Error($"Cannot resolve `{field.FieldType}`");
s_logger.Error($"Cannot resolve `{field.FieldType}`");
return false;
}

View File

@@ -0,0 +1,249 @@
using System;
using UnityEngine.Assertions;
using UnityEngine.Events;
namespace RebootKit.Engine.Foundation {
public static class DisposableListenerEx {
/// Action
public static IDisposable Listen(this Action action, Action listener) {
Assert.IsNotNull(action);
Assert.IsNotNull(listener);
return new DisposableActionListener(action, listener);
}
public static IDisposable Listen<T>(this Action<T> action, Action<T> listener) {
Assert.IsNotNull(action);
Assert.IsNotNull(listener);
return new DisposableActionListener<T>(action, listener);
}
public static IDisposable Listen<T1, T2>(this Action<T1, T2> action, Action<T1, T2> listener) {
Assert.IsNotNull(action);
Assert.IsNotNull(listener);
return new DisposableActionListener<T1, T2>(action, listener);
}
public static IDisposable Listen<T1, T2, T3>(this Action<T1, T2, T3> action, Action<T1, T2, T3> listener) {
Assert.IsNotNull(action);
Assert.IsNotNull(listener);
return new DisposableActionListener<T1, T2, T3>(action, listener);
}
public static IDisposable Listen<T1, T2, T3, T4>(this Action<T1, T2, T3, T4> action, Action<T1, T2, T3, T4> listener) {
Assert.IsNotNull(action);
Assert.IsNotNull(listener);
return new DisposableActionListener<T1, T2, T3, T4>(action, listener);
}
/// UnityEvent
public static IDisposable Listen(this UnityEvent unityEvent, UnityAction listener) {
Assert.IsNotNull(unityEvent);
Assert.IsNotNull(listener);
return new DisposableUnityEventListener(unityEvent, listener);
}
public static IDisposable Listen<T>(this UnityEvent<T> unityEvent, UnityAction<T> listener) {
Assert.IsNotNull(unityEvent);
Assert.IsNotNull(listener);
return new DisposableUnityEventListener<T>(unityEvent, listener);
}
public static IDisposable Listen<T1, T2>(this UnityEvent<T1, T2> unityEvent, UnityAction<T1, T2> listener) {
Assert.IsNotNull(unityEvent);
Assert.IsNotNull(listener);
return new DisposableUnityEventListener<T1, T2>(unityEvent, listener);
}
public static IDisposable Listen<T1, T2, T3>(this UnityEvent<T1, T2, T3> unityEvent, UnityAction<T1, T2, T3> listener) {
Assert.IsNotNull(unityEvent);
Assert.IsNotNull(listener);
return new DisposableUnityEventListener<T1, T2, T3>(unityEvent, listener);
}
public static IDisposable Listen<T1, T2, T3, T4>(this UnityEvent<T1, T2, T3, T4> unityEvent, UnityAction<T1, T2, T3, T4> listener) {
Assert.IsNotNull(unityEvent);
Assert.IsNotNull(listener);
return new DisposableUnityEventListener<T1, T2, T3, T4>(unityEvent, listener);
}
}
struct DisposableActionListener : IDisposable {
Action m_Action;
readonly Action m_Listener;
internal DisposableActionListener(Action action, Action listener) {
m_Action = action;
m_Listener = listener;
m_Action += m_Listener;
}
public void Dispose() {
if (m_Action != null) {
m_Action -= m_Listener;
m_Action = null;
}
}
}
struct DisposableActionListener<T> : IDisposable {
Action<T> m_Action;
readonly Action<T> m_Listener;
internal DisposableActionListener(Action<T> action, Action<T> listener) {
m_Action = action;
m_Listener = listener;
m_Action += m_Listener;
}
public void Dispose() {
if (m_Action != null) {
m_Action -= m_Listener;
m_Action = null;
}
}
}
struct DisposableActionListener<T1, T2> : IDisposable {
Action<T1, T2> m_Action;
readonly Action<T1, T2> m_Listener;
internal DisposableActionListener(Action<T1, T2> action, Action<T1, T2> listener) {
m_Action = action;
m_Listener = listener;
m_Action += m_Listener;
}
public void Dispose() {
if (m_Action != null) {
m_Action -= m_Listener;
m_Action = null;
}
}
}
struct DisposableActionListener<T1, T2, T3> : IDisposable {
Action<T1, T2, T3> m_Action;
readonly Action<T1, T2, T3> m_Listener;
internal DisposableActionListener(Action<T1, T2, T3> action, Action<T1, T2, T3> listener) {
m_Action = action;
m_Listener = listener;
m_Action += m_Listener;
}
public void Dispose() {
if (m_Action != null) {
m_Action -= m_Listener;
m_Action = null;
}
}
}
struct DisposableActionListener<T1, T2, T3, T4> : IDisposable {
Action<T1, T2, T3, T4> m_Action;
readonly Action<T1, T2, T3, T4> m_Listener;
internal DisposableActionListener(Action<T1, T2, T3, T4> action, Action<T1, T2, T3, T4> listener) {
m_Action = action;
m_Listener = listener;
m_Action += m_Listener;
}
public void Dispose() {
if (m_Action != null) {
m_Action -= m_Listener;
m_Action = null;
}
}
}
struct DisposableUnityEventListener : IDisposable {
UnityEvent m_Event;
readonly UnityAction m_Listener;
internal DisposableUnityEventListener(UnityEvent unityEvent, UnityAction listener) {
m_Event = unityEvent;
m_Listener = listener;
m_Event.AddListener(m_Listener);
}
public void Dispose() {
if (m_Event != null) {
m_Event.RemoveListener(m_Listener);
m_Event = null;
}
}
}
struct DisposableUnityEventListener<T> : IDisposable {
UnityEvent<T> m_Event;
readonly UnityAction<T> m_Listener;
internal DisposableUnityEventListener(UnityEvent<T> unityEvent, UnityAction<T> listener) {
m_Event = unityEvent;
m_Listener = listener;
m_Event.AddListener(m_Listener);
}
public void Dispose() {
if (m_Event != null) {
m_Event.RemoveListener(m_Listener);
m_Event = null;
}
}
}
struct DisposableUnityEventListener<T1, T2> : IDisposable {
UnityEvent<T1, T2> m_Event;
readonly UnityAction<T1, T2> m_Listener;
internal DisposableUnityEventListener(UnityEvent<T1, T2> unityEvent, UnityAction<T1, T2> listener) {
m_Event = unityEvent;
m_Listener = listener;
m_Event.AddListener(m_Listener);
}
public void Dispose() {
if (m_Event != null) {
m_Event.RemoveListener(m_Listener);
m_Event = null;
}
}
}
struct DisposableUnityEventListener<T1, T2, T3> : IDisposable {
UnityEvent<T1, T2, T3> m_Event;
readonly UnityAction<T1, T2, T3> m_Listener;
internal DisposableUnityEventListener(UnityEvent<T1, T2, T3> unityEvent, UnityAction<T1, T2, T3> listener) {
m_Event = unityEvent;
m_Listener = listener;
m_Event.AddListener(m_Listener);
}
public void Dispose() {
if (m_Event != null) {
m_Event.RemoveListener(m_Listener);
m_Event = null;
}
}
}
struct DisposableUnityEventListener<T1, T2, T3, T4> : IDisposable {
UnityEvent<T1, T2, T3, T4> m_Event;
readonly UnityAction<T1, T2, T3, T4> m_Listener;
internal DisposableUnityEventListener(UnityEvent<T1, T2, T3, T4> unityEvent, UnityAction<T1, T2, T3, T4> listener) {
m_Event = unityEvent;
m_Listener = listener;
m_Event.AddListener(m_Listener);
}
public void Dispose() {
if (m_Event != null) {
m_Event.RemoveListener(m_Listener);
m_Event = null;
}
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 60723820074047008649a9c5c1caa1eb
timeCreated: 1743248914

View File

@@ -0,0 +1,37 @@
using System;
namespace RebootKit.Engine.Foundation {
public readonly struct Either<TLeft, TRight> {
public TLeft Left { get; }
public TRight Right { get; }
public bool IsRight { get; }
public bool IsLeft => !IsRight;
Either(TLeft left, TRight right, bool isRight) {
Left = left;
Right = right;
IsRight = isRight;
}
public void Match(Action<TLeft> leftAction, Action<TRight> rightAction) {
if (IsRight) {
rightAction(Right);
} else {
leftAction(Left);
}
}
public static Either<TLeft, TRight> FromLeft(TLeft value) {
return new Either<TLeft, TRight>(value, default, false);
}
public static Either<TLeft, TRight> FromRight(TRight value) {
return new Either<TLeft, TRight>(default, value, true);
}
public override string ToString() {
return IsRight ? $"Right({Right})" : $"Left({Left})";
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: f094644b7b6a45e89f281ba5db991288
timeCreated: 1742635059

View File

@@ -1,50 +1,59 @@
using System.Threading;
using Cysharp.Threading.Tasks;
using UnityEditor;
using UnityEngine;
using UnityEngine.SceneManagement;
namespace RebootKit.Engine.Foundation {
public static class EntryPoint {
private static readonly Logger _logger = new(nameof(EntryPoint));
static readonly Logger s_logger = new(nameof(EntryPoint));
private static CancellationTokenSource _cancellationTokenSource;
static CancellationTokenSource s_cancellationTokenSource;
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.AfterSceneLoad)]
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSplashScreen)]
public static void Start() {
if (_cancellationTokenSource != null) {
_cancellationTokenSource.Cancel();
if (s_cancellationTokenSource != null) {
s_cancellationTokenSource.Cancel();
}
RR.Shared = null;
RR.s_Shared = null;
_cancellationTokenSource = new CancellationTokenSource();
SceneManager.LoadScene(0, LoadSceneMode.Single);
RunAsync(_cancellationTokenSource.Token).Forget();
s_cancellationTokenSource = new CancellationTokenSource();
RunAsync(s_cancellationTokenSource.Token).Forget();
#if UNITY_EDITOR
static void OnPlayerModeState(UnityEditor.PlayModeStateChange state) {
if (state == UnityEditor.PlayModeStateChange.ExitingPlayMode) {
_cancellationTokenSource.Cancel();
}
static void OnPlayerModeState(PlayModeStateChange state) {
if (state == PlayModeStateChange.ExitingPlayMode) s_cancellationTokenSource.Cancel();
}
UnityEditor.EditorApplication.playModeStateChanged -= OnPlayerModeState;
UnityEditor.EditorApplication.playModeStateChanged += OnPlayerModeState;
EditorApplication.playModeStateChanged -= OnPlayerModeState;
EditorApplication.playModeStateChanged += OnPlayerModeState;
#endif
}
public static async UniTask RunAsync(CancellationToken cancellationToken) {
using RR instance = new RR();
static async UniTask RunAsync(CancellationToken cancellationToken) {
s_logger.Info("Loading engine config");
EngineConfigAsset configAsset = Resources.Load<EngineConfigAsset>(RConsts.k_EngineConfigResourcesPath);
if (configAsset == null) {
s_logger.Error($"Couldn't load engine config from resources: {RConsts.k_EngineConfigResourcesPath}");
return;
}
RR.Shared = instance;
if (!configAsset.initializeOnLoad) {
return;
}
_logger.Debug("running");
using RR instance = new();
RR.s_Shared = instance;
await instance.Init(cancellationToken);
await instance.Run(cancellationToken);
_logger.Debug("stopped");
s_logger.Info("Initializing RR");
await instance.Init(configAsset, cancellationToken);
s_logger.Info("Loading main scene");
await SceneManager.LoadSceneAsync(RConsts.k_MainSceneBuildIndex, LoadSceneMode.Single).ToUniTask(cancellationToken: cancellationToken);
s_logger.Info("Starting RR");
instance.Run();
}
}
}

View File

@@ -0,0 +1,46 @@
using System;
using UnityEngine;
namespace RebootKit.Engine.Foundation {
[Serializable]
public struct FloatRange {
public float min;
public float max;
public FloatRange(float min, float max) {
this.min = min;
this.max = max;
}
public float Lerp(float t) {
return Mathf.Lerp(min, max, t);
}
public float Random() {
return UnityEngine.Random.Range(min, max);
}
}
[Serializable]
public struct IntRange {
public int min;
public int max;
public IntRange(int min, int max) {
this.min = min;
this.max = max;
}
public int Lerp(float t) {
return (int) Mathf.Lerp(min, max, t);
}
public int RandomInclusive() {
return UnityEngine.Random.Range(min, max + 1);
}
public int RandomExclusive() {
return UnityEngine.Random.Range(min, max);
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 16444e84cabf4bb1b992202508a5d1d5
timeCreated: 1742636719

View File

@@ -10,23 +10,34 @@ namespace RebootKit.Engine.Foundation {
void OnTick();
}
public class ControllersManager : IDisposable {
private readonly List<IController> _controllers = new();
private bool _isRunning;
private readonly CancellationToken _cancellationToken;
public class ControllersManager<TController> : IDisposable where TController : IController {
readonly CancellationToken _cancellationToken;
readonly List<TController> _controllers = new();
bool _isRunning;
public ControllersManager(CancellationToken cancellationToken) {
_cancellationToken = cancellationToken;
}
public void Dispose() {
foreach (IController controller in _controllers) {
foreach (TController controller in _controllers) {
controller.Dispose();
}
}
public void Add(IController controller) {
public bool TryFind<T>(out T outController) where T : IController {
foreach (TController controller in _controllers) {
if (controller is T res) {
outController = res;
return true;
}
}
outController = default;
return false;
}
public void Add(TController controller) {
_controllers.Add(controller);
if (_isRunning) {
@@ -34,7 +45,7 @@ namespace RebootKit.Engine.Foundation {
}
}
public void Remove(IController controller) {
public void Remove(TController controller) {
if (_isRunning) {
controller.OnStop();
}
@@ -47,7 +58,7 @@ namespace RebootKit.Engine.Foundation {
return;
}
foreach (IController controller in _controllers) {
foreach (TController controller in _controllers) {
await controller.OnStart(cancellationToken);
}
@@ -59,7 +70,7 @@ namespace RebootKit.Engine.Foundation {
return;
}
foreach (IController controller in _controllers) {
foreach (TController controller in _controllers) {
controller.OnStop();
}
@@ -67,26 +78,26 @@ namespace RebootKit.Engine.Foundation {
}
public void Tick() {
foreach (IController controller in _controllers) {
foreach (TController controller in _controllers) {
controller.OnTick();
}
}
}
public static class ControllersManagerUtils {
public static void Add(this ControllersManager manager, ControllerAsset asset, DIContext context) {
public static void Add(this ControllersManager<IController> manager, ControllerAsset asset, DIContext context) {
IController controller = asset.Create(context);
manager.Add(controller);
}
public static void Add(this ControllersManager manager, List<ControllerAsset> controllerAsset, DIContext context) {
public static void Add(this ControllersManager<IController> manager, List<ControllerAsset> controllerAsset, DIContext context) {
foreach (ControllerAsset asset in controllerAsset) {
IController controller = asset.Create(context);
manager.Add(controller);
}
}
public static void Add(this ControllersManager manager, ControllerAsset[] controllerAsset, DIContext context) {
public static void Add(this ControllersManager<IController> manager, ControllerAsset[] controllerAsset, DIContext context) {
foreach (ControllerAsset asset in controllerAsset) {
IController controller = asset.Create(context);
manager.Add(controller);

View File

@@ -4,7 +4,7 @@ namespace RebootKit.Engine.Foundation {
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);
}

View File

@@ -0,0 +1,47 @@
using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
namespace RebootKit.Engine.Foundation {
public interface IPredicate {
bool Evaluate();
}
[Serializable]
public class PredicateAnd : IPredicate {
[SerializeReference] List<IPredicate> m_Rules;
public PredicateAnd(IEnumerable<IPredicate> rules) {
m_Rules = new List<IPredicate>(rules);
}
public bool Evaluate() {
return m_Rules.All(t => t.Evaluate());
}
}
[Serializable]
public class PredicateOr : IPredicate {
[SerializeReference] List<IPredicate> m_Rules;
public PredicateOr(IEnumerable<IPredicate> rules) {
m_Rules = new List<IPredicate>(rules);
}
public bool Evaluate() {
return m_Rules.Any(t => t.Evaluate());
}
}
[Serializable]
public class PredicateConsts : IPredicate {
bool m_Result;
public PredicateConsts(bool result) {
m_Result = result;
}
public bool Evaluate() => m_Result;
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 924b2e41a3f8489898792c98c9da5ce3
timeCreated: 1742687454

View File

@@ -10,42 +10,42 @@ namespace RebootKit.Engine.Foundation {
}
public readonly struct Logger {
private readonly string _name;
readonly string m_Name;
public Logger(string name) {
_name = name;
m_Name = name;
}
public void Log(LogLevel level, string message) {
switch (level) {
case LogLevel.Info:
UnityEngine.Debug.Log(FormatMessage(level, _name, message, true));
UnityEngine.Debug.Log(FormatMessage(level, m_Name, message, true));
break;
case LogLevel.Debug:
UnityEngine.Debug.Log(FormatMessage(level, _name, message, true));
UnityEngine.Debug.Log(FormatMessage(level, m_Name, message, true));
break;
case LogLevel.Warning:
UnityEngine.Debug.LogWarning(FormatMessage(level, _name, message, true));
UnityEngine.Debug.LogWarning(FormatMessage(level, m_Name, message, true));
break;
case LogLevel.Error:
UnityEngine.Debug.LogError(FormatMessage(level, _name, message, true));
UnityEngine.Debug.LogError(FormatMessage(level, m_Name, message, true));
break;
default:
throw new ArgumentOutOfRangeException(nameof(level), level, null);
}
}
[Conditional(RConsts.BuildFlagDebug)]
[Conditional(RConsts.k_BuildFlagDebug)]
public void Info(string message) {
Log(LogLevel.Info, message);
}
[Conditional(RConsts.BuildFlagDebug)]
[Conditional(RConsts.k_BuildFlagDebug)]
public void Debug(string message) {
Log(LogLevel.Debug, message);
}
[Conditional(RConsts.BuildFlagDebug)]
[Conditional(RConsts.k_BuildFlagDebug)]
public void Warning(string message) {
Log(LogLevel.Warning, message);
}
@@ -54,7 +54,7 @@ namespace RebootKit.Engine.Foundation {
Log(LogLevel.Error, message);
}
private static string FormatMessage(LogLevel level, string name, string message, bool richText) {
static string FormatMessage(LogLevel level, string name, string message, bool richText) {
if (!richText) {
string prefix = level switch {
LogLevel.Info => "",

View File

@@ -1,4 +1,5 @@
using UnityEngine;
using Unity.Assertions;
using UnityEngine;
namespace RebootKit.Engine.Foundation {
public interface IDependencyInstaller {
@@ -8,18 +9,35 @@ namespace RebootKit.Engine.Foundation {
public abstract class SceneDependencyInstaller : MonoBehaviour, IDependencyInstaller {
public abstract void Install(DIContext context);
}
public class SceneDI : MonoBehaviour, IDependencyInstaller {
[SerializeField]
private SceneDependencyInstaller[] _sceneInstallers;
[SerializeField]
private SerializableGuid _guid;
[DefaultExecutionOrder(-1000)]
public class SceneDI : MonoBehaviour, IDependencyInstaller {
static readonly Logger s_logger = new(nameof(SceneDI));
[SerializeField] SceneDependencyInstaller[] m_Installers;
void Awake() {
DIContext context = RR.DIContext;
foreach (GameObject root in gameObject.scene.GetRootGameObjects()) {
context.InjectGameObject(root);
}
}
public void Install(DIContext context) {
foreach (SceneDependencyInstaller installer in _sceneInstallers) {
foreach (SceneDependencyInstaller installer in m_Installers) {
installer.Install(context);
}
}
}
public static class DIContextGameObjectEx {
public static void InjectGameObject(this DIContext context, GameObject gameObject, bool injectChildren = true) {
Assert.IsNotNull(gameObject);
Component[] components = injectChildren ? gameObject.GetComponentsInChildren<Component>() : gameObject.GetComponents<Component>();
foreach (Component component in components) {
context.Inject(component);
}
}
}
}

View File

@@ -6,17 +6,10 @@ namespace RebootKit.Engine.Foundation {
public struct SerializableGuid : IEquatable<SerializableGuid> {
public static SerializableGuid Zero = new(0, 0, 0, 0);
[SerializeField, HideInInspector]
public uint A;
[SerializeField, HideInInspector]
public uint B;
[SerializeField, HideInInspector]
public uint C;
[SerializeField, HideInInspector]
public uint D;
[SerializeField, HideInInspector] public uint A;
[SerializeField, HideInInspector] public uint B;
[SerializeField, HideInInspector] public uint C;
[SerializeField, HideInInspector] public uint D;
public SerializableGuid(uint a, uint b, uint c, uint d) {
A = a;
@@ -45,9 +38,16 @@ namespace RebootKit.Engine.Foundation {
return HashCode.Combine(A, B, C, D);
}
public static SerializableGuid New() => new(Guid.NewGuid());
public static SerializableGuid New() {
return new SerializableGuid(Guid.NewGuid());
}
public static bool operator ==(SerializableGuid lhs, SerializableGuid rhs) => lhs.Equals(rhs);
public static bool operator !=(SerializableGuid lhs, SerializableGuid rhs) => !lhs.Equals(rhs);
public static bool operator ==(SerializableGuid lhs, SerializableGuid rhs) {
return lhs.Equals(rhs);
}
public static bool operator !=(SerializableGuid lhs, SerializableGuid rhs) {
return !lhs.Equals(rhs);
}
}
}

View File

@@ -0,0 +1,46 @@
using System;
using System.Collections.Generic;
namespace RebootKit.Engine.Foundation {
public interface IState {
void Enter();
void Exit();
}
public class StateMachine<TState> where TState : class, IState {
readonly Dictionary<Type, TState> m_States;
IState m_ActiveState;
public StateMachine() {
m_States = new Dictionary<Type, TState>();
m_ActiveState = null;
}
public StateMachine(IEnumerable<TState> states) {
foreach (TState state in states) {
AddState(state);
}
}
public void AddState(TState state) {
Type type = state.GetType();
if (!m_States.TryAdd(type, state)) {
throw new Exception($"State {type} already exists in the state machine.");
}
}
public void TransitionTo<TStateType>() where TStateType : class, TState {
Type type = typeof(TStateType);
if (!m_States.TryGetValue(type, out TState newState)) {
throw new Exception($"State {type} not found in the state machine.");
}
m_ActiveState?.Exit();
m_ActiveState = newState;
m_ActiveState.Enter();
}
public bool IsStateActive<TStateType>() where TStateType : class, TState => m_ActiveState != null && m_ActiveState.GetType() == typeof(TStateType);
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 1a328f69e2714109abf4509628aff4ea
timeCreated: 1743212938

View File

@@ -2,36 +2,27 @@
using UnityEngine;
using UnityEngine.Rendering.Universal;
namespace RebootKit.Engine.Graphics.Pixelize
{
public class PixelizeFeature : ScriptableRendererFeature
{
[Serializable]
public class PassSettings
{
public RenderPassEvent RenderPassEvent = RenderPassEvent.BeforeRenderingPostProcessing;
public int FrameHeight = 240;
}
namespace RebootKit.Engine.Graphics.Pixelize {
public class PixelizeFeature : ScriptableRendererFeature {
[SerializeField] PassSettings _settings;
[SerializeField]
private PassSettings _settings;
PixelizePass _pass;
private PixelizePass _pass;
public override void Create()
{
public override void Create() {
_pass = new PixelizePass(_settings);
}
public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingData renderingData)
{
public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingData renderingData) {
#if UNITY_EDITOR
if (renderingData.cameraData.isSceneViewCamera)
{
return;
}
if (renderingData.cameraData.isSceneViewCamera) return;
#endif
renderer.EnqueuePass(_pass);
}
[Serializable]
public class PassSettings {
public RenderPassEvent RenderPassEvent = RenderPassEvent.BeforeRenderingPostProcessing;
public int FrameHeight = 240;
}
}
}

View File

@@ -1,31 +1,28 @@
using UnityEngine;
using System;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Rendering.Universal;
namespace RebootKit.Engine.Graphics.Pixelize
{
public class PixelizePass : ScriptableRenderPass
{
private static int PixelBufferID = Shader.PropertyToID("_PixelBuffer");
namespace RebootKit.Engine.Graphics.Pixelize {
public class PixelizePass : ScriptableRenderPass {
static readonly int PixelBufferID = Shader.PropertyToID("_PixelBuffer");
private PixelizeFeature.PassSettings _settings;
RenderTargetIdentifier _colorBuffer;
int _frameHeight;
int _frameWidth;
private RenderTargetIdentifier _colorBuffer;
private RenderTargetIdentifier _pixelBuffer;
readonly Material _material;
RenderTargetIdentifier _pixelBuffer;
private Material _material;
private int _frameWidth;
private int _frameHeight;
readonly PixelizeFeature.PassSettings _settings;
public PixelizePass(PixelizeFeature.PassSettings settings)
{
public PixelizePass(PixelizeFeature.PassSettings settings) {
_settings = settings;
renderPassEvent = settings.RenderPassEvent;
_material = CoreUtils.CreateEngineMaterial("Hidden/Szafa/Pixelize");
}
public override void OnCameraSetup(CommandBuffer cmd, ref RenderingData renderingData)
{
public override void OnCameraSetup(CommandBuffer cmd, ref RenderingData renderingData) {
_colorBuffer = renderingData.cameraData.renderer.cameraColorTargetHandle;
RenderTextureDescriptor descriptor = renderingData.cameraData.cameraTargetDescriptor;
@@ -43,21 +40,15 @@ namespace RebootKit.Engine.Graphics.Pixelize
_pixelBuffer = new RenderTargetIdentifier(PixelBufferID);
}
public override void OnCameraCleanup(CommandBuffer cmd)
{
if (cmd == null)
{
throw new System.ArgumentNullException(nameof(cmd));
}
public override void OnCameraCleanup(CommandBuffer cmd) {
if (cmd == null) throw new ArgumentNullException(nameof(cmd));
cmd.ReleaseTemporaryRT(PixelBufferID);
}
public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData)
{
public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData) {
CommandBuffer cmd = CommandBufferPool.Get();
using (new ProfilingScope(cmd, new ProfilingSampler("Pixelize Pass")))
{
using (new ProfilingScope(cmd, new ProfilingSampler("Pixelize Pass"))) {
// Blit(cmd, _colorBuffer, _pixelBuffer, _material);
// Blit(cmd, _pixelBuffer, _colorBuffer);
}

View File

@@ -1,14 +1,17 @@
using RebootKit.Engine.Foundation;
using RebootKit.Engine.Graphics;
using RebootKit.Engine.Services.ConsoleUI;
using UnityEngine;
namespace RebootKit.Engine {
public class MainSceneInstaller : SceneDependencyInstaller {
[SerializeField]
private MainCameraService _mainCameraService;
[SerializeField] MainCameraService _mainCameraService;
[SerializeField] ConsoleUIService _consoleUIService;
public override void Install(DIContext context) {
context.Bind(_mainCameraService);
context.Bind(_consoleUIService);
}
}
}

View File

@@ -0,0 +1,10 @@
using UnityEngine;
namespace RebootKit.Engine {
public abstract class RAsset : ScriptableObject {
}
public abstract class ConfigAsset<TConfig> : RAsset {
public TConfig config;
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 79caceb466274368bfc8bd2ec9599527
timeCreated: 1743213149

View File

@@ -1,18 +1,14 @@
namespace RebootKit.Engine
{
namespace RebootKit.Engine {
public static class RConsts {
public const int MainSceneBuildIndex = 0;
public const int k_MainSceneBuildIndex = 0;
public const string EngineConfigAssetName = "RealityRebootKit";
public const string EngineConfigResourcesPath = "TheGame/" + EngineConfigAssetName;
public const string AssetMenu = "Reboot Reality/";
public const string FPPKitAssetMenu = AssetMenu + "FPP Kit/";
public const string ServiceAssetMenu = AssetMenu + "Services/";
public const string UnitsAssetMenu = AssetMenu + "Units/";
public const string GameModeAssetMenu = AssetMenu + "GameModes/";
public const string WorldAssetMenu = AssetMenu + "World/";
public const string BuildFlagDebug = "RR_DEBUG";
public const string k_EngineConfigAssetName = "RealityRebootKit";
public const string k_EngineConfigResourcesPath = "TheGame/" + k_EngineConfigAssetName;
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_BuildFlagDebug = "RR_DEBUG";
}
}

View File

@@ -0,0 +1,51 @@
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.Events;
namespace RebootKit.Engine {
public partial class RR {
public static ConsoleService Console => s_Shared.m_ConsoleService;
public static InputService Input => s_Shared.m_InputService;
public static WorldService World => s_Shared.m_WorldService;
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);
if (cvar != null) {
return cvar;
}
cvar = new CVar(name, defaultValue);
Console.Replace(cvar);
return cvar;
}
public static CVar CVarNumber(string name, double defaultValue = 0) {
CVar cvar = Console.GetCVar(name);
if (cvar != null) {
return cvar;
}
cvar = new CVar(name, defaultValue);
Console.Replace(cvar);
return cvar;
}
public static CVar CVarString(string name, string defaultValue = "") {
CVar cvar = Console.GetCVar(name);
if (cvar != null) {
return cvar;
}
cvar = new CVar(name, defaultValue);
Console.Replace(cvar);
return cvar;
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 90375a4c5db84d538d31d54f302ac022
timeCreated: 1743212750

View File

@@ -0,0 +1,52 @@
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>();
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: d7b1b5cbd7e04f38ba5f61a04709336b
timeCreated: 1743213081

View File

@@ -7,139 +7,62 @@ using RebootKit.Engine.Services.Game;
using RebootKit.Engine.Services.Input;
using RebootKit.Engine.Services.Simulation;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.Assertions;
using UnityEngine.Events;
using Logger = RebootKit.Engine.Foundation.Logger;
/*
* Game starts:
* - Entry point creates instance of RR
* - Core Services are installed
* - Loads main scene and installs deps
* -
*/
namespace RebootKit.Engine {
public abstract class RAsset : ScriptableObject {
}
public class RR : IDisposable {
public static RR Shared { get; set; }
public partial class RR : IDisposable {
internal static RR s_Shared;
private static readonly Logger Logger = new("RR");
static readonly Logger s_logger = new("RR");
private EngineConfigAsset _engineConfigAsset;
ConsoleService m_ConsoleService;
DIContext m_DIContext;
private ConsoleService _consoleService;
private InputService _inputService;
private WorldService _worldService;
private GameService _gameService;
EngineConfigAsset m_EngineConfigAsset;
GameService m_GameService;
InputService m_InputService;
WorldService m_WorldService;
private DIContext _diContext;
readonly UnityEvent<string, CVarValue> m_CVarChanged = new();
public void Dispose() {
m_CVarChanged.RemoveAllListeners();
}
public async UniTask Init(CancellationToken cancellationToken) {
Logger.Info("Waking up");
public async UniTask Init(EngineConfigAsset configAsset, CancellationToken cancellationToken) {
Assert.IsNotNull(configAsset, "Config asset is required");
s_logger.Info("Waking up");
m_EngineConfigAsset = configAsset;
Logger.Info("Loading engine config");
_engineConfigAsset = Resources.Load<EngineConfigAsset>(RConsts.EngineConfigResourcesPath);
if (_engineConfigAsset == null) {
Logger.Error($"Couldn't load engine config from resources: {RConsts.EngineConfigResourcesPath}");
return;
}
Logger.Info("Loading engine found");
_diContext = new DIContext();
_diContext.AddInjector(new CVarFieldInjector());
m_DIContext = new DIContext();
m_DIContext.AddInjector(new CVarFieldInjector());
CreateCoreServices();
InstallMainScene();
InitializeAppStateMachine();
await UniTask.Yield(cancellationToken);
}
public async UniTask Run(CancellationToken cancellationToken) {
Logger.Info($"Starting initial game mode");
await _gameService.Start(_engineConfigAsset.StartingGameMode, cancellationToken);
public void Run() {
OpenMainMenu();
}
private TService CreateService<TService>(ServiceAsset<TService> asset) where TService : class, IService {
TService service = asset.Create(_diContext);
_diContext.Bind(service);
TService CreateService<TService>(ServiceAsset<TService> asset) where TService : class, IService {
TService service = asset.Create(m_DIContext);
m_DIContext.Bind(service);
return service;
}
private void CreateCoreServices() {
Logger.Debug("Registering core services");
_consoleService = CreateService(_engineConfigAsset.ConsoleService);
_inputService = CreateService(_engineConfigAsset.InputService);
_worldService = CreateService(_engineConfigAsset.WorldService);
_gameService = CreateService(_engineConfigAsset.GameService);
}
void CreateCoreServices() {
s_logger.Debug("Registering core services");
private void InstallMainScene() {
GameObject[] gameObjects = SceneManager.GetSceneByBuildIndex(RConsts.MainSceneBuildIndex).GetRootGameObjects();
if (gameObjects.Length == 0) {
return;
}
foreach (GameObject root in gameObjects) {
SceneDI di = root.GetComponent<SceneDI>();
if (di == null) {
continue;
}
di.Install(_diContext);
}
}
//
// API
//
/// Services
public static ConsoleService Console() => Shared._consoleService;
public static InputService Input() => Shared._inputService;
public static WorldService World() => Shared._worldService;
public static GameService Game() => Shared._gameService;
/// CVars
public static CVar CVarIndex(string name, int defaultValue = -1) {
CVar cvar = Console().GetCVar(name);
if (cvar != null) {
return cvar;
}
cvar = new CVar(name, defaultValue);
Console().Replace(cvar);
return cvar;
}
public static CVar CVarNumber(string name, double defaultValue = 0) {
CVar cvar = Console().GetCVar(name);
if (cvar != null) {
return cvar;
}
cvar = new CVar(name, defaultValue);
Console().Replace(cvar);
return cvar;
}
public static CVar CVarString(string name, string defaultValue = "") {
CVar cvar = Console().GetCVar(name);
if (cvar != null) {
return cvar;
}
cvar = new CVar(name, defaultValue);
Console().Replace(cvar);
return cvar;
m_ConsoleService = CreateService(m_EngineConfigAsset.coreServices.consoleService);
m_InputService = CreateService(m_EngineConfigAsset.coreServices.inputService);
m_WorldService = CreateService(m_EngineConfigAsset.coreServices.worldService);
m_GameService = CreateService(m_EngineConfigAsset.coreServices.gameService);
}
}
}

View File

@@ -7,45 +7,45 @@ namespace RebootKit.Engine.Services.Console {
[Serializable]
public struct CVarValue {
public CVarValueKind Kind;
public CVarValueKind kind;
public double NumberValue;
public string StringValue;
public double numberValue;
public string stringValue;
public CVarValue(int value) {
Kind = CVarValueKind.Number;
NumberValue = value;
StringValue = null;
kind = CVarValueKind.Number;
numberValue = value;
stringValue = null;
}
public CVarValue(float value) {
Kind = CVarValueKind.Number;
NumberValue = value;
StringValue = null;
kind = CVarValueKind.Number;
numberValue = value;
stringValue = null;
}
public CVarValue(double value) {
Kind = CVarValueKind.Number;
NumberValue = value;
StringValue = null;
kind = CVarValueKind.Number;
numberValue = value;
stringValue = null;
}
public CVarValue(string value) {
Kind = CVarValueKind.String;
NumberValue = 0;
StringValue = value;
kind = CVarValueKind.String;
numberValue = 0;
stringValue = value;
}
public void CopyFrom(CVarValue value) {
Kind = value.Kind;
NumberValue = value.NumberValue;
StringValue = value.StringValue;
kind = value.kind;
numberValue = value.numberValue;
stringValue = value.stringValue;
}
public override string ToString() {
return Kind switch {
CVarValueKind.Number => NumberValue.ToString(),
CVarValueKind.String => $"\"{StringValue}\"",
return kind switch {
CVarValueKind.Number => numberValue.ToString(),
CVarValueKind.String => $"\"{stringValue}\"",
_ => throw new ArgumentOutOfRangeException()
};
}
@@ -58,108 +58,98 @@ namespace RebootKit.Engine.Services.Console {
[Serializable]
public class CVar {
public CVarFlags Flags;
public string Name;
public string Description;
public CVarValue DefaultValue;
public CVarValue Value { get; private set; }
public int IndexValue => (int) Value.NumberValue;
public float FloatValue => (float) Value.NumberValue;
public double NumberValue => Value.NumberValue;
public string StringValue => Value.StringValue;
public event Action OnChanged = delegate { };
public CVarFlags flags;
public string name;
public string description;
public CVarValue defaultValue;
public CVar(CVar other) {
Flags = other.Flags;
Name = other.Name;
Description = other.Description;
DefaultValue = other.DefaultValue;
flags = other.flags;
name = other.name;
description = other.description;
defaultValue = other.defaultValue;
Value = other.Value;
}
public CVar(string name, CVarValue value, string description = "") {
Name = name;
Description = description;
DefaultValue = value;
Value = DefaultValue;
this.name = name;
this.description = description;
defaultValue = value;
Value = defaultValue;
}
public CVar(string name, int value, string description = "") {
Name = name;
Description = description;
DefaultValue = new CVarValue(value);
Value = DefaultValue;
this.name = name;
this.description = description;
defaultValue = new CVarValue(value);
Value = defaultValue;
}
public CVar(string name, float value, string description = "") {
Name = name;
Description = description;
DefaultValue = new CVarValue(value);
Value = DefaultValue;
this.name = name;
this.description = description;
defaultValue = new CVarValue(value);
Value = defaultValue;
}
public CVar(string name, double value, string description = "") {
Name = name;
Description = description;
DefaultValue = new CVarValue(value);
Value = DefaultValue;
this.name = name;
this.description = description;
defaultValue = new CVarValue(value);
Value = defaultValue;
}
public CVar(string name, string value, string description = "") {
Name = name;
Description = description;
DefaultValue = new CVarValue(value);
Value = DefaultValue;
this.name = name;
this.description = description;
defaultValue = new CVarValue(value);
Value = defaultValue;
}
public CVarValue Value { get; private set; }
public int IndexValue => (int) Value.numberValue;
public float FloatValue => (float) Value.numberValue;
public double NumberValue => Value.numberValue;
public string StringValue => Value.stringValue;
public event Action StateChanged = delegate { };
public void Set(int value) {
if (Flags.HasFlag(CVarFlags.ReadOnly)) {
return;
}
if (flags.HasFlag(CVarFlags.ReadOnly)) return;
Value = new CVarValue(value);
OnChanged?.Invoke();
StateChanged?.Invoke();
}
public void Set(float value) {
if (Flags.HasFlag(CVarFlags.ReadOnly)) {
return;
}
if (flags.HasFlag(CVarFlags.ReadOnly)) return;
Value = new CVarValue(value);
OnChanged?.Invoke();
StateChanged?.Invoke();
}
public void Set(string value) {
if (Flags.HasFlag(CVarFlags.ReadOnly)) {
return;
}
if (flags.HasFlag(CVarFlags.ReadOnly)) return;
Value = new CVarValue(value);
OnChanged?.Invoke();
StateChanged?.Invoke();
}
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;
OnChanged?.Invoke();
Value = defaultValue;
StateChanged?.Invoke();
}
public override string ToString() {

View File

@@ -1,17 +1,14 @@
using UnityEngine;
namespace RebootKit.Engine.Services.Console {
[CreateAssetMenu(menuName = RConsts.AssetMenu + "cvar", fileName = "cvar")]
[CreateAssetMenu(menuName = RConsts.k_AddComponentMenu + "cvar", fileName = "cvar")]
public class CVarAsset : ScriptableObject {
[SerializeField]
private CVar _cvar;
[SerializeField] CVar m_CVar;
public CVar Create(string cvarName = null) {
CVar cvar = new(_cvar);
CVar cvar = new(m_CVar);
if (cvarName != null) {
cvar.Name = cvarName;
}
if (cvarName != null) cvar.name = cvarName;
return cvar;
}

View File

@@ -5,9 +5,6 @@ using RebootKit.Engine.Foundation;
namespace RebootKit.Engine.Services.Console {
[AttributeUsage(AttributeTargets.Field)]
public class CVarAttribute : Attribute {
public string Name { get; }
public CVarValue Value { get; }
public CVarAttribute(string name, float defaultValue) {
Name = name;
Value = new CVarValue(defaultValue);
@@ -27,19 +24,20 @@ namespace RebootKit.Engine.Services.Console {
Name = name;
Value = new CVarValue(defaultValue);
}
public string Name { get; }
public CVarValue Value { get; }
}
public class CVarFieldInjector : DIContext.IFieldInjector {
private static readonly Logger Logger = new(nameof(CVarFieldInjector));
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;
}
if (!Attribute.IsDefined(field, typeof(CVarAttribute))) return false;
ConsoleService console = context.Resolve<ConsoleService>();
if (console == null) {
Logger.Error($"Cannot inject field because cannot resolve `{nameof(ConsoleService)}`");
s_logger.Error($"Cannot inject field because cannot resolve `{nameof(ConsoleService)}`");
return false;
}

View File

@@ -2,11 +2,7 @@
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using Cysharp.Threading.Tasks;
using RebootKit.Engine.Foundation;
using RebootKit.Engine.Services.Input;
using UnityEngine.InputSystem;
using Logger = RebootKit.Engine.Foundation.Logger;
namespace RebootKit.Engine.Services.Console {
@@ -21,144 +17,91 @@ namespace RebootKit.Engine.Services.Console {
public string Description { get; } = "Prints available commands/cvars and their descriptions.";
public void Execute(string[] args) {
RR.Console().PrintHelp();
RR.Console.PrintHelp();
}
}
public class ConsoleService : IService {
private static readonly Logger _logger = new(nameof(ConsoleService));
static readonly Logger _logger = new(nameof(ConsoleService));
[Serializable]
public class Config {
public ConsoleUI ConsoleUIPrefab;
public ScriptableInputAction ToggleAction;
}
readonly List<IConsoleCommand> _commands = new();
readonly List<CVar> _cvars = new();
private ConsoleUI _ui;
private Config _config;
private List<IConsoleCommand> _commands = new();
private List<CVar> _cvars = new();
public bool IsVisible => _ui.IsVisible;
public ConsoleService(Config config) {
_config = config;
public ConsoleService() {
_logger.Info("Waking up");
_ui = UnityEngine.Object.Instantiate(_config.ConsoleUIPrefab);
UnityEngine.Object.DontDestroyOnLoad(_ui.gameObject);
_config.ToggleAction.Action.Enable();
_config.ToggleAction.Action.performed += OnToggleAction;
RegisterCommand(new HelpCommand());
_ui.SetVisibility(false);
_ui.Clear();
_ui.Write("Hello shelf\n");
}
public void Dispose() {
if (_ui != null) {
UnityEngine.Object.Destroy(_ui);
_ui = null;
}
}
_config.ToggleAction.Action.performed -= OnToggleAction;
public event Action<string> OnOutputMessage = _ => { };
public void WriteToOutput(string message) {
OnOutputMessage?.Invoke(message);
}
public bool CVarExists(string name) {
foreach (CVar cvar in _cvars) {
if (cvar.Name.Equals(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)) {
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;
}
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);
}
CVar foundCVar = GetCVar(cvar.name);
if (foundCVar != null) _cvars.Remove(foundCVar);
_cvars.Add(cvar);
}
private string[] ParseCommandInputArguments(string text) {
if (text.Length == 0) {
return Array.Empty<string>();
}
string[] ParseCommandInputArguments(string text) {
if (text.Length == 0) return Array.Empty<string>();
return new string[] {text};
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 _commands)
if (command.Name.Equals(commandName)) {
command.Execute(arguments);
return;
}
}
foreach (CVar cvar in _cvars) {
if (cvar.Name.Equals(commandName)) {
if (arguments.Length == 1) {
cvar.ParseFromString(arguments[0]);
}
foreach (CVar cvar in _cvars)
if (cvar.name.Equals(commandName)) {
if (arguments.Length == 1) cvar.ParseFromString(arguments[0]);
_ui.Write($"<b>{cvar.Name}</b> - {cvar.ToString()}\n");
WriteToOutput($"<b>{cvar.name}</b> - {cvar}\n");
return;
}
}
_ui.Write($"ERROR: Command/CVar `{commandName}` not found.");
}
public void ToggleVisibility() {
_ui.SetVisibility(!_ui.IsVisible);
if (_ui.IsVisible) {
RR.Input().DisableControls();
RR.Input().UnlockCursor();
} else {
RR.Input().EnableControls();
RR.Input().LockCursor();
}
WriteToOutput($"ERROR: Command/CVar `{commandName}` not found.");
}
public void RegisterCommand(IConsoleCommand command) {
@@ -186,17 +129,13 @@ namespace RebootKit.Engine.Services.Console {
message.AppendLine("Available cvars:");
foreach (CVar cvar in _cvars) {
message.Append(" ");
message.Append(cvar.Name);
message.Append(cvar.name);
message.Append(" - ");
message.Append(cvar.Description);
message.Append(cvar.description);
message.AppendLine();
}
_ui.Write(message.ToString());
}
private void OnToggleAction(InputAction.CallbackContext obj) {
ToggleVisibility();
WriteToOutput(message.ToString());
}
}
}

View File

@@ -2,19 +2,14 @@
using UnityEngine;
namespace RebootKit.Engine.Services.Console {
[CreateAssetMenu(menuName = RConsts.ServiceAssetMenu + "Console")]
[CreateAssetMenu(menuName = RConsts.k_ServiceAssetMenu + "Console")]
public class ConsoleServiceAsset : ServiceAsset<ConsoleService> {
[SerializeField]
private ConsoleService.Config _config;
[SerializeField] CVar[] _initialCVars;
[SerializeField]
private CVar[] _initialCVars;
[SerializeField]
private bool _loadCVarsFromResources = true;
[SerializeField] bool _loadCVarsFromResources = true;
public override ConsoleService Create(DIContext context) {
ConsoleService service = new(_config);
ConsoleService service = new();
context.Inject(service);
foreach (CVar cvar in _initialCVars) {

View File

@@ -1,63 +0,0 @@
using System.Text;
using UnityEngine;
using UnityEngine.UIElements;
using Logger = RebootKit.Engine.Foundation.Logger;
namespace RebootKit.Engine.Services.Console {
public class ConsoleUI : MonoBehaviour {
private static readonly Logger Logger = new(nameof(ConsoleUI));
private StringBuilder _content = new();
[SerializeField]
private UIDocument _document;
private Label _labelMessage;
private TextField _textField;
private Button _submitButton;
public bool IsVisible { get; private set; }
private void OnEnable() {
IsVisible = _document.enabled;
VisualElement root = _document.rootVisualElement;
_labelMessage = root.Q<Label>("console-window-message");
_labelMessage.text = "SIEMA";
_textField = root.Q<TextField>("console-text-field");
_submitButton = root.Q<Button>("console-btn-submit");
_submitButton.clicked += OnSubmitButtonClicked;
}
private void OnSubmit(string input) {
RR.Console().Execute(input);
_textField.value = input;
}
public void SetVisibility(bool visible) {
_document.enabled = visible;
IsVisible = visible;
}
public void Write(string message) {
_content.Append(message);
_labelMessage.text = _content.ToString();
_labelMessage.MarkDirtyRepaint();
}
public void Clear() {
_content.Clear();
_labelMessage.text = "";
if (_textField != null) {
_textField.label = "";
}
}
private void OnSubmitButtonClicked() {
Logger.Info("Submit");
OnSubmit(_textField.value);
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 0500959e68464db2abd534e30f6f5978
timeCreated: 1742422569

View File

@@ -0,0 +1,81 @@
using System.Text;
using RebootKit.Engine.Foundation;
using RebootKit.Engine.Services.Input;
using UnityEngine;
using UnityEngine.InputSystem;
using Logger = RebootKit.Engine.Foundation.Logger;
namespace RebootKit.Engine.Services.ConsoleUI {
public class ConsoleUIService : ServiceMonoBehaviour {
static readonly Logger s_logger = new(nameof(ConsoleUIService));
[SerializeField] ConsoleVC m_ConsoleVC;
[SerializeField] ScriptableInputAction m_ToggleAction;
readonly StringBuilder m_Content = new();
public bool IsVisible => m_ConsoleVC.gameObject.activeSelf;
void Awake() {
SetVisibility(false);
}
void OnEnable() {
s_logger.Info("OnEnable console");
m_ToggleAction.Action.Enable();
m_ToggleAction.Action.performed += OnToggleAction;
m_ConsoleVC.InputSubmitted += OnUserInput;
m_ConsoleVC.ClearRequested += Clear;
RR.Console.OnOutputMessage += Write;
}
void OnDisable() {
m_ToggleAction.Action.performed -= OnToggleAction;
m_ConsoleVC.InputSubmitted -= OnUserInput;
m_ConsoleVC.ClearRequested -= Clear;
RR.Console.OnOutputMessage -= Write;
}
public override void Dispose() {
}
public void ToggleVisibility() {
SetVisibility(!IsVisible);
if (IsVisible) {
RR.Input.DisableControls();
RR.Input.UnlockCursor();
m_ConsoleVC.SetMessageContent(m_Content.ToString());
} else {
RR.Input.EnableControls();
RR.Input.LockCursor();
}
}
void OnUserInput(string input) {
RR.Console.Execute(input);
}
public void SetVisibility(bool visible) {
m_ConsoleVC.gameObject.SetActive(visible);
}
public void Write(string message) {
m_Content.AppendLine(message);
m_ConsoleVC.SetMessageContent(m_Content.ToString());
}
public void Clear() {
m_Content.Clear();
m_ConsoleVC.SetMessageContent(string.Empty);
}
void OnToggleAction(InputAction.CallbackContext obj) {
ToggleVisibility();
}
}
}

View File

@@ -0,0 +1,62 @@
using System;
using UnityEngine;
using UnityEngine.UIElements;
using Logger = RebootKit.Engine.Foundation.Logger;
namespace RebootKit.Engine.Services.ConsoleUI {
public class ConsoleVC : MonoBehaviour {
static readonly Logger s_logger = new(nameof(ConsoleVC));
[SerializeField] UIDocument m_Document;
Label m_LabelMessage;
VisualElement m_Root;
ScrollView m_ScrollView;
TextField m_TextField;
void OnEnable() {
m_Root = m_Document.rootVisualElement;
m_LabelMessage = m_Root.Q<Label>("console-window-message");
m_TextField = m_Root.Q<TextField>("console-text-field");
m_TextField.value = string.Empty;
m_TextField.RegisterCallback<KeyUpEvent>(ev => {
if (ev.keyCode == KeyCode.Return) {
Submit();
ev.StopPropagation();
}
});
Button submitButton = m_Root.Q<Button>("console-btn-submit");
submitButton.RegisterCallback<ClickEvent>(_ => { Submit(); });
Button clearButton = m_Root.Q<Button>("console-btn-clear");
clearButton.RegisterCallback<ClickEvent>(_ => { Clear(); });
m_ScrollView = m_Root.Q<ScrollView>("console-scrollview");
m_TextField.schedule.Execute(() => m_TextField.Focus()).StartingIn(1);
}
public event Action<string> InputSubmitted = _ => { };
public event Action ClearRequested = () => { };
public void SetMessageContent(string message) {
m_LabelMessage.text = message;
m_ScrollView.schedule.Execute(() => { m_ScrollView.scrollOffset = new Vector2(0, m_ScrollView.contentContainer.contentRect.height); }).StartingIn(16);
}
void Submit() {
InputSubmitted.Invoke(m_TextField.value);
m_TextField.value = string.Empty;
m_TextField.Focus();
}
void Clear() {
ClearRequested.Invoke();
m_TextField.value = string.Empty;
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: a6131b8af74b4894ba7b95b12286bc66
timeCreated: 1742461272

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: f7a30943696f49638fd85fb1f89d5a26
timeCreated: 1743250667

View File

@@ -0,0 +1,28 @@
using System.Threading;
using Cysharp.Threading.Tasks;
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);
}
void SetOverlayModeChanged(int mode) {
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: f18f4d0e8d914fdca81f98faf0e1546f
timeCreated: 1743249301

View File

@@ -0,0 +1,46 @@
using System;
using Cysharp.Threading.Tasks;
using RebootKit.Engine.Foundation;
using RebootKit.Engine.Services.Console;
using UnityEngine;
namespace RebootKit.Engine.Services.Development {
static class DebugCVars {
public const string k_OverlayMode = "debug.mode";
}
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 OnDisable() {
Dispose();
}
public override void Dispose() {
m_CVarChangedListener.Dispose();
}
void OnOverlayModeChanged(int mode) {
if (mode == 1) {
m_DebugOverlayView.Show(destroyCancellationToken).Forget();
} else {
m_DebugOverlayView.Hide(destroyCancellationToken).Forget();
}
}
void OnCVarChanged(string cvarName, CVarValue value) {
if (cvarName == DebugCVars.k_OverlayMode) {
OnOverlayModeChanged((int)value.numberValue);
}
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 0ea9757c83234daaae0d4227ac495da2
timeCreated: 1743250681

View File

@@ -4,14 +4,9 @@ using RebootKit.Engine.Foundation;
using UnityEngine;
namespace RebootKit.Engine.Services.Game {
[Serializable]
public class GameModeConfig {
public ControllerAsset[] Controllers;
}
public abstract class GameModeAsset : FactoryAsset<GameMode> {
[field: SerializeField]
public GameModeConfig GameModeConfig { get; private set; }
public GameMode.Config GameModeConfig { get; private set; }
public override GameMode Create(DIContext context) {
GameMode gameMode = new(GameModeConfig);
@@ -22,51 +17,62 @@ namespace RebootKit.Engine.Services.Game {
public abstract void ConfigureGameMode(GameMode gameMode);
}
public class GameMode : IDisposable {
private readonly GameModeConfig _config;
private readonly ControllersManager _controllersManager;
[Serializable]
public class Config {
public ControllerAsset[] controllers;
}
[Inject]
private DIContext _diContext;
readonly Config m_Config;
readonly ControllersManager<IController> m_Controllers;
private CancellationTokenSource _destroyCancellationTokenSource;
private bool _isRunning;
readonly CancellationTokenSource m_DestroyCancellationTokenSource;
public GameMode(GameModeConfig config) {
_config = config;
_isRunning = false;
[Inject] DIContext m_DIContext;
bool m_IsRunning;
_destroyCancellationTokenSource = new CancellationTokenSource();
_controllersManager = new ControllersManager(_destroyCancellationTokenSource.Token);
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() {
_destroyCancellationTokenSource.Cancel();
_controllersManager.Dispose();
m_DestroyCancellationTokenSource.Cancel();
m_Controllers.Dispose();
}
public async Awaitable<bool> Start(CancellationToken cancellationToken) {
_controllersManager.Add(_config.Controllers, _diContext);
await _controllersManager.Start(cancellationToken);
m_Controllers.Add(m_Config.controllers, m_DIContext);
await m_Controllers.Start(cancellationToken);
_isRunning = true;
m_IsRunning = true;
return true;
}
public void Stop() {
_isRunning = false;
m_IsRunning = false;
_controllersManager.Stop();
m_Controllers.Stop();
}
public void Tick() {
_controllersManager.Tick();
m_Controllers.Tick();
}
public void AddController(IController controller) {
_controllersManager.Add(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;
}
}
}

View File

@@ -5,39 +5,42 @@ using UnityEngine.Assertions;
namespace RebootKit.Engine.Services.Game {
public class GameService : IService {
private static readonly Logger Logger = new(nameof(GameService));
static readonly Logger s_logger = new(nameof(GameService));
[Inject] DIContext m_DIContext;
GameMode m_GameMode;
GameModeAsset m_GameModeAsset;
bool m_isRunning;
[Inject]
private DIContext _diContext;
private GameModeAsset _gameModeAsset;
private GameMode _gameMode;
private bool _running;
public void Dispose() {
_running = false;
_gameMode.Dispose();
m_isRunning = false;
m_GameMode.Dispose();
}
public async UniTask Start(GameModeAsset asset, CancellationToken cancellationToken) {
Assert.IsNotNull(asset);
_gameMode = asset.Create(_diContext);
await _gameMode.Start(cancellationToken);
m_GameMode = asset.Create(m_DIContext);
await m_GameMode.Start(cancellationToken);
Run(cancellationToken).Forget();
}
private async UniTask Run(CancellationToken cancellationToken) {
if (_gameMode == null) {
Logger.Error("Trying to run game without game mode");
async UniTask Run(CancellationToken cancellationToken) {
if (m_GameMode == null) {
s_logger.Error("Trying to run game without game mode");
return;
}
_running = true;
while (_running) {
m_isRunning = true;
while (m_isRunning) {
await UniTask.Yield(PlayerLoopTiming.Update, cancellationToken);
_gameMode.Tick();
m_GameMode.Tick();
if (cancellationToken.IsCancellationRequested) {
return;
}
}
}
}

View File

@@ -2,7 +2,7 @@
using UnityEngine;
namespace RebootKit.Engine.Services.Game {
[CreateAssetMenu(menuName = RConsts.ServiceAssetMenu + "Game")]
[CreateAssetMenu(menuName = RConsts.k_ServiceAssetMenu + "Game")]
public class GameServiceAsset : ServiceAsset<GameService> {
public override GameService Create(DIContext context) {
GameService service = context.Create<GameService>();

View File

@@ -1,36 +1,29 @@
using System;
using System.Threading;
using Cysharp.Threading.Tasks;
using RebootKit.Engine.Foundation;
using UnityEngine;
using UnityEngine.InputSystem;
namespace RebootKit.Engine.Services.Input {
public class InputService : IService {
[Serializable]
public class Config {
public InputActionAsset InputAsset;
}
private Config _config;
readonly Config m_Config;
public InputService(Config config) {
_config = config;
m_Config = config;
}
public void Dispose() {
}
public void EnableControls() {
_config.InputAsset.Enable();
m_Config.inputAsset.Enable();
}
public void DisableControls() {
_config.InputAsset.Disable();
m_Config.inputAsset.Disable();
}
public InputAction FindInputAction(string path) {
return _config.InputAsset.FindAction(path);
return m_Config.inputAsset.FindAction(path);
}
public void LockCursor() {
@@ -42,5 +35,10 @@ namespace RebootKit.Engine.Services.Input {
Cursor.lockState = CursorLockMode.None;
Cursor.visible = true;
}
[Serializable]
public class Config {
public InputActionAsset inputAsset;
}
}
}

View File

@@ -2,13 +2,12 @@
using UnityEngine;
namespace RebootKit.Engine.Services.Input {
[CreateAssetMenu(menuName = RConsts.ServiceAssetMenu + "Input")]
[CreateAssetMenu(menuName = RConsts.k_ServiceAssetMenu + "Input")]
public class InputServiceAsset : ServiceAsset<InputService> {
[SerializeField]
private InputService.Config _config;
[SerializeField] InputService.Config m_Config;
public override InputService Create(DIContext context) {
InputService instance = new(_config);
InputService instance = new(m_Config);
context.Inject(instance);
return instance;
}

View File

@@ -1,11 +1,9 @@
using UnityEngine;
using UnityEngine.InputSystem;
namespace RebootKit.Engine.Services.Input
{
[CreateAssetMenu(menuName = RConsts.AssetMenu + "Input Action", fileName = "Input Action")]
public class ScriptableInputAction : ScriptableObject
{
namespace RebootKit.Engine.Services.Input {
[CreateAssetMenu(menuName = RConsts.k_AddComponentMenu + "Input Action", fileName = "Input Action")]
public class ScriptableInputAction : ScriptableObject {
[field: SerializeField]
public InputAction Action { get; private set; }
}

View File

@@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: f5fb2de6697247618aa0dc36a659ddcc
timeCreated: 1741791621

View File

@@ -1,7 +0,0 @@
namespace RebootKit.Engine.Services.LoadigScreen
{
public class LoadingScreenService
{
}
}

View File

@@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: 0a45f8f7ea6f45198713694a39790614
timeCreated: 1740671052

View File

@@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: 663488f6dc6f4f23a2fb88ab0b2a8daa
timeCreated: 1741043532

Some files were not shown because too many files have changed in this diff Show More