Skip to content

Commit e0e32c8

Browse files
Merged and fixed stuff :)
2 parents 7a39f3a + b300c11 commit e0e32c8

21 files changed

+1967
-972
lines changed

MLAPI-Editor/MLAPIEditor.cs

Lines changed: 127 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
using System;
2+
using System.Collections;
23
using System.Collections.Generic;
34
using System.IO;
5+
using System.Text;
46
using UnityEditor;
57
using UnityEngine;
68

@@ -23,6 +25,19 @@ public class GithubAsset
2325
public string name;
2426
}
2527

28+
[Serializable]
29+
public class AppveyorProject
30+
{
31+
public int repositoryBranch;
32+
}
33+
34+
[Serializable]
35+
public class AppveyorBuild
36+
{
37+
38+
}
39+
40+
[InitializeOnLoad]
2641
public class MLAPIEditor : EditorWindow
2742
{
2843
private GithubRelease[] releases = new GithubRelease[0];
@@ -50,60 +65,83 @@ private long lastUpdated
5065
}
5166
}
5267

68+
private bool isFetching = false;
69+
private bool isParsing = false;
70+
private bool canRefetch => !(isFetching || isParsing);
71+
72+
private int tab;
73+
5374
[MenuItem("Window/MLAPI")]
5475
public static void ShowWindow()
5576
{
5677
GetWindow<MLAPIEditor>();
5778
}
5879

80+
Vector2 scrollPos = Vector2.zero;
5981
private void OnGUI()
6082
{
61-
if (foldoutStatus != null)
83+
GUILayout.BeginArea(new Rect(5, 0, position.width - 5, position.height - 60));
84+
scrollPos = GUILayout.BeginScrollView(scrollPos);
85+
tab = GUILayout.Toolbar(tab, new string[] { "GitHub", "Commits" });
86+
if (tab == 0)
6287
{
63-
for (int i = 0; i < foldoutStatus.Length; i++)
88+
if (foldoutStatus != null)
6489
{
65-
if (releases[i] == null)
66-
continue;
67-
foldoutStatus[i] = EditorGUILayout.Foldout(foldoutStatus[i], releases[i].tag_name + " - " + releases[i].name);
68-
if (foldoutStatus[i])
90+
for (int i = 0; i < foldoutStatus.Length; i++)
6991
{
70-
EditorGUI.indentLevel++;
71-
EditorGUILayout.LabelField("Release notes", EditorStyles.boldLabel);
72-
EditorGUILayout.LabelField(releases[i].body, EditorStyles.wordWrappedLabel);
73-
EditorGUILayout.Space();
74-
EditorGUILayout.Space();
75-
if (releases[i].prerelease)
76-
{
77-
GUIStyle style = new GUIStyle(EditorStyles.boldLabel);
78-
style.normal.textColor = new Color(1f, 0.5f, 0f);
79-
EditorGUILayout.LabelField("Pre-release", style);
80-
}
81-
else
82-
{
83-
GUIStyle style = new GUIStyle(EditorStyles.boldLabel);
84-
style.normal.textColor = new Color(0f, 1f, 0f);
85-
EditorGUILayout.LabelField("Stable-release", style);
86-
}
87-
if (currentVersion == releases[i].tag_name)
92+
if (releases[i] == null)
93+
continue;
94+
foldoutStatus[i] = EditorGUILayout.Foldout(foldoutStatus[i], releases[i].tag_name + " - " + releases[i].name);
95+
if (foldoutStatus[i])
8896
{
89-
GUIStyle boldStyle = new GUIStyle(EditorStyles.boldLabel);
90-
boldStyle.normal.textColor = new Color(0.3f, 1f, 0.3f);
91-
EditorGUILayout.LabelField("Installed", boldStyle);
92-
}
93-
EditorGUILayout.LabelField("Release date: " + DateTime.Parse(DateTime.Parse(releases[i].published_at).ToString()), EditorStyles.miniBoldLabel);
97+
EditorGUI.indentLevel++;
98+
EditorGUILayout.LabelField("Release notes", EditorStyles.boldLabel);
99+
EditorGUILayout.LabelField(releases[i].body, EditorStyles.wordWrappedLabel);
100+
EditorGUILayout.Space();
101+
EditorGUILayout.Space();
102+
if (releases[i].prerelease)
103+
{
104+
GUIStyle style = new GUIStyle(EditorStyles.boldLabel);
105+
style.normal.textColor = new Color(1f, 0.5f, 0f);
106+
EditorGUILayout.LabelField("Pre-release", style);
107+
}
108+
else
109+
{
110+
GUIStyle style = new GUIStyle(EditorStyles.boldLabel);
111+
style.normal.textColor = new Color(0f, 1f, 0f);
112+
EditorGUILayout.LabelField("Stable-release", style);
113+
}
114+
if (currentVersion == releases[i].tag_name)
115+
{
116+
GUIStyle boldStyle = new GUIStyle(EditorStyles.boldLabel);
117+
boldStyle.normal.textColor = new Color(0.3f, 1f, 0.3f);
118+
EditorGUILayout.LabelField("Installed", boldStyle);
119+
}
120+
EditorGUILayout.LabelField("Release date: " + DateTime.Parse(DateTime.Parse(releases[i].published_at).ToString()), EditorStyles.miniBoldLabel);
94121

95-
if (currentVersion != releases[i].tag_name && GUILayout.Button("Install"))
96-
InstallRelease(i);
122+
if (currentVersion != releases[i].tag_name && GUILayout.Button("Install"))
123+
InstallRelease(i);
97124

98-
EditorGUI.indentLevel--;
125+
EditorGUI.indentLevel--;
126+
}
99127
}
100128
}
101129
}
130+
else if (tab == 1)
131+
{
132+
EditorGUILayout.LabelField("Not yet implemented. The rest API for AppVeyor is proper garbage and is needed to grab the artifact download URLs", EditorStyles.wordWrappedLabel);
133+
}
134+
GUILayout.EndScrollView();
135+
GUILayout.EndArea();
136+
137+
GUILayout.BeginArea(new Rect(5, position.height - 60, position.width - 5, 60));
102138

103-
GUILayout.BeginArea(new Rect(5, position.height - 40, position.width, 40));
139+
string lastUpdatedString = lastUpdated == 0 ? "Never" : new DateTime(lastUpdated).ToShortTimeString();
140+
GUILayout.Label("Last checked: " + lastUpdatedString, EditorStyles.centeredGreyMiniLabel);
104141

105-
if (GUILayout.Button("Fetch releases"))
106-
GetReleases();
142+
string fetchButton = isFetching ? "Fetching..." : isParsing ? "Parsing..." : "Fetch releases";
143+
if (GUILayout.Button(fetchButton) && canRefetch)
144+
EditorCoroutine.Start(GetReleases());
107145
if (GUILayout.Button("Reset defaults"))
108146
{
109147
releases = new GithubRelease[0];
@@ -114,11 +152,8 @@ private void OnGUI()
114152

115153
GUILayout.EndArea();
116154

117-
string lastUpdatedString = lastUpdated == 0 ? "Never" : new DateTime(lastUpdated).ToShortTimeString();
118-
EditorGUI.LabelField(new Rect(5, position.height - 60, position.width, 20), "Last checked: " + lastUpdatedString, EditorStyles.centeredGreyMiniLabel);
119-
120155
if ((releases.Length == 0 && (DateTime.Now - new DateTime(lastUpdated)).TotalSeconds > 600) || (DateTime.Now - new DateTime(lastUpdated)).TotalSeconds > 3600)
121-
GetReleases();
156+
EditorCoroutine.Start(GetReleases());
122157

123158
Repaint();
124159
}
@@ -146,22 +181,26 @@ private void InstallRelease(int index)
146181
AssetDatabase.Refresh();
147182
}
148183

149-
private void GetReleases()
184+
185+
IEnumerator GetReleases()
150186
{
151187
lastUpdated = DateTime.Now.Ticks;
152188

153189
WWW www = new WWW("https://api.github.com/repos/TwoTenPvP/MLAPI/releases");
190+
isFetching = true;
154191
while (!www.isDone && string.IsNullOrEmpty(www.error))
155192
{
156-
EditorGUI.ProgressBar(new Rect(5, position.height - 60, position.width, 20), www.progress, "Fetching...");
193+
yield return null;
157194
}
195+
isFetching = false;
196+
isParsing = true;
158197
string json = www.text;
159198

160199
//This makes it from a json array to the individual objects in the array.
161200
//The JSON serializer cant take arrays. We have to split it up outselves.
162201
List<string> releasesJson = new List<string>();
163202
int depth = 0;
164-
string currentObject = "";
203+
StringBuilder builder = new StringBuilder();
165204
for (int i = 1; i < json.Length - 1; i++)
166205
{
167206
if (json[i] == '[')
@@ -174,12 +213,18 @@ private void GetReleases()
174213
depth--;
175214

176215
if ((depth == 0 && json[i] != ',') || depth > 0)
177-
currentObject += json[i];
216+
builder.Append(json[i]);
178217

179218
if (depth == 0 && json[i] == ',')
180219
{
181-
releasesJson.Add(currentObject);
182-
currentObject = "";
220+
releasesJson.Add(builder.ToString());
221+
builder.Length = 0;
222+
}
223+
224+
//Parse in smaller batches
225+
if (i % (json.Length / 30) == 0)
226+
{
227+
yield return null;
183228
}
184229
}
185230

@@ -193,6 +238,43 @@ private void GetReleases()
193238
foldoutStatus[i] = true;
194239
else
195240
foldoutStatus[i] = false;
241+
242+
if (i % (releasesJson.Count / 30f) == 0)
243+
{
244+
yield return null;
245+
}
246+
}
247+
isParsing = false;
248+
}
249+
250+
public class EditorCoroutine
251+
{
252+
public static EditorCoroutine Start(IEnumerator routine)
253+
{
254+
EditorCoroutine coroutine = new EditorCoroutine(routine);
255+
coroutine.Start();
256+
return coroutine;
257+
}
258+
259+
private readonly IEnumerator coroutine;
260+
EditorCoroutine(IEnumerator routine)
261+
{
262+
coroutine = routine;
263+
}
264+
265+
private void Start()
266+
{
267+
EditorApplication.update += Update;
268+
}
269+
270+
private void Stop()
271+
{
272+
EditorApplication.update -= Update;
273+
}
274+
275+
void Update()
276+
{
277+
if (!coroutine.MoveNext()) Stop();
196278
}
197279
}
198280
}

MLAPI-Editor/NetworkedBehaviourEditor.cs

Lines changed: 91 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using MLAPI.Attributes;
2+
using MLAPI.Data;
23
using MLAPI.MonoBehaviours.Core;
34
using System;
45
using System.Collections.Generic;
@@ -9,26 +10,110 @@ namespace UnityEditor
910
{
1011
[CustomEditor(typeof(NetworkedBehaviour), true)]
1112
[CanEditMultipleObjects]
12-
public class NetworkedBehaviourInspector : Editor
13+
public class NetworkedBehaviourEditor : Editor
1314
{
1415
private bool initialized;
15-
protected List<string> syncedVarNames = new List<string>();
16+
private HashSet<string> syncedVarNames = new HashSet<string>();
17+
private List<string> networkedVarNames = new List<string>();
18+
private Dictionary<string, FieldInfo> networkedVarFields = new Dictionary<string, FieldInfo>();
19+
private Dictionary<string, object> networkedVarObjects = new Dictionary<string, object>();
1620

1721
private GUIContent syncedVarLabelGuiContent;
22+
private GUIContent networkedVarLabelGuiContent;
1823

1924
private void Init(MonoScript script)
2025
{
2126
initialized = true;
2227

28+
syncedVarNames.Clear();
29+
networkedVarNames.Clear();
30+
networkedVarFields.Clear();
31+
networkedVarObjects.Clear();
32+
2333
syncedVarLabelGuiContent = new GUIContent("SyncedVar", "This variable has been marked with the [SyncedVar] attribute.");
34+
networkedVarLabelGuiContent = new GUIContent("NetworkedVar", "This variable is a NetworkedVar. It can not be serialized and can only be changed during runtime.");
2435

2536
FieldInfo[] fields = script.GetClass().GetFields(BindingFlags.Public | BindingFlags.Instance | BindingFlags.FlattenHierarchy | BindingFlags.NonPublic);
2637
for (int i = 0; i < fields.Length; i++)
2738
{
2839
Attribute[] attributes = (Attribute[])fields[i].GetCustomAttributes(typeof(SyncedVar), true);
2940
if (attributes.Length > 0)
3041
syncedVarNames.Add(fields[i].Name);
42+
43+
Type ft = fields[i].FieldType;
44+
if (ft.IsGenericType && ft.GetGenericTypeDefinition() == typeof(NetworkedVar<>))
45+
{
46+
networkedVarNames.Add(fields[i].Name);
47+
networkedVarFields.Add(fields[i].Name, fields[i]);
48+
}
49+
}
50+
}
51+
52+
void RenderNetworkedVar(int index)
53+
{
54+
if (!networkedVarFields.ContainsKey(networkedVarNames[index]))
55+
{
56+
serializedObject.Update();
57+
SerializedProperty scriptProperty = serializedObject.FindProperty("m_Script");
58+
if (scriptProperty == null)
59+
return;
60+
61+
MonoScript targetScript = scriptProperty.objectReferenceValue as MonoScript;
62+
Init(targetScript);
63+
}
64+
Type type = networkedVarFields[networkedVarNames[index]].GetValue(target).GetType();
65+
Type genericType = type.GetGenericArguments()[0];
66+
67+
EditorGUILayout.BeginHorizontal();
68+
if (genericType == typeof(string))
69+
{
70+
NetworkedVar<string> var = (NetworkedVar<string>)networkedVarFields[networkedVarNames[index]].GetValue(target);
71+
var.Value = EditorGUILayout.TextField(networkedVarNames[index], var.Value);
72+
}
73+
else if (genericType.IsValueType)
74+
{
75+
MethodInfo method = typeof(NetworkedBehaviourEditor).GetMethod("RenderNetworkedVarValueType", BindingFlags.Public | BindingFlags.Instance | BindingFlags.FlattenHierarchy | BindingFlags.NonPublic);
76+
MethodInfo genericMethod = method.MakeGenericMethod(genericType);
77+
genericMethod.Invoke(this, new object[] { (object)index });
3178
}
79+
else
80+
{
81+
EditorGUILayout.LabelField("Type not renderable");
82+
}
83+
GUILayout.Label(networkedVarLabelGuiContent, EditorStyles.miniLabel, GUILayout.Width(EditorStyles.miniLabel.CalcSize(networkedVarLabelGuiContent).x));
84+
EditorGUILayout.EndHorizontal();
85+
}
86+
87+
void RenderNetworkedVarValueType<T>(int index) where T : struct
88+
{
89+
NetworkedVar<T> var = (NetworkedVar<T>)networkedVarFields[networkedVarNames[index]].GetValue(target);
90+
Type type = typeof(T);
91+
object val = var.Value;
92+
string name = networkedVarNames[index];
93+
if (type == typeof(int))
94+
val = EditorGUILayout.IntField(name, (int)val);
95+
else if (type == typeof(uint))
96+
val = EditorGUILayout.LongField(name, (long)val);
97+
else if (type == typeof(short))
98+
val = EditorGUILayout.IntField(name, (int)val);
99+
else if (type == typeof(ushort))
100+
val = EditorGUILayout.IntField(name, (int)val);
101+
else if (type == typeof(sbyte))
102+
val = EditorGUILayout.IntField(name, (int)val);
103+
else if (type == typeof(byte))
104+
val = EditorGUILayout.IntField(name, (int)val);
105+
else if (type == typeof(long))
106+
val = EditorGUILayout.LongField(name, (long)val);
107+
else if (type == typeof(ulong))
108+
val = EditorGUILayout.LongField(name, (long)val);
109+
else if (type == typeof(bool))
110+
val = EditorGUILayout.Toggle(name, (bool)val);
111+
else if (type == typeof(string))
112+
val = EditorGUILayout.TextField(name, (string)val);
113+
else
114+
EditorGUILayout.LabelField("Type not renderable");
115+
116+
var.Value = (T)val;
32117
}
33118

34119
public override void OnInspectorGUI()
@@ -47,6 +132,9 @@ public override void OnInspectorGUI()
47132
EditorGUI.BeginChangeCheck();
48133
serializedObject.Update();
49134

135+
for (int i = 0; i < networkedVarNames.Count; i++)
136+
RenderNetworkedVar(i);
137+
50138
SerializedProperty property = serializedObject.GetIterator();
51139
bool expanded = true;
52140
while (property.NextVisible(expanded))
@@ -78,7 +166,7 @@ public override void OnInspectorGUI()
78166
expanded = false;
79167
}
80168
serializedObject.ApplyModifiedProperties();
81-
EditorGUI.EndChangeCheck();
169+
EditorGUI.EndChangeCheck();
82170
}
83171
}
84172
}

0 commit comments

Comments
 (0)