Compare commits
7 Commits
cb3e3e5f28
...
a8ab73ac65
Author | SHA1 | Date | |
---|---|---|---|
a8ab73ac65 | |||
35ac57bfba | |||
945f9ca7d1 | |||
d2b2834a60 | |||
f82e0ce9ef | |||
5444ea7186 | |||
3a54d2023f |
Binary file not shown.
@@ -168,5 +168,19 @@ namespace Cryville.Common {
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the namespace qualified name of a type.
|
||||
/// </summary>
|
||||
/// <param name="type">The type.</param>
|
||||
/// <returns>The namespace qualified name of the class.</returns>
|
||||
public static string GetNamespaceQualifiedName(Type type) {
|
||||
string result = type.Namespace + "." + type.Name;
|
||||
var typeargs = type.GetGenericArguments();
|
||||
if (typeargs.Length > 0) {
|
||||
result = string.Format("{0}[{1}]", result, string.Join(",", from a in typeargs select GetNamespaceQualifiedName(a)));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -9,14 +9,6 @@ namespace Cryville.Common.Unity {
|
||||
return (num2 & num) == num;
|
||||
}
|
||||
|
||||
public static void ShowException(Exception ex) {
|
||||
ShowMessageBox(ex.ToString());
|
||||
}
|
||||
|
||||
public static void ShowMessageBox(string message) {
|
||||
GameObject.Instantiate<GameObject>(Resources.Load<GameObject>("Common/Popup")).GetComponent<Popup>().Message = message;
|
||||
}
|
||||
|
||||
public static void Purge(Transform obj) {
|
||||
foreach (Transform i in obj)
|
||||
GameObject.Destroy(i.gameObject);
|
||||
|
@@ -13,6 +13,7 @@ namespace Cryville.Common.Unity.Input {
|
||||
};
|
||||
// TODO set private
|
||||
public readonly List<InputHandler> _handlers = new List<InputHandler>();
|
||||
readonly Dictionary<Type, InputHandler> _typemap = new Dictionary<Type, InputHandler>();
|
||||
readonly Dictionary<InputHandler, double> _timeOrigins = new Dictionary<InputHandler, double>();
|
||||
readonly object _lock = new object();
|
||||
readonly Dictionary<InputIdentifier, InputVector> _vectors = new Dictionary<InputIdentifier, InputVector>();
|
||||
@@ -22,6 +23,7 @@ namespace Cryville.Common.Unity.Input {
|
||||
try {
|
||||
if (!typeof(InputHandler).IsAssignableFrom(t)) continue;
|
||||
var h = (InputHandler)ReflectionHelper.InvokeEmptyConstructor(t);
|
||||
_typemap.Add(t, h);
|
||||
h.OnInput += OnInput;
|
||||
_handlers.Add(h);
|
||||
_timeOrigins.Add(h, 0);
|
||||
@@ -32,6 +34,9 @@ namespace Cryville.Common.Unity.Input {
|
||||
}
|
||||
}
|
||||
}
|
||||
public InputHandler GetHandler(string name) {
|
||||
return _typemap[Type.GetType(name)];
|
||||
}
|
||||
public void Activate() {
|
||||
lock (_lock) {
|
||||
_events.Clear();
|
||||
|
@@ -1,34 +0,0 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace Cryville.Common.Unity {
|
||||
public class Popup : MonoBehaviour {
|
||||
|
||||
public string Message = "";
|
||||
|
||||
LayoutElement layout;
|
||||
|
||||
float timer = 0;
|
||||
|
||||
const float DURATION = 5.0f;
|
||||
const float DURIN = 0.4f;
|
||||
const float DUROUT = 0.4f;
|
||||
const float HEIGHT = 50f;
|
||||
|
||||
#pragma warning disable IDE0051
|
||||
void Start() {
|
||||
layout = GetComponent<LayoutElement>();
|
||||
GetComponentInChildren<Text>().text = Message;
|
||||
transform.SetParent(GameObject.Find("PopupList").transform);
|
||||
layout.minHeight = 0;
|
||||
}
|
||||
|
||||
void Update() {
|
||||
if (timer <= DURIN) layout.minHeight = timer / DURIN * HEIGHT;
|
||||
else if (timer >= DURATION) GameObject.Destroy(gameObject);
|
||||
else if (timer >= DURATION - DUROUT) layout.minHeight = (DURATION - timer) / DUROUT * HEIGHT;
|
||||
timer += Time.deltaTime;
|
||||
}
|
||||
#pragma warning restore IDE0051
|
||||
}
|
||||
}
|
@@ -133,10 +133,10 @@ namespace Cryville.Common.Unity {
|
||||
prop.SetValue(Target, v, new object[]{ });
|
||||
}
|
||||
catch (TargetInvocationException ex) {
|
||||
CallHelper.ShowMessageBox(ex.InnerException.Message);
|
||||
// CallHelper.ShowMessageBox(ex.InnerException.Message);
|
||||
}
|
||||
catch (Exception ex) {
|
||||
CallHelper.ShowMessageBox(ex.Message);
|
||||
// CallHelper.ShowMessageBox(ex.Message);
|
||||
}
|
||||
}
|
||||
UpdateValue();
|
||||
|
@@ -121,7 +121,7 @@ namespace Cryville.Crtr.Browsing {
|
||||
resources = converter.ConvertFrom(file);
|
||||
}
|
||||
catch (Exception ex) {
|
||||
CallHelper.ShowMessageBox(ex.Message);
|
||||
Popup.Create(ex.Message);
|
||||
return false;
|
||||
}
|
||||
foreach (var res in resources) {
|
||||
|
@@ -59,11 +59,11 @@ namespace Cryville.Crtr.Browsing {
|
||||
private void OnAddDialogClosed() {
|
||||
if (_dialog.FileName == null) return;
|
||||
if (ResourceManager.ImportItemFrom(_dialog.FileName)) {
|
||||
CallHelper.ShowMessageBox("Import succeeded");
|
||||
Popup.Create("Import succeeded");
|
||||
OnPathClicked(ResourceManager.CurrentDirectory.Length - 1);
|
||||
}
|
||||
else {
|
||||
CallHelper.ShowMessageBox("Import failed");
|
||||
Popup.Create("Import failed");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -86,6 +86,7 @@ namespace Cryville.Crtr.Browsing {
|
||||
|
||||
void SetDataSettings(int id, ChartDetail detail) {
|
||||
Settings.Default.LoadRuleset = detail.Meta.ruleset + "/.umgr";
|
||||
Settings.Default.LoadRulesetConfig = detail.Meta.ruleset + ".json";
|
||||
Settings.Default.LoadSkin = detail.Meta.ruleset + "/Old KeyUI/.umgs";
|
||||
Settings.Default.LoadChart = MainBrowser.ResourceManager.GetItemPath(id);
|
||||
}
|
||||
|
@@ -2,7 +2,7 @@
|
||||
|
||||
using Cryville.Common;
|
||||
using Cryville.Common.Plist;
|
||||
using Cryville.Common.Unity.Input;
|
||||
using Cryville.Crtr.Config;
|
||||
using Cryville.Crtr.Event;
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
@@ -68,15 +68,6 @@ namespace Cryville.Crtr {
|
||||
|
||||
InputProxy inputProxy;
|
||||
|
||||
~ChartPlayer() {
|
||||
Dispose();
|
||||
}
|
||||
|
||||
public void Dispose() {
|
||||
if (loadThread != null) loadThread.Abort();
|
||||
if (texLoader != null) texLoader.Dispose();
|
||||
}
|
||||
|
||||
#region MonoBehaviour
|
||||
void Start() {
|
||||
var logobj = GameObject.Find("Logs");
|
||||
@@ -99,6 +90,19 @@ namespace Cryville.Crtr {
|
||||
// Camera.main.RenderToCubemap();
|
||||
}
|
||||
|
||||
void OnDestroy() {
|
||||
if (cbus != null) cbus.Dispose();
|
||||
if (bbus != null) bbus.Dispose();
|
||||
if (tbus != null) tbus.Dispose();
|
||||
if (nbus != null) nbus.Dispose();
|
||||
if (loadThread != null) loadThread.Abort();
|
||||
if (texLoader != null) texLoader.Dispose();
|
||||
if (inputProxy != null) inputProxy.Dispose();
|
||||
if (texs != null) foreach (var t in texs) Texture.Destroy(t.Value);
|
||||
Camera.onPostRender -= OnCameraPostRender;
|
||||
GC.Collect();
|
||||
}
|
||||
|
||||
bool texloaddone;
|
||||
diag::Stopwatch texloadtimer = new diag::Stopwatch();
|
||||
bool firstFrame;
|
||||
@@ -142,6 +146,7 @@ namespace Cryville.Crtr {
|
||||
}
|
||||
catch (Exception ex) {
|
||||
Game.LogException("Game", "An error occured while playing", ex);
|
||||
Popup.CreateException(ex);
|
||||
Stop();
|
||||
}
|
||||
}
|
||||
@@ -190,9 +195,10 @@ namespace Cryville.Crtr {
|
||||
Logger.Log("main", 1, "Load/MainThread", "Main thread done ({0}ms)", texloadtimer.Elapsed.TotalMilliseconds);
|
||||
}
|
||||
if (!loadThread.IsAlive) {
|
||||
if (cbus == null) {
|
||||
if (threadException != null) {
|
||||
Logger.Log("main", 4, "Load/MainThread", "Load failed");
|
||||
loadThread = null;
|
||||
Popup.CreateException(threadException);
|
||||
#if BUILD
|
||||
ReturnToMenu();
|
||||
#endif
|
||||
@@ -328,6 +334,9 @@ namespace Cryville.Crtr {
|
||||
FileInfo rulesetFile = new FileInfo(
|
||||
Game.GameDataPath + "/rulesets/" + Settings.Default.LoadRuleset
|
||||
);
|
||||
FileInfo rulesetConfigFile = new FileInfo(
|
||||
Game.GameDataPath + "/config/rulesets/" + Settings.Default.LoadRulesetConfig
|
||||
);
|
||||
FileInfo skinFile = new FileInfo(
|
||||
Game.GameDataPath + "/skins/" + Settings.Default.LoadSkin
|
||||
);
|
||||
@@ -335,6 +344,7 @@ namespace Cryville.Crtr {
|
||||
loadThread.Start(new LoadInfo() {
|
||||
chartFile = chartFile,
|
||||
rulesetFile = rulesetFile,
|
||||
rulesetConfigFile = rulesetConfigFile,
|
||||
skinFile = skinFile,
|
||||
});
|
||||
|
||||
@@ -365,23 +375,7 @@ namespace Cryville.Crtr {
|
||||
}
|
||||
Logger.Log("main", 0, "Load/Prehandle", "Initializing states");
|
||||
cbus.BroadcastInit();
|
||||
|
||||
inputProxy = new InputProxy(pruleset, judge);
|
||||
foreach (var i in Game.InputManager._handlers) {
|
||||
/*if (i is UnityKeyHandler<UnityKeyboardReceiver>) {
|
||||
inputProxy.Set(new InputProxyEntry { Source = new InputSource { Handler = i, Type = (int)KeyCode.Z }, Target = "track0" });
|
||||
inputProxy.Set(new InputProxyEntry { Source = new InputSource { Handler = i, Type = (int)KeyCode.X }, Target = "track1" });
|
||||
inputProxy.Set(new InputProxyEntry { Source = new InputSource { Handler = i, Type = (int)KeyCode.Comma }, Target = "track2" });
|
||||
inputProxy.Set(new InputProxyEntry { Source = new InputSource { Handler = i, Type = (int)KeyCode.Period }, Target = "track3" });
|
||||
break;
|
||||
}*/
|
||||
if (i is UnityMouseHandler) {
|
||||
inputProxy.Set(new InputProxyEntry { Source = new InputSource { Handler = i, Type = 0 }, Target = "screen_x" });
|
||||
break;
|
||||
}
|
||||
}
|
||||
inputProxy.Activate();
|
||||
|
||||
if (logEnabled) ToggleLogs();
|
||||
Logger.Log("main", 0, "Load/Prehandle", "Cleaning up");
|
||||
GC.Collect();
|
||||
@@ -396,6 +390,7 @@ namespace Cryville.Crtr {
|
||||
}
|
||||
catch (Exception ex) {
|
||||
Game.LogException("Load/Prehandle", "An error occured while prehandling the data", ex);
|
||||
Popup.CreateException(ex);
|
||||
Stop();
|
||||
}
|
||||
}
|
||||
@@ -403,20 +398,17 @@ namespace Cryville.Crtr {
|
||||
public void Stop() {
|
||||
try {
|
||||
Logger.Log("main", 1, "Game", "Stopping");
|
||||
chart = null;
|
||||
Game.AudioSession = Game.AudioSequencer.NewSession();
|
||||
if (cbus != null) cbus.Dispose();
|
||||
if (bbus != null) bbus.Dispose();
|
||||
if (tbus != null) tbus.Dispose();
|
||||
if (nbus != null) nbus.Dispose();
|
||||
inputProxy.Deactivate();
|
||||
foreach (var t in texs) Texture.Destroy(t.Value);
|
||||
Camera.onPostRender -= OnCameraPostRender;
|
||||
if (cbus != null) { cbus.Dispose(); cbus = null; }
|
||||
if (bbus != null) { bbus.Dispose(); bbus = null; }
|
||||
if (tbus != null) { tbus.Dispose(); tbus = null; }
|
||||
if (nbus != null) { nbus.Dispose(); nbus = null; }
|
||||
Logger.Log("main", 1, "Game", "Stopped");
|
||||
}
|
||||
catch (Exception ex) {
|
||||
if (!logEnabled) ToggleLogs();
|
||||
Game.LogException("Game", "An error occured while stopping", ex);
|
||||
Popup.CreateException(ex);
|
||||
}
|
||||
finally {
|
||||
if (started) {
|
||||
@@ -441,9 +433,11 @@ namespace Cryville.Crtr {
|
||||
struct LoadInfo {
|
||||
public FileInfo chartFile;
|
||||
public FileInfo rulesetFile;
|
||||
public FileInfo rulesetConfigFile;
|
||||
public FileInfo skinFile;
|
||||
}
|
||||
|
||||
Exception threadException;
|
||||
#if !NO_THREAD
|
||||
Thread loadThread = null;
|
||||
diag::Stopwatch workerTimer;
|
||||
@@ -460,6 +454,7 @@ namespace Cryville.Crtr {
|
||||
}
|
||||
catch (Exception ex) {
|
||||
Game.LogException("Load/WorkerThread", "An error occured while loading the data", ex);
|
||||
threadException = ex;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -476,7 +471,7 @@ namespace Cryville.Crtr {
|
||||
|
||||
etor = new PdtEvaluator();
|
||||
|
||||
LoadRuleset(info.rulesetFile);
|
||||
LoadRuleset(info.rulesetFile, info.rulesetConfigFile);
|
||||
Logger.Log("main", 0, "Load/WorkerThread", "Applying ruleset (iteration 1)");
|
||||
pruleset.PrePatch(chart);
|
||||
|
||||
@@ -491,6 +486,12 @@ namespace Cryville.Crtr {
|
||||
judge = new Judge(pruleset);
|
||||
etor.ContextJudge = judge;
|
||||
|
||||
inputProxy = new InputProxy(pruleset, judge);
|
||||
inputProxy.LoadFrom(_rscfg.inputs);
|
||||
if (!inputProxy.IsCompleted) {
|
||||
throw new ArgumentException("Input config not completed\nPlease complete the input settings");
|
||||
}
|
||||
|
||||
cbus.AttachSystems(pskin, judge);
|
||||
Logger.Log("main", 0, "Load/WorkerThread", "Attaching handlers");
|
||||
var ch = new ChartHandler(chart, dir);
|
||||
@@ -510,11 +511,15 @@ namespace Cryville.Crtr {
|
||||
}
|
||||
}
|
||||
Logger.Log("main", 0, "Load/WorkerThread", "Prehandling (iteration 1)");
|
||||
cbus.Clone(16).Forward();
|
||||
using (var pbus = cbus.Clone(16)) {
|
||||
pbus.Forward();
|
||||
}
|
||||
Logger.Log("main", 0, "Load/WorkerThread", "Patching events");
|
||||
cbus.DoPatch();
|
||||
Logger.Log("main", 0, "Load/WorkerThread", "Prehandling (iteration 2)");
|
||||
cbus.Clone(17).Forward();
|
||||
using (var pbus = cbus.Clone(17)) {
|
||||
pbus.Forward();
|
||||
}
|
||||
|
||||
Logger.Log("main", 0, "Load/WorkerThread", "Cloning states (type 1)");
|
||||
bbus = cbus.Clone(1, -clippingDist);
|
||||
@@ -525,7 +530,8 @@ namespace Cryville.Crtr {
|
||||
}
|
||||
}
|
||||
|
||||
void LoadRuleset(FileInfo file) {
|
||||
RulesetConfig _rscfg;
|
||||
void LoadRuleset(FileInfo file, FileInfo cfgfile) {
|
||||
DirectoryInfo dir = file.Directory;
|
||||
Logger.Log("main", 0, "Load/WorkerThread", "Loading ruleset: {0}", file);
|
||||
using (StreamReader reader = new StreamReader(file.FullName, Encoding.UTF8)) {
|
||||
@@ -535,6 +541,12 @@ namespace Cryville.Crtr {
|
||||
if (ruleset.format != 1) throw new FormatException("Invalid ruleset file version");
|
||||
ruleset.LoadPdt(dir);
|
||||
pruleset = ruleset.Root;
|
||||
if (!cfgfile.Exists) throw new FileNotFoundException("Ruleset config not found\nPlease open the config to generate");
|
||||
using (StreamReader cfgreader = new StreamReader(cfgfile.FullName, Encoding.UTF8)) {
|
||||
_rscfg = JsonConvert.DeserializeObject<RulesetConfig>(cfgreader.ReadToEnd(), new JsonSerializerSettings() {
|
||||
MissingMemberHandling = MissingMemberHandling.Error
|
||||
});
|
||||
}
|
||||
pruleset.Optimize(etor);
|
||||
}
|
||||
}
|
||||
|
@@ -1,4 +1,8 @@
|
||||
using UnityEngine;
|
||||
using Newtonsoft.Json;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using UnityEngine.SceneManagement;
|
||||
|
||||
namespace Cryville.Crtr.Config {
|
||||
@@ -6,6 +10,45 @@ namespace Cryville.Crtr.Config {
|
||||
[SerializeField]
|
||||
Transform m_content;
|
||||
|
||||
[SerializeField]
|
||||
InputConfigPanel m_inputConfigPanel;
|
||||
|
||||
public Ruleset ruleset;
|
||||
RulesetConfig _rscfg;
|
||||
|
||||
void Awake() {
|
||||
ChartPlayer.etor = new PdtEvaluator();
|
||||
FileInfo file = new FileInfo(
|
||||
Game.GameDataPath + "/rulesets/" + Settings.Default.LoadRuleset
|
||||
);
|
||||
DirectoryInfo dir = file.Directory;
|
||||
using (StreamReader reader = new StreamReader(file.FullName, Encoding.UTF8)) {
|
||||
ruleset = JsonConvert.DeserializeObject<Ruleset>(reader.ReadToEnd(), new JsonSerializerSettings() {
|
||||
MissingMemberHandling = MissingMemberHandling.Error
|
||||
});
|
||||
if (ruleset.format != 1) throw new FormatException("Invalid ruleset file version");
|
||||
ruleset.LoadPdt(dir);
|
||||
}
|
||||
FileInfo cfgfile = new FileInfo(
|
||||
Game.GameDataPath + "/config/rulesets/" + Settings.Default.LoadRulesetConfig
|
||||
);
|
||||
if (!cfgfile.Exists) {
|
||||
if (!cfgfile.Directory.Exists) cfgfile.Directory.Create();
|
||||
_rscfg = new RulesetConfig();
|
||||
}
|
||||
else {
|
||||
using (StreamReader cfgreader = new StreamReader(cfgfile.FullName, Encoding.UTF8)) {
|
||||
_rscfg = JsonConvert.DeserializeObject<RulesetConfig>(cfgreader.ReadToEnd(), new JsonSerializerSettings() {
|
||||
MissingMemberHandling = MissingMemberHandling.Error
|
||||
});
|
||||
}
|
||||
}
|
||||
var proxy = new InputProxy(ruleset.Root, null);
|
||||
proxy.LoadFrom(_rscfg.inputs);
|
||||
m_inputConfigPanel.proxy = proxy;
|
||||
Game.InputManager.Activate();
|
||||
}
|
||||
|
||||
public void SwitchCategory(GameObject cat) {
|
||||
foreach (Transform c in m_content) {
|
||||
c.gameObject.SetActive(false);
|
||||
@@ -14,6 +57,15 @@ namespace Cryville.Crtr.Config {
|
||||
}
|
||||
|
||||
public void ReturnToMenu() {
|
||||
Game.InputManager.Deactivate();
|
||||
m_inputConfigPanel.proxy.SaveTo(_rscfg.inputs);
|
||||
m_inputConfigPanel.proxy.Dispose();
|
||||
FileInfo cfgfile = new FileInfo(
|
||||
Game.GameDataPath + "/config/rulesets/" + Settings.Default.LoadRulesetConfig
|
||||
);
|
||||
using (StreamWriter cfgwriter = new StreamWriter(cfgfile.FullName, false, Encoding.UTF8)) {
|
||||
cfgwriter.Write(JsonConvert.SerializeObject(_rscfg, Game.GlobalJsonSerializerSettings));
|
||||
}
|
||||
GameObject.Find("Master").GetComponent<Master>().ShowMenu();
|
||||
#if UNITY_5_5_OR_NEWER
|
||||
SceneManager.UnloadSceneAsync("Config");
|
||||
|
@@ -1,15 +1,14 @@
|
||||
using Cryville.Common.Unity;
|
||||
using Cryville.Common.Unity.Input;
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace Cryville.Crtr.Config {
|
||||
public class InputConfig : MonoBehaviour {
|
||||
public class InputConfigPanel : MonoBehaviour {
|
||||
[SerializeField]
|
||||
ConfigScene m_configScene;
|
||||
|
||||
[SerializeField]
|
||||
GameObject m_inputDialog;
|
||||
|
||||
@@ -25,14 +24,13 @@ namespace Cryville.Crtr.Config {
|
||||
[SerializeField]
|
||||
GameObject m_prefabInputConfigEntry;
|
||||
|
||||
InputProxy _proxy;
|
||||
Dictionary<string, InputConfigEntry> _entries = new Dictionary<string, InputConfigEntry>();
|
||||
public InputProxy proxy;
|
||||
Dictionary<string, InputConfigPanelEntry> _entries = new Dictionary<string, InputConfigPanelEntry>();
|
||||
|
||||
string _sel;
|
||||
public void OpenDialog(string entry) {
|
||||
_sel = entry;
|
||||
m_inputDialog.SetActive(true);
|
||||
Game.InputManager.Activate();
|
||||
CallHelper.Purge(m_deviceList);
|
||||
_recvsrcs.Clear();
|
||||
AddSourceItem(null);
|
||||
@@ -40,38 +38,24 @@ namespace Cryville.Crtr.Config {
|
||||
|
||||
public void CloseDialog() {
|
||||
m_inputDialog.SetActive(false);
|
||||
Game.InputManager.Deactivate();
|
||||
}
|
||||
|
||||
public void CloseDialog(InputSource? src) {
|
||||
_proxy.Set(new InputProxyEntry {
|
||||
proxy.Set(new InputProxyEntry {
|
||||
Target = _sel,
|
||||
Source = src,
|
||||
});
|
||||
m_inputDialog.SetActive(false);
|
||||
Game.InputManager.Deactivate();
|
||||
}
|
||||
|
||||
void Start() {
|
||||
ChartPlayer.etor = new PdtEvaluator();
|
||||
FileInfo file = new FileInfo(
|
||||
Game.GameDataPath + "/rulesets/" + Settings.Default.LoadRuleset
|
||||
);
|
||||
DirectoryInfo dir = file.Directory;
|
||||
using (StreamReader reader = new StreamReader(file.FullName, Encoding.UTF8)) {
|
||||
var ruleset = JsonConvert.DeserializeObject<Ruleset>(reader.ReadToEnd(), new JsonSerializerSettings() {
|
||||
MissingMemberHandling = MissingMemberHandling.Error
|
||||
});
|
||||
if (ruleset.format != 1) throw new FormatException("Invalid ruleset file version");
|
||||
ruleset.LoadPdt(dir);
|
||||
_proxy = new InputProxy(ruleset.Root, null);
|
||||
foreach (var i in ruleset.Root.inputs) {
|
||||
var e = GameObject.Instantiate(m_prefabInputConfigEntry, m_entryList.transform).GetComponent<InputConfigEntry>();
|
||||
foreach (var i in m_configScene.ruleset.Root.inputs) {
|
||||
var e = GameObject.Instantiate(m_prefabInputConfigEntry, m_entryList.transform).GetComponent<InputConfigPanelEntry>();
|
||||
_entries.Add(i.Key, e);
|
||||
e.SetKey(this, i.Key);
|
||||
OnProxyChanged(this, proxy[i.Key]);
|
||||
}
|
||||
_proxy.ProxyChanged += OnProxyChanged;
|
||||
}
|
||||
proxy.ProxyChanged += OnProxyChanged;
|
||||
}
|
||||
|
||||
void OnProxyChanged(object sender, ProxyChangedEventArgs e) {
|
||||
@@ -94,7 +78,7 @@ namespace Cryville.Crtr.Config {
|
||||
var obj = Instantiate(m_prefabListItem, m_deviceList);
|
||||
obj.transform.Find("Text").GetComponent<Text>().text = src == null ? "None" : src.Value.Handler.GetTypeName(src.Value.Type);
|
||||
var btn = obj.GetComponent<Button>();
|
||||
if (src != null) btn.interactable = !_proxy.IsUsed(src.Value);
|
||||
if (src != null) btn.interactable = !proxy.IsUsed(src.Value);
|
||||
btn.onClick.AddListener(() => {
|
||||
CloseDialog(src);
|
||||
});
|
@@ -2,7 +2,7 @@
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace Cryville.Crtr.Config {
|
||||
public class InputConfigEntry : MonoBehaviour {
|
||||
public class InputConfigPanelEntry : MonoBehaviour {
|
||||
[SerializeField]
|
||||
Text m_key;
|
||||
|
||||
@@ -12,7 +12,7 @@ namespace Cryville.Crtr.Config {
|
||||
[SerializeField]
|
||||
Button m_button;
|
||||
|
||||
public void SetKey(InputConfig master, string name) {
|
||||
public void SetKey(InputConfigPanel master, string name) {
|
||||
m_key.text = name;
|
||||
m_value.text = "None";
|
||||
m_button.onClick.AddListener(() => {
|
12
Assets/Cryville/Crtr/Config/RulesetConfig.cs
Normal file
12
Assets/Cryville/Crtr/Config/RulesetConfig.cs
Normal file
@@ -0,0 +1,12 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Cryville.Crtr.Config {
|
||||
public class RulesetConfig {
|
||||
public Dictionary<string, InputConfigEntry> inputs
|
||||
= new Dictionary<string, InputConfigEntry>();
|
||||
}
|
||||
public class InputConfigEntry {
|
||||
public string handler;
|
||||
public int type;
|
||||
}
|
||||
}
|
11
Assets/Cryville/Crtr/Config/RulesetConfig.cs.meta
Normal file
11
Assets/Cryville/Crtr/Config/RulesetConfig.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: aa140184f4b7acb4b994a0826e1f107d
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -196,7 +196,7 @@ namespace Cryville.Crtr.Event {
|
||||
public void Dispose() {
|
||||
if (Disposed) return;
|
||||
Disposed = true;
|
||||
if (Handler != null) Handler.Dispose();
|
||||
if (CloneType < 16 && Handler != null) Handler.Dispose();
|
||||
foreach (var s in Children)
|
||||
s.Value.Dispose();
|
||||
RMVPool.ReturnAll();
|
||||
|
@@ -1,13 +1,13 @@
|
||||
using Cryville.Common;
|
||||
using Cryville.Common.Pdt;
|
||||
using Cryville.Common.Unity.Input;
|
||||
using Cryville.Crtr.Config;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using Logger = Cryville.Common.Logger;
|
||||
|
||||
namespace Cryville.Crtr {
|
||||
public class InputProxy {
|
||||
public class InputProxy : IDisposable {
|
||||
readonly PdtEvaluator _etor;
|
||||
readonly PdtRuleset _ruleset;
|
||||
readonly Judge _judge;
|
||||
@@ -37,33 +37,61 @@ namespace Cryville.Crtr {
|
||||
readonly Dictionary<string, int> _use = new Dictionary<string, int>();
|
||||
readonly Dictionary<string, List<string>> _rev = new Dictionary<string, List<string>>();
|
||||
public event EventHandler<ProxyChangedEventArgs> ProxyChanged;
|
||||
public void LoadFrom(Dictionary<string, InputConfigEntry> config) {
|
||||
foreach (var cfg in config) {
|
||||
Set(new InputProxyEntry {
|
||||
Target = cfg.Key,
|
||||
Source = new InputSource {
|
||||
Handler = Game.InputManager.GetHandler(cfg.Value.handler),
|
||||
Type = cfg.Value.type
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
public void SaveTo(Dictionary<string, InputConfigEntry> config) {
|
||||
config.Clear();
|
||||
foreach (var p in _tproxies) {
|
||||
config.Add(p.Key, new InputConfigEntry {
|
||||
handler = ReflectionHelper.GetNamespaceQualifiedName(p.Value.Source.Value.Handler.GetType()),
|
||||
type = p.Value.Source.Value.Type
|
||||
});
|
||||
}
|
||||
}
|
||||
public void Set(InputProxyEntry proxy) {
|
||||
var name = proxy.Target;
|
||||
if (_tproxies.ContainsKey(name)) Remove(proxy);
|
||||
if (_use[proxy.Target] > 0)
|
||||
var target = proxy.Target;
|
||||
if (!_ruleset.inputs.ContainsKey(target)) throw new ArgumentException("Invalid input name");
|
||||
if (_tproxies.ContainsKey(target)) Remove(proxy);
|
||||
if (_use[target] > 0)
|
||||
throw new InvalidOperationException("Input already assigned");
|
||||
if (proxy.Source != null) {
|
||||
if (_judge != null) {
|
||||
proxy.Source.Value.Handler.OnInput -= OnInput; // Prevent duplicated hooks, no exception will be thrown
|
||||
proxy.Source.Value.Handler.OnInput += OnInput;
|
||||
}
|
||||
_tproxies.Add(proxy.Target, proxy);
|
||||
_tproxies.Add(target, proxy);
|
||||
_sproxies.Add(proxy.Source.Value, proxy);
|
||||
IncrementUseRecursive(name);
|
||||
IncrementReversedUseRecursive(name);
|
||||
IncrementUseRecursive(target);
|
||||
IncrementReversedUseRecursive(target);
|
||||
}
|
||||
}
|
||||
void Remove(InputProxyEntry proxy) {
|
||||
var name = proxy.Target;
|
||||
if (_judge != null) _tproxies[name].Source.Value.Handler.OnInput -= OnInput;
|
||||
_sproxies.Remove(_tproxies[name].Source.Value);
|
||||
_tproxies.Remove(name);
|
||||
DecrementUseRecursive(name);
|
||||
DecrementReversedUseRecursive(name);
|
||||
var target = proxy.Target;
|
||||
if (_judge != null) _tproxies[target].Source.Value.Handler.OnInput -= OnInput;
|
||||
_sproxies.Remove(_tproxies[target].Source.Value);
|
||||
_tproxies.Remove(target);
|
||||
DecrementUseRecursive(target);
|
||||
DecrementReversedUseRecursive(target);
|
||||
}
|
||||
public bool IsUsed(InputSource src) {
|
||||
return _sproxies.ContainsKey(src);
|
||||
}
|
||||
public bool IsCompleted {
|
||||
get {
|
||||
foreach (var i in _use)
|
||||
if (i.Value == 0 && !_tproxies.ContainsKey(i.Key)) return false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
void IncrementUseRecursive(string name) {
|
||||
BroadcastProxyChanged(name);
|
||||
var passes = _ruleset.inputs[name].pass;
|
||||
@@ -100,7 +128,12 @@ namespace Cryville.Crtr {
|
||||
}
|
||||
void BroadcastProxyChanged(string name) {
|
||||
var del = ProxyChanged;
|
||||
if (del != null) del(this, new ProxyChangedEventArgs(name, _tproxies.ContainsKey(name) ? _tproxies[name].Source : null, _use[name] > 0));
|
||||
if (del != null) del(this, this[name]);
|
||||
}
|
||||
public ProxyChangedEventArgs this[string name] {
|
||||
get {
|
||||
return new ProxyChangedEventArgs(name, _tproxies.ContainsKey(name) ? _tproxies[name].Source : null, _use[name] > 0);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
@@ -115,6 +148,22 @@ namespace Cryville.Crtr {
|
||||
}
|
||||
public void Deactivate() { foreach (var src in _sproxies.Keys) src.Handler.Deactivate(); }
|
||||
|
||||
~InputProxy() {
|
||||
Dispose(false);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
public void Dispose() {
|
||||
Dispose(true);
|
||||
}
|
||||
protected void Dispose(bool disposing) {
|
||||
if (disposing) {
|
||||
Deactivate();
|
||||
foreach (var proxy in _tproxies.Values) {
|
||||
proxy.Source.Value.Handler.OnInput -= OnInput;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
readonly object _lock = new object();
|
||||
static readonly int _var_value = IdentifierManager.SharedInstance.Request("value");
|
||||
static readonly PropOp.Arbitrary _arbop = new PropOp.Arbitrary();
|
||||
|
39
Assets/Cryville/Crtr/Popup.cs
Normal file
39
Assets/Cryville/Crtr/Popup.cs
Normal file
@@ -0,0 +1,39 @@
|
||||
using System;
|
||||
using UnityEditor.VersionControl;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace Cryville.Crtr {
|
||||
public class Popup : MonoBehaviour {
|
||||
public string Message = "";
|
||||
CanvasGroup group;
|
||||
float timer = 0;
|
||||
|
||||
const float DURATION = 5.0f;
|
||||
const float DURIN = 0.4f;
|
||||
const float DUROUT = 0.4f;
|
||||
|
||||
void Start() {
|
||||
group = GetComponent<CanvasGroup>();
|
||||
group.alpha = 0;
|
||||
GetComponentInChildren<Text>().text = Message;
|
||||
transform.SetParent(GameObject.Find("PopupList").transform);
|
||||
}
|
||||
|
||||
void Update() {
|
||||
if (timer <= DURIN) group.alpha = timer / DURIN;
|
||||
else if (timer >= DURATION) GameObject.Destroy(gameObject);
|
||||
else if (timer >= DURATION - DUROUT) group.alpha = (DURATION - timer) / DUROUT;
|
||||
timer += Time.deltaTime;
|
||||
}
|
||||
|
||||
|
||||
public static void CreateException(Exception ex) {
|
||||
Create(ex.Message);
|
||||
}
|
||||
|
||||
public static void Create(string msg) {
|
||||
Instantiate(Resources.Load<GameObject>("Common/Popup")).GetComponent<Popup>().Message = msg;
|
||||
}
|
||||
}
|
||||
}
|
@@ -84,6 +84,18 @@ namespace Cryville.Crtr {
|
||||
}
|
||||
}
|
||||
|
||||
[Browsable(false)]
|
||||
[Category("data")]
|
||||
[Description("The ruleset config file to load.")]
|
||||
public string LoadRulesetConfig {
|
||||
get {
|
||||
return PlayerPrefs.GetString("LoadRulesetConfig", "");
|
||||
}
|
||||
set {
|
||||
PlayerPrefs.SetString("LoadRulesetConfig", value);
|
||||
}
|
||||
}
|
||||
|
||||
[Browsable(false)]
|
||||
[Category("data")]
|
||||
[Description("The skin file to load.")]
|
||||
|
Binary file not shown.
Binary file not shown.
Reference in New Issue
Block a user