Compare commits
33 Commits
Author | SHA1 | Date | |
---|---|---|---|
59c2210359 | |||
4fab20953a | |||
ee7b0f5081 | |||
33ee7a9a87 | |||
900bd7b77a | |||
6bd32c9aef | |||
13893b2853 | |||
23789c15eb | |||
a1f7418d32 | |||
274a823d02 | |||
ba6239068a | |||
ff8c925f32 | |||
2a6a33e60c | |||
8910b1f4a0 | |||
36dddea4d9 | |||
6a648c2dcd | |||
2d4087dc89 | |||
f91aacd78e | |||
9c08cbf0d2 | |||
88d35e4eaf | |||
675ce68073 | |||
db0165d145 | |||
7015426300 | |||
0d4cc5e208 | |||
e7ce0985fb | |||
eb6dafbd60 | |||
b6e238780e | |||
c7ea6f1d4b | |||
4a5b2a6889 | |||
b84d645aee | |||
67b44db1ae | |||
ee4399109a | |||
87ef534f59 |
@@ -24,11 +24,11 @@ namespace Cryville.Common {
|
||||
if (Key == 0) return "";
|
||||
return Name.ToString();
|
||||
}
|
||||
public static implicit operator Identifier(string identifier) {
|
||||
return new Identifier(identifier);
|
||||
public static bool operator ==(Identifier lhs, Identifier rhs) {
|
||||
return lhs.Equals(rhs);
|
||||
}
|
||||
public static implicit operator string(Identifier identifier) {
|
||||
return identifier.ToString();
|
||||
public static bool operator !=(Identifier lhs, Identifier rhs) {
|
||||
return !lhs.Equals(rhs);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -186,7 +186,7 @@ namespace Cryville.Common.Pdt {
|
||||
protected abstract PdtOperator GetOperator(PdtOperatorSignature sig);
|
||||
unsafe void Operate(PdtOperator op, int pc, bool noset = false) {
|
||||
fixed (byte* pmem = _mem) {
|
||||
op.Begin(this);
|
||||
op.Begin(this, pc);
|
||||
for (int i = 0; i < pc; i++) {
|
||||
var frame = _stack[--_framecount];
|
||||
op.LoadOperand(new PdtVariableMemory(frame.Type, pmem + frame.Offset, frame.Length));
|
||||
|
@@ -54,15 +54,14 @@ namespace Cryville.Common.Pdt {
|
||||
/// <param name="binder">The binder.</param>
|
||||
/// <returns>The interpreted object.</returns>
|
||||
public static T Interpret<T>(string src, Binder binder) {
|
||||
return (T)new PdtInterpreter(src, typeof(T), binder).Interpret();
|
||||
return (T)new PdtInterpreter(src, binder).Interpret(typeof(T));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The source string.
|
||||
/// </summary>
|
||||
public string Source { get; private set; }
|
||||
readonly Type _type;
|
||||
readonly Binder _binder;
|
||||
Binder _binder;
|
||||
/// <summary>
|
||||
/// The current position in the string being parsed by the interpreter.
|
||||
/// </summary>
|
||||
@@ -167,23 +166,27 @@ namespace Cryville.Common.Pdt {
|
||||
/// Creates an instance of the <see cref="PdtInterpreter" /> class.
|
||||
/// </summary>
|
||||
/// <param name="src">The source string.</param>
|
||||
/// <param name="type">The destination type.</param>
|
||||
/// <param name="binder">The binder. May be <c>null</c>.</param>
|
||||
public PdtInterpreter(string src, Type type, Binder binder) {
|
||||
public PdtInterpreter(string src, Binder binder) {
|
||||
Source = src;
|
||||
_type = type;
|
||||
_binder = binder;
|
||||
if (_binder == null)
|
||||
_binder = BinderAttribute.CreateBinderOfType(_type);
|
||||
}
|
||||
int[] m_formatVersion;
|
||||
public int[] GetFormatVersion() {
|
||||
if (m_formatVersion == null) InterpretDirectives();
|
||||
return m_formatVersion;
|
||||
}
|
||||
/// <summary>
|
||||
/// Interprets the source to an object.
|
||||
/// </summary>
|
||||
/// <param name="type">The output type.</param>
|
||||
/// <returns>The interpreted object.</returns>
|
||||
public object Interpret() {
|
||||
public object Interpret(Type type) {
|
||||
try {
|
||||
InterpretDirectives();
|
||||
return InterpretObject(_type);
|
||||
if (m_formatVersion == null) InterpretDirectives();
|
||||
if (_binder == null)
|
||||
_binder = BinderAttribute.CreateBinderOfType(type);
|
||||
return InterpretObject(type);
|
||||
}
|
||||
catch (Exception ex) {
|
||||
throw new PdtParsingException(this, ex);
|
||||
@@ -201,7 +204,10 @@ namespace Cryville.Common.Pdt {
|
||||
break;
|
||||
case "format":
|
||||
ws();
|
||||
if (GetNumber() != "1")
|
||||
m_formatVersion = (from i in GetNumber().Split('.') select int.Parse(i)).ToArray();
|
||||
if (m_formatVersion.Length == 0)
|
||||
throw new FormatException("Invalid format version");
|
||||
if (m_formatVersion[0] != 1)
|
||||
throw new NotSupportedException("Format not supported");
|
||||
flag = true;
|
||||
break;
|
||||
@@ -226,6 +232,10 @@ namespace Cryville.Common.Pdt {
|
||||
while (true) {
|
||||
try { ws(); }
|
||||
catch (IndexOutOfRangeException) { return result; }
|
||||
if (cc == '}') {
|
||||
GetChar();
|
||||
return result;
|
||||
}
|
||||
object pkey = InterpretKey(type);
|
||||
char c = GetChar();
|
||||
switch (c) {
|
||||
@@ -288,8 +298,6 @@ namespace Cryville.Common.Pdt {
|
||||
}
|
||||
}
|
||||
break;
|
||||
case '}':
|
||||
return result;
|
||||
default:
|
||||
throw new InvalidOperationException("Internal error: Invalid key interpretation");
|
||||
}
|
||||
|
@@ -11,7 +11,7 @@ namespace Cryville.Common.Pdt {
|
||||
/// <summary>
|
||||
/// The count of the operands loaded.
|
||||
/// </summary>
|
||||
protected int LoadedOperandCount { get { return _pc - _loadindex; } }
|
||||
protected int LoadedOperandCount { get; private set; }
|
||||
/// <summary>
|
||||
/// Gets the operand at the specified index.
|
||||
/// </summary>
|
||||
@@ -35,13 +35,13 @@ namespace Cryville.Common.Pdt {
|
||||
}
|
||||
PdtEvaluatorBase _etor;
|
||||
bool _rfreq = true;
|
||||
internal void Begin(PdtEvaluatorBase etor) {
|
||||
internal void Begin(PdtEvaluatorBase etor, int pc) {
|
||||
_etor = etor;
|
||||
_loadindex = _pc;
|
||||
_loadindex = LoadedOperandCount = pc;
|
||||
}
|
||||
internal void LoadOperand(PdtVariableMemory mem) {
|
||||
if (_loadindex == 0) return;
|
||||
_operands[--_loadindex] = mem;
|
||||
if (--_loadindex >= _pc) return;
|
||||
_operands[_loadindex] = mem;
|
||||
}
|
||||
internal void Call(byte* prmem, bool noset) {
|
||||
_prmem = prmem;
|
||||
|
@@ -16,7 +16,6 @@ using UnityEngine;
|
||||
using UnityEngine.Networking;
|
||||
using UnityEngine.SceneManagement;
|
||||
using UnityEngine.Scripting;
|
||||
using UnityEngine.UI;
|
||||
using diag = System.Diagnostics;
|
||||
using Logger = Cryville.Common.Logger;
|
||||
|
||||
@@ -43,14 +42,14 @@ namespace Cryville.Crtr {
|
||||
EventBus bbus;
|
||||
EventBus tbus;
|
||||
EventBus nbus;
|
||||
InputProxy inputProxy;
|
||||
Judge judge;
|
||||
public static EffectManager effectManager;
|
||||
bool started = false;
|
||||
|
||||
static bool initialized;
|
||||
static Text logs;
|
||||
TextMeshProUGUI logs;
|
||||
TextMeshProUGUI status;
|
||||
readonly TargetString statusstr = new TargetString();
|
||||
readonly StringBuffer statusbuf = new StringBuffer();
|
||||
|
||||
static Vector2 screenSize;
|
||||
public static Rect hitRect;
|
||||
@@ -71,15 +70,15 @@ namespace Cryville.Crtr {
|
||||
public static Dictionary<Identifier, MotionRegistry> motionRegistry = new Dictionary<Identifier, MotionRegistry>();
|
||||
|
||||
public static PdtEvaluator etor;
|
||||
|
||||
InputProxy inputProxy;
|
||||
#endregion
|
||||
|
||||
#region MonoBehaviour
|
||||
void Start() {
|
||||
d_addLogEntry = new Action<int, string, string>(AddLogEntry);
|
||||
|
||||
var logobj = GameObject.Find("Logs");
|
||||
if (logobj != null)
|
||||
logs = logobj.GetComponent<Text>();
|
||||
logs = logobj.GetComponent<TextMeshProUGUI>();
|
||||
if (!initialized) {
|
||||
Game.Init();
|
||||
GenericResources.LoadDefault();
|
||||
@@ -162,6 +161,8 @@ namespace Cryville.Crtr {
|
||||
tbus.ForwardStepByTime(renderDist, step);
|
||||
tbus.EndGraphicalUpdate();
|
||||
UnityEngine.Profiling.Profiler.EndSample();
|
||||
|
||||
effectManager.Tick(cbus.Time);
|
||||
}
|
||||
catch (Exception ex) {
|
||||
Game.LogException("Game", "An error occured while playing", ex);
|
||||
@@ -177,6 +178,12 @@ namespace Cryville.Crtr {
|
||||
if (texHandler.isDone) {
|
||||
var tex = texHandler.texture;
|
||||
tex.wrapMode = TextureWrapMode.Clamp;
|
||||
if (frames.ContainsKey(name)) {
|
||||
Logger.Log("main", 3, "Load/Prehandle", "Duplicated texture name: {0}", name);
|
||||
}
|
||||
else {
|
||||
frames.Add(name, new SpriteFrame(tex));
|
||||
}
|
||||
texs.Add(name, tex);
|
||||
texLoader.Dispose();
|
||||
texHandler.Dispose();
|
||||
@@ -192,14 +199,14 @@ namespace Cryville.Crtr {
|
||||
}
|
||||
#endif
|
||||
}
|
||||
if (texLoader == null)
|
||||
if (texLoader == null) {
|
||||
if (texLoadQueue.Count > 0) {
|
||||
#if UNITY_5_4_OR_NEWER
|
||||
texHandler = new DownloadHandlerTexture();
|
||||
texLoader = new UnityWebRequest(Game.FileProtocolPrefix + texLoadQueue.Dequeue(), "GET", texHandler, null);
|
||||
texLoader.SendWebRequest();
|
||||
#else
|
||||
texLoader = new WWW(Game.FileProtocolPrefix + texLoadQueue.Dequeue());
|
||||
texLoader = new WWW(Game.FileProtocolPrefix + texLoadQueue.Dequeue());
|
||||
#endif
|
||||
}
|
||||
else if (!texloaddone) {
|
||||
@@ -207,6 +214,7 @@ namespace Cryville.Crtr {
|
||||
texloadtimer.Stop();
|
||||
Logger.Log("main", 1, "Load/MainThread", "Main thread done ({0}ms)", texloadtimer.Elapsed.TotalMilliseconds);
|
||||
}
|
||||
}
|
||||
if (!loadThread.IsAlive) {
|
||||
if (threadException != null) {
|
||||
Logger.Log("main", 4, "Load/MainThread", "Load failed");
|
||||
@@ -222,25 +230,46 @@ namespace Cryville.Crtr {
|
||||
}
|
||||
}
|
||||
}
|
||||
readonly TargetString statusstr = new TargetString();
|
||||
readonly StringBuffer statusbuf = new StringBuffer();
|
||||
readonly TargetString logsstr = new TargetString();
|
||||
readonly StringBuffer logsbuf = new StringBuffer();
|
||||
readonly List<string> logEntries = new List<string>();
|
||||
int logsLength = 0;
|
||||
Action<int, string, string> d_addLogEntry;
|
||||
void AddLogEntry(int level, string module, string msg) {
|
||||
string color;
|
||||
switch (level) {
|
||||
case 0: color = "#888888"; break;
|
||||
case 1: color = "#bbbbbb"; break;
|
||||
case 2: color = "#0088ff"; break;
|
||||
case 3: color = "#ffff00"; break;
|
||||
case 4: color = "#ff0000"; break;
|
||||
case 5: color = "#bb0000"; break;
|
||||
default: color = "#ff00ff"; break;
|
||||
}
|
||||
var l = string.Format(
|
||||
"\n<color={1}bb><{2}> {3}</color>",
|
||||
DateTime.UtcNow.ToString("s"), color, module, msg
|
||||
);
|
||||
logEntries.Add(l);
|
||||
logsLength += l.Length;
|
||||
}
|
||||
void LogUpdate() {
|
||||
string _logs = logs.text;
|
||||
Game.MainLogger.Enumerate((level, module, msg) => {
|
||||
string color;
|
||||
switch (level) {
|
||||
case 0: color = "#888888"; break;
|
||||
case 1: color = "#bbbbbb"; break;
|
||||
case 2: color = "#0088ff"; break;
|
||||
case 3: color = "#ffff00"; break;
|
||||
case 4: color = "#ff0000"; break;
|
||||
case 5: color = "#bb0000"; break;
|
||||
default: color = "#ff00ff"; break;
|
||||
}
|
||||
_logs += string.Format(
|
||||
"\r\n<color={1}bb><{2}> {3}</color>",
|
||||
DateTime.UtcNow.ToString("s"), color, module, msg
|
||||
);
|
||||
});
|
||||
logs.text = _logs.Substring(Mathf.Max(0, _logs.IndexOf('\n', Mathf.Max(0, _logs.Length - 4096))));
|
||||
logsbuf.Clear();
|
||||
Game.MainLogger.Enumerate(d_addLogEntry);
|
||||
while (logsLength >= 4096) {
|
||||
logsLength -= logEntries[0].Length;
|
||||
logEntries.RemoveAt(0);
|
||||
}
|
||||
foreach (var l in logEntries) {
|
||||
logsbuf.Append(l);
|
||||
}
|
||||
logsstr.Length = logsbuf.Count;
|
||||
var larr = logsstr.TrustedAsArray();
|
||||
logsbuf.CopyTo(0, larr, 0, logsbuf.Count);
|
||||
logs.SetText(larr, 0, logsbuf.Count);
|
||||
|
||||
statusbuf.Clear();
|
||||
statusbuf.AppendFormat(
|
||||
"FPS: i{0:0} / s{1:0}\nSMem: {2:N0} / {3:N0}\nIMem: {4:N0} / {5:N0}",
|
||||
@@ -281,9 +310,9 @@ namespace Cryville.Crtr {
|
||||
}
|
||||
}
|
||||
statusstr.Length = statusbuf.Count;
|
||||
var arr = statusstr.TrustedAsArray();
|
||||
statusbuf.CopyTo(0, arr, 0, statusbuf.Count);
|
||||
status.SetText(arr, 0, statusbuf.Count);
|
||||
var sarr = statusstr.TrustedAsArray();
|
||||
statusbuf.CopyTo(0, sarr, 0, statusbuf.Count);
|
||||
status.SetText(sarr, 0, statusbuf.Count);
|
||||
}
|
||||
#endregion
|
||||
|
||||
@@ -313,6 +342,8 @@ namespace Cryville.Crtr {
|
||||
|
||||
bool logEnabled = true;
|
||||
public void ToggleLogs() {
|
||||
logEntries.Clear();
|
||||
logsLength = 0;
|
||||
logs.text = "";
|
||||
status.SetText("");
|
||||
logEnabled = !logEnabled;
|
||||
@@ -424,16 +455,6 @@ namespace Cryville.Crtr {
|
||||
try {
|
||||
diag::Stopwatch timer = new diag::Stopwatch();
|
||||
timer.Reset(); timer.Start();
|
||||
Logger.Log("main", 0, "Load/Prehandle", "Initializing textures");
|
||||
foreach (var t in texs) {
|
||||
if (frames.ContainsKey(t.Key)) {
|
||||
Logger.Log("main", 3, "Load/Prehandle", "Duplicated texture name: {0}", t.Key);
|
||||
continue;
|
||||
}
|
||||
var f = new SpriteFrame(t.Value);
|
||||
f.Init();
|
||||
frames.Add(t.Key, f);
|
||||
}
|
||||
Logger.Log("main", 0, "Load/Prehandle", "Prehandling (iteration 2)");
|
||||
cbus.BroadcastPreInit();
|
||||
Logger.Log("main", 0, "Load/Prehandle", "Prehandling (iteration 3)");
|
||||
@@ -450,8 +471,10 @@ namespace Cryville.Crtr {
|
||||
timer.Stop();
|
||||
Logger.Log("main", 1, "Load/Prehandle", "Prehandling done ({0}ms)", timer.Elapsed.TotalMilliseconds);
|
||||
if (Settings.Default.ClearLogOnPlay) {
|
||||
logs.text = "";
|
||||
logEntries.Clear();
|
||||
logsLength = 0;
|
||||
Game.MainLogger.Enumerate((level, module, msg) => { });
|
||||
logs.text = "";
|
||||
}
|
||||
Game.AudioSequencer.Playing = true;
|
||||
atime0 = Game.AudioClient.BufferPosition;
|
||||
@@ -476,6 +499,9 @@ namespace Cryville.Crtr {
|
||||
if (tbus != null) { tbus.Dispose(); tbus = null; }
|
||||
if (bbus != null) { bbus.Dispose(); bbus = null; }
|
||||
if (cbus != null) { cbus.Dispose(); cbus.DisposeAll(); cbus = null; }
|
||||
effectManager.Dispose();
|
||||
effectManager = null;
|
||||
etor = null;
|
||||
Logger.Log("main", 1, "Game", "Stopped");
|
||||
}
|
||||
catch (Exception ex) {
|
||||
@@ -559,7 +585,7 @@ namespace Cryville.Crtr {
|
||||
|
||||
inputProxy = new InputProxy(pruleset, judge);
|
||||
inputProxy.LoadFrom(_rscfg.inputs);
|
||||
if (!inputProxy.IsCompleted) {
|
||||
if (!inputProxy.IsCompleted()) {
|
||||
throw new ArgumentException("Input config not completed\nPlease complete the input settings");
|
||||
}
|
||||
|
||||
@@ -617,6 +643,7 @@ namespace Cryville.Crtr {
|
||||
skin.LoadPdt(dir);
|
||||
pskin = skin.Root;
|
||||
pskin.Optimize(etor);
|
||||
effectManager = new EffectManager(pskin);
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
|
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Cryville.Crtr.Components {
|
||||
public abstract class MeshBase : SkinComponent {
|
||||
@@ -7,6 +8,7 @@ namespace Cryville.Crtr.Components {
|
||||
}
|
||||
|
||||
protected MeshWrapper mesh = new MeshWrapper();
|
||||
protected Material[] materials;
|
||||
|
||||
short _zindex;
|
||||
public short ZIndex {
|
||||
@@ -22,9 +24,16 @@ namespace Cryville.Crtr.Components {
|
||||
}
|
||||
protected void UpdateZIndex() {
|
||||
if (!mesh.Initialized) return;
|
||||
foreach (var mat in mesh.Renderer.materials) {
|
||||
foreach (var mat in materials) {
|
||||
mat.renderQueue = _zindex;
|
||||
}
|
||||
}
|
||||
protected override void OnDestroy() {
|
||||
if (materials != null)
|
||||
foreach (var mat in materials) {
|
||||
Material.Destroy(mat);
|
||||
}
|
||||
mesh.Destroy();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -19,11 +19,7 @@ namespace Cryville.Crtr.Components {
|
||||
|
||||
public SectionalGameObject() {
|
||||
SubmitProperty("partial", new PropOp.Boolean(v => part = Part.idle));
|
||||
SubmitProperty("part", new PropOp.Enum<Part>(v => part = v, v => (Part)v), 2);
|
||||
}
|
||||
|
||||
protected override void OnDestroy() {
|
||||
mesh.Destroy();
|
||||
SubmitProperty("part", new PropOp.Enum<Part>(v => part = v, v => (Part)v), 1);
|
||||
}
|
||||
|
||||
public override void Init() {
|
||||
@@ -67,7 +63,7 @@ namespace Cryville.Crtr.Components {
|
||||
SubmitProperty("head", new PropOp.String(v => head.FrameName = v));
|
||||
SubmitProperty("body", new PropOp.String(v => body.FrameName = v));
|
||||
SubmitProperty("tail", new PropOp.String(v => tail.FrameName = v));
|
||||
SubmitProperty("shape", new op_set_shape(this), 2);
|
||||
SubmitProperty("shape", new op_set_shape(this), 1);
|
||||
}
|
||||
|
||||
#pragma warning disable IDE1006
|
||||
@@ -103,7 +99,6 @@ namespace Cryville.Crtr.Components {
|
||||
public SpriteInfo body = new SpriteInfo();
|
||||
public SpriteInfo tail = new SpriteInfo();
|
||||
|
||||
Material[] mats;
|
||||
List<Vector3> vertices;
|
||||
List<float> lengths;
|
||||
float sumLength = 0;
|
||||
@@ -112,23 +107,25 @@ namespace Cryville.Crtr.Components {
|
||||
base.Init();
|
||||
mesh.Init(transform);
|
||||
|
||||
mats = mesh.Renderer.materials = new Material[] { mesh.NewMaterial, mesh.NewMaterial, mesh.NewMaterial };
|
||||
head.Bind(mats[0]);
|
||||
body.Bind(mats[1]);
|
||||
tail.Bind(mats[2]);
|
||||
mesh.Renderer.materials = materials = new Material[] {
|
||||
MeshWrapper.NewMaterial(),
|
||||
MeshWrapper.NewMaterial(),
|
||||
MeshWrapper.NewMaterial(),
|
||||
};
|
||||
head.Bind(materials[0]);
|
||||
body.Bind(materials[1]);
|
||||
tail.Bind(materials[2]);
|
||||
|
||||
UpdateZIndex();
|
||||
}
|
||||
|
||||
protected override void OnDestroy() {
|
||||
base.OnDestroy();
|
||||
Reset();
|
||||
foreach (var m in mats) Material.Destroy(m);
|
||||
if (_shape != null) _shapePool.Return(_shape);
|
||||
if (vertices != null) {
|
||||
_ptPool.Return(vertices);
|
||||
_lPool.Return(lengths);
|
||||
}
|
||||
base.OnDestroy();
|
||||
}
|
||||
|
||||
protected override void AppendPointInternal(Vector3 p, Quaternion r) {
|
||||
|
5
Assets/Cryville/Crtr/Components/SkinAnimation.cs
Normal file
5
Assets/Cryville/Crtr/Components/SkinAnimation.cs
Normal file
@@ -0,0 +1,5 @@
|
||||
namespace Cryville.Crtr.Components {
|
||||
public class SkinAnimation : SkinComponent {
|
||||
protected override void OnDestroy() { }
|
||||
}
|
||||
}
|
11
Assets/Cryville/Crtr/Components/SkinAnimation.cs.meta
Normal file
11
Assets/Cryville/Crtr/Components/SkinAnimation.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 80318e36af5412345871bdbf80d49ef2
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -14,8 +14,8 @@ namespace Cryville.Crtr.Components {
|
||||
/// </summary>
|
||||
/// <param name="name">The name of the property.</param>
|
||||
/// <param name="property">The property.</param>
|
||||
protected void SubmitProperty(string name, PdtOperator property, int uct = 1) {
|
||||
Properties.Add(IdentifierManager.SharedInstance.Request(name), new SkinProperty(property, uct));
|
||||
protected void SubmitProperty(string name, PdtOperator property, int udl = 0) {
|
||||
Properties.Add(IdentifierManager.SharedInstance.Request(name), new SkinProperty(property, udl));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -30,10 +30,10 @@ namespace Cryville.Crtr.Components {
|
||||
}
|
||||
public struct SkinProperty {
|
||||
public PdtOperator Operator { get; set; }
|
||||
public int UpdateCloneType { get; set; }
|
||||
public SkinProperty(PdtOperator op, int uct = 1) {
|
||||
public int UpdateDynamicLevel { get; set; }
|
||||
public SkinProperty(PdtOperator op, int udl = 0) {
|
||||
Operator = op;
|
||||
UpdateCloneType = uct;
|
||||
UpdateDynamicLevel = udl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -25,10 +25,6 @@ namespace Cryville.Crtr.Components {
|
||||
}
|
||||
#pragma warning restore IDE1006
|
||||
|
||||
protected override void OnDestroy() {
|
||||
mesh.Destroy();
|
||||
}
|
||||
|
||||
Vector2 _scale = Vector2.one;
|
||||
public Vector2 Scale {
|
||||
get { return _scale; }
|
||||
@@ -92,6 +88,7 @@ namespace Cryville.Crtr.Components {
|
||||
|
||||
protected void InternalInit(string meshName = "quad") {
|
||||
mesh.Init(transform);
|
||||
mesh.Renderer.materials = materials = new Material[] { MeshWrapper.NewMaterial() };
|
||||
mesh.Mesh = GenericResources.Meshes[meshName];
|
||||
UpdateScale();
|
||||
UpdateZIndex();
|
||||
|
@@ -29,19 +29,12 @@ namespace Cryville.Crtr.Components {
|
||||
return Rect.width / Rect.height;
|
||||
}
|
||||
}
|
||||
bool _loaded;
|
||||
Material _mat;
|
||||
public void Bind(Material mat) {
|
||||
_loaded = true;
|
||||
_mat = mat;
|
||||
Reload();
|
||||
}
|
||||
public void Load() {
|
||||
_loaded = true;
|
||||
Reload();
|
||||
}
|
||||
public void Reload() {
|
||||
if (!_loaded) return;
|
||||
if (!string.IsNullOrEmpty(FrameName)) {
|
||||
if (ChartPlayer.frames.ContainsKey(FrameName)) {
|
||||
Frame = ChartPlayer.frames[FrameName];
|
||||
@@ -56,11 +49,16 @@ namespace Cryville.Crtr.Components {
|
||||
_mat.mainTexture = Frame == null ? null : Frame.Texture;
|
||||
}
|
||||
}
|
||||
public static bool IsNullOrEmpty(SpriteInfo sprite) {
|
||||
return sprite == null || sprite.Frame == null;
|
||||
}
|
||||
}
|
||||
|
||||
public class SpritePlane : SpriteBase {
|
||||
public SpritePlane() {
|
||||
SubmitProperty("frame", new PropOp.String(v => Frame = v));
|
||||
SubmitProperty("frames", new PropOp.StringArray(v => Frames = v));
|
||||
SubmitProperty("index", new PropOp.Integer(v => Index = v));
|
||||
SubmitProperty("fit", new PropOp.Enum<FitMode>(v => Fit = v, v => (FitMode)v));
|
||||
SubmitProperty("opacity", new PropOp.Float(v => Opacity = v));
|
||||
}
|
||||
@@ -83,37 +81,61 @@ namespace Cryville.Crtr.Components {
|
||||
}
|
||||
}
|
||||
|
||||
protected SpriteInfo frameInfo = new SpriteInfo();
|
||||
|
||||
public string Frame {
|
||||
get { return frameInfo.FrameName; }
|
||||
int m_index;
|
||||
public int Index {
|
||||
get { return m_index; }
|
||||
set {
|
||||
frameInfo.FrameName = value;
|
||||
m_index = value;
|
||||
OnFrameUpdate();
|
||||
}
|
||||
}
|
||||
SpriteInfo[] m_frames = new SpriteInfo[] { new SpriteInfo() };
|
||||
public string[] Frames {
|
||||
set {
|
||||
m_frames = new SpriteInfo[value.Length];
|
||||
for (int i = 0; i < value.Length; i++) {
|
||||
m_frames[i] = new SpriteInfo() { FrameName = value[i] };
|
||||
}
|
||||
OnFrameUpdate();
|
||||
}
|
||||
}
|
||||
public string Frame {
|
||||
set {
|
||||
if (value == CurrentFrame.FrameName) return;
|
||||
CurrentFrame.FrameName = value;
|
||||
OnFrameUpdate();
|
||||
}
|
||||
}
|
||||
protected SpriteInfo CurrentFrame {
|
||||
get {
|
||||
if (m_frames.Length == 0) return null;
|
||||
if (m_index < 0) m_index = 0;
|
||||
else if (m_index >= m_frames.Length) m_index = m_frames.Length - 1;
|
||||
return m_frames[m_index];
|
||||
}
|
||||
}
|
||||
protected void OnFrameUpdate() {
|
||||
if (!mesh.Initialized) return;
|
||||
if (frameInfo.Frame == null) {
|
||||
var frame = CurrentFrame;
|
||||
if (SpriteInfo.IsNullOrEmpty(frame)) {
|
||||
mesh.Renderer.enabled = false;
|
||||
return;
|
||||
}
|
||||
mesh.Renderer.enabled = true;
|
||||
mesh.Renderer.material.mainTexture = frame.Frame.Texture;
|
||||
UpdateUV();
|
||||
UpdateScale();
|
||||
UpdateZIndex();
|
||||
}
|
||||
readonly Vector2[] _uvs = new Vector2[4];
|
||||
protected virtual void UpdateUV() {
|
||||
if (frameInfo.Frame == null) {
|
||||
Logger.Log("main", 4, "Skin", "Unable to load texture {0}", frameInfo.FrameName);
|
||||
return;
|
||||
}
|
||||
var frame = CurrentFrame;
|
||||
if (SpriteInfo.IsNullOrEmpty(frame)) return;
|
||||
Vector2[] muv = OriginalUV;
|
||||
Vector2[] uv = new Vector2[muv.Length];
|
||||
for (int i = 0; i < uv.Length; i++) {
|
||||
uv[i] = frameInfo.Frame.GetUV(muv[i]);
|
||||
for (int i = 0; i < _uvs.Length; i++) {
|
||||
_uvs[i] = frame.Frame.GetUV(muv[i]);
|
||||
}
|
||||
mesh.Mesh.uv = uv;
|
||||
mesh.Mesh.uv = _uvs;
|
||||
}
|
||||
|
||||
float _opacity = 1;
|
||||
@@ -124,7 +146,7 @@ namespace Cryville.Crtr.Components {
|
||||
UpdateOpacity();
|
||||
}
|
||||
}
|
||||
void UpdateOpacity() {
|
||||
protected void UpdateOpacity() {
|
||||
if (!mesh.Initialized) return;
|
||||
var c = mesh.Renderer.material.color;
|
||||
c.a = _opacity;
|
||||
@@ -144,7 +166,7 @@ namespace Cryville.Crtr.Components {
|
||||
}
|
||||
|
||||
protected override void UpdateScale() {
|
||||
if (frameInfo.Frame == null) return;
|
||||
if (SpriteInfo.IsNullOrEmpty(CurrentFrame)) return;
|
||||
base.UpdateScale();
|
||||
if (m_fit != FitMode.none && Scale.x != Scale.y) m_fit = FitMode.none;
|
||||
}
|
||||
@@ -153,8 +175,8 @@ namespace Cryville.Crtr.Components {
|
||||
get {
|
||||
switch (m_fit) {
|
||||
case FitMode.none: return Vector3.one;
|
||||
case FitMode.width: return new Vector3(1, 1, 1 / frameInfo.Ratio);
|
||||
case FitMode.height: return new Vector3(frameInfo.Ratio, 1, 1);
|
||||
case FitMode.width: return new Vector3(1, 1, 1 / CurrentFrame.Ratio);
|
||||
case FitMode.height: return new Vector3(CurrentFrame.Ratio, 1, 1);
|
||||
default: throw new NotSupportedException("Unsupported fit mode");
|
||||
}
|
||||
}
|
||||
@@ -162,7 +184,6 @@ namespace Cryville.Crtr.Components {
|
||||
|
||||
public override void Init() {
|
||||
InternalInit();
|
||||
frameInfo.Bind(mesh.Renderer.material);
|
||||
OnFrameUpdate();
|
||||
UpdateOpacity();
|
||||
}
|
||||
|
@@ -44,24 +44,26 @@ namespace Cryville.Crtr.Components {
|
||||
UpdateUV();
|
||||
}
|
||||
|
||||
readonly Vector2[] _uvs = new Vector2[8];
|
||||
readonly Vector3[] _verts = new Vector3[8];
|
||||
protected override void UpdateUV() {
|
||||
Vector2[] muv = OriginalUV;
|
||||
Vector2[] uv = new Vector2[muv.Length];
|
||||
var frame = CurrentFrame;
|
||||
if (SpriteInfo.IsNullOrEmpty(frame)) return;
|
||||
|
||||
var or = frameInfo.Ratio;
|
||||
Vector2[] muv = OriginalUV;
|
||||
|
||||
var or = frame.Ratio;
|
||||
var sr = Scale.x / Scale.y;
|
||||
var b = new Vector2(
|
||||
(or / sr) * _border.x,
|
||||
1 - (or / sr) * (1 - _border.y)
|
||||
);
|
||||
Vector3[] vert = mesh.Mesh.vertices;
|
||||
var rr = or / sr;
|
||||
var b1 = rr * _border.x;
|
||||
var b2 = 1 - rr * (1 - _border.y);
|
||||
|
||||
for (int i = 0; i < muv.Length; i++) {
|
||||
float x; float bx;
|
||||
switch ((int)muv[i].x) {
|
||||
case 0: x = 0; bx = 0; break;
|
||||
case 1: x = _border.x; bx = b.x; break;
|
||||
case 2: x = _border.y; bx = b.y; break;
|
||||
case 1: x = _border.x; bx = b1; break;
|
||||
case 2: x = _border.y; bx = b2; break;
|
||||
case 3: x = 1; bx = 1; break;
|
||||
default: throw new NotSupportedException("Built-in resource corrupted");
|
||||
}
|
||||
@@ -71,18 +73,18 @@ namespace Cryville.Crtr.Components {
|
||||
case 3: y = 1; break;
|
||||
default: throw new NotSupportedException("Built-in resource corrupted");
|
||||
}
|
||||
uv[i] = frameInfo.Frame.GetUV(x, y);
|
||||
_uvs[i] = frame.Frame.GetUV(x, y);
|
||||
bx -= 0.5f; y -= 0.5f;
|
||||
vert[i] = new Vector3(bx, 0, y);
|
||||
_verts[i] = new Vector3(bx, 0, y);
|
||||
}
|
||||
mesh.Mesh.uv = uv;
|
||||
mesh.Mesh.vertices = vert;
|
||||
mesh.Mesh.uv = _uvs;
|
||||
mesh.Mesh.vertices = _verts;
|
||||
}
|
||||
|
||||
public override void Init() {
|
||||
frameInfo.Load();
|
||||
InternalInit("quad_scale3h");
|
||||
OnFrameUpdate();
|
||||
UpdateOpacity();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -25,6 +25,8 @@ namespace Cryville.Crtr.Components {
|
||||
var values = GetOperand(1);
|
||||
int arrtype; int len;
|
||||
values.GetArraySuffix(out arrtype, out len);
|
||||
if (arrtype != PdtInternalType.String) throw new InvalidCastException("Not an array of strings");
|
||||
if (len != keys.Length) throw new ArgumentException("Length of key not equal to frame count");
|
||||
var result = new Dictionary<char, SpriteInfo>(len);
|
||||
int o = 0;
|
||||
for (int i = 0; i < len; i++) {
|
||||
@@ -77,7 +79,6 @@ namespace Cryville.Crtr.Components {
|
||||
verts.Clear();
|
||||
uvs.Clear();
|
||||
foreach (var f in m_frames) {
|
||||
f.Value.Load();
|
||||
if (frameHeight == 0) frameHeight = f.Value.Rect.height;
|
||||
else if (frameHeight != f.Value.Rect.height) throw new Exception("Inconsistent frame height for text component");
|
||||
var tex = f.Value.Frame.Texture;
|
||||
@@ -85,6 +86,7 @@ namespace Cryville.Crtr.Components {
|
||||
var m = new MeshWrapper();
|
||||
m.Init(mesh.MeshTransform);
|
||||
m.Mesh = new Mesh();
|
||||
m.Renderer.material = MeshWrapper.NewMaterial(); // TODO Destroy or add to `materials`
|
||||
m.Renderer.material.mainTexture = tex;
|
||||
meshes.Add(tex, m);
|
||||
verts.Add(tex, new List<Vector3>());
|
||||
@@ -102,10 +104,11 @@ namespace Cryville.Crtr.Components {
|
||||
void UpdateMeshes() {
|
||||
if (meshes.Count == 0) return;
|
||||
sum_x = 0;
|
||||
foreach (var t in meshes.Keys) {
|
||||
verts[t].Clear();
|
||||
uvs[t].Clear();
|
||||
tris[t].Clear();
|
||||
foreach (var t in meshes) {
|
||||
var key = t.Key;
|
||||
verts[key].Clear();
|
||||
uvs[key].Clear();
|
||||
tris[key].Clear();
|
||||
}
|
||||
foreach (var c in m_value) {
|
||||
var f = m_frames[c];
|
||||
@@ -121,11 +124,12 @@ namespace Cryville.Crtr.Components {
|
||||
uvs[t].Add(f.Frame.GetUV(new Vector2(0, 1)));
|
||||
sum_x += w + m_spacing;
|
||||
}
|
||||
foreach (var t in meshes.Keys) {
|
||||
var m = meshes[t].Mesh;
|
||||
foreach (var t in meshes) {
|
||||
var key = t.Key;
|
||||
var m = meshes[key].Mesh;
|
||||
m.Clear();
|
||||
int cc = verts[t].Count / 4;
|
||||
var _tris = tris[t];
|
||||
int cc = verts[key].Count / 4;
|
||||
var _tris = tris[key];
|
||||
for (int i = 0; i < cc; i++) {
|
||||
_tris.Add(i * 4);
|
||||
_tris.Add(i * 4 + 3);
|
||||
@@ -134,9 +138,9 @@ namespace Cryville.Crtr.Components {
|
||||
_tris.Add(i * 4 + 3);
|
||||
_tris.Add(i * 4 + 2);
|
||||
}
|
||||
m.SetVertices(verts[t]);
|
||||
m.SetUVs(0, uvs[t]);
|
||||
m.SetTriangles(tris[t], 0);
|
||||
m.SetVertices(verts[key]);
|
||||
m.SetUVs(0, uvs[key]);
|
||||
m.SetTriangles(tris[key], 0);
|
||||
m.RecalculateNormals();
|
||||
}
|
||||
sum_x -= m_spacing;
|
||||
@@ -164,10 +168,10 @@ namespace Cryville.Crtr.Components {
|
||||
}
|
||||
void UpdateOpacity() {
|
||||
if (!mesh.Initialized) return;
|
||||
foreach (var m in meshes.Values) {
|
||||
var c = m.Renderer.material.color;
|
||||
foreach (var m in meshes) {
|
||||
var c = m.Value.Renderer.material.color;
|
||||
c.a = _opacity;
|
||||
m.Renderer.material.color = c;
|
||||
m.Value.Renderer.material.color = c;
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -1,4 +1,5 @@
|
||||
using Cryville.Common.Unity;
|
||||
using Cryville.Common;
|
||||
using Cryville.Common.Unity;
|
||||
using Cryville.Common.Unity.Input;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
@@ -26,10 +27,10 @@ namespace Cryville.Crtr.Config {
|
||||
|
||||
SimpleInputConsumer _consumer;
|
||||
public InputProxy proxy;
|
||||
readonly Dictionary<string, InputConfigPanelEntry> _entries = new Dictionary<string, InputConfigPanelEntry>();
|
||||
readonly Dictionary<Identifier, InputConfigPanelEntry> _entries = new Dictionary<Identifier, InputConfigPanelEntry>();
|
||||
|
||||
string _sel;
|
||||
public void OpenDialog(string entry) {
|
||||
Identifier _sel;
|
||||
public void OpenDialog(Identifier entry) {
|
||||
_sel = entry;
|
||||
m_inputDialog.SetActive(true);
|
||||
CallHelper.Purge(m_deviceList);
|
||||
@@ -85,9 +86,21 @@ namespace Cryville.Crtr.Config {
|
||||
if (_recvsrcs.Contains(src)) return;
|
||||
_recvsrcs.Add(src);
|
||||
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 text = obj.transform.Find("Text").GetComponent<Text>();
|
||||
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) {
|
||||
var tsrc = src.Value;
|
||||
bool flag = false;
|
||||
if (proxy.IsUsed(tsrc)) {
|
||||
text.text += " (Used)";
|
||||
}
|
||||
else if (tsrc.Handler.GetDimension(src.Value.Type) < m_configScene.ruleset.Root.inputs[_sel].dim) {
|
||||
text.text += " (Not Applicable)";
|
||||
}
|
||||
else flag = true;
|
||||
btn.interactable = flag;
|
||||
}
|
||||
btn.onClick.AddListener(() => {
|
||||
CloseDialog(src);
|
||||
});
|
||||
|
@@ -1,4 +1,5 @@
|
||||
using UnityEngine;
|
||||
using Cryville.Common;
|
||||
using UnityEngine;
|
||||
using UnityEngine.EventSystems;
|
||||
using UnityEngine.UI;
|
||||
|
||||
@@ -13,8 +14,8 @@ namespace Cryville.Crtr.Config {
|
||||
[SerializeField]
|
||||
Button m_button;
|
||||
|
||||
public void SetKey(InputConfigPanel master, string name) {
|
||||
m_key.text = name;
|
||||
public void SetKey(InputConfigPanel master, Identifier name) {
|
||||
m_key.text = (string)name.Name;
|
||||
m_value.text = "None";
|
||||
m_button.onClick.AddListener(() => {
|
||||
master.OpenDialog(name);
|
||||
@@ -26,27 +27,18 @@ namespace Cryville.Crtr.Config {
|
||||
if (e.Used) {
|
||||
m_button.interactable = false;
|
||||
m_value.text = "(Not Required)";
|
||||
m_value.color = Color.black;
|
||||
}
|
||||
else {
|
||||
m_button.interactable = true;
|
||||
if (e.Proxy == null) {
|
||||
m_value.text = "(Unassigned)";
|
||||
m_value.color = Color.yellow;
|
||||
if (e.Required) m_value.text += " (Required)";
|
||||
}
|
||||
else {
|
||||
m_value.text = e.Proxy.Value.Handler.GetTypeName(e.Proxy.Value.Type);
|
||||
m_value.color = Color.black;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void SetValue(string name) {
|
||||
m_value.text = name;
|
||||
}
|
||||
|
||||
public void SetEnabled(bool flag) {
|
||||
m_button.interactable = flag;
|
||||
m_value.color = e.Required ? Color.yellow : Color.black;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
59
Assets/Cryville/Crtr/EffectGroup.cs
Normal file
59
Assets/Cryville/Crtr/EffectGroup.cs
Normal file
@@ -0,0 +1,59 @@
|
||||
using Cryville.Common.Buffers;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Cryville.Crtr {
|
||||
public class EffectGroup {
|
||||
public EffectDefinition Definition { get; private set; }
|
||||
readonly EffectPool _pool;
|
||||
class EffectPool : ObjectPool<EffectInstance> {
|
||||
readonly List<EffectInstance> _instances
|
||||
= new List<EffectInstance>();
|
||||
readonly EffectGroup _group;
|
||||
public EffectPool(EffectGroup group) : base(256) {
|
||||
_group = group;
|
||||
}
|
||||
protected override EffectInstance Construct() {
|
||||
var result = new EffectInstance(_group.Definition);
|
||||
_instances.Add(result);
|
||||
return result;
|
||||
}
|
||||
public void DisposeAll() {
|
||||
foreach (var i in _instances) i.Dispose();
|
||||
}
|
||||
}
|
||||
readonly Dictionary<float, EffectInstance> _instances
|
||||
= new Dictionary<float, EffectInstance>();
|
||||
readonly List<EffectInstance> _endQueue
|
||||
= new List<EffectInstance>();
|
||||
public EffectGroup(EffectDefinition def) {
|
||||
Definition = def;
|
||||
_pool = new EffectPool(this);
|
||||
}
|
||||
double _time;
|
||||
public void Tick(double time) {
|
||||
_time = time;
|
||||
while (_endQueue.Count > 0) {
|
||||
var item = _endQueue[0];
|
||||
if (item.EndTime > _time) break;
|
||||
item.OnDone();
|
||||
_instances.Remove(item.Index);
|
||||
_pool.Return(item);
|
||||
_endQueue.RemoveAt(0);
|
||||
}
|
||||
}
|
||||
public void Emit(float index) {
|
||||
EffectInstance instance;
|
||||
if (!_instances.TryGetValue(index, out instance)) {
|
||||
_instances.Add(index, instance = _pool.Rent());
|
||||
}
|
||||
instance.Index = index;
|
||||
instance.OnEmit(_time);
|
||||
var i = _endQueue.BinarySearch(instance);
|
||||
if (i < 0) i = ~i;
|
||||
_endQueue.Insert(i, instance);
|
||||
}
|
||||
public void Dispose() {
|
||||
_pool.DisposeAll();
|
||||
}
|
||||
}
|
||||
}
|
11
Assets/Cryville/Crtr/EffectGroup.cs.meta
Normal file
11
Assets/Cryville/Crtr/EffectGroup.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d0d27f9b4383b3445a2a27bfe94173a5
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
66
Assets/Cryville/Crtr/EffectInstance.cs
Normal file
66
Assets/Cryville/Crtr/EffectInstance.cs
Normal file
@@ -0,0 +1,66 @@
|
||||
using Cryville.Common;
|
||||
using Cryville.Crtr.Components;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Cryville.Crtr {
|
||||
public class EffectInstance : ISkinnableGroup, IComparable<EffectInstance> {
|
||||
readonly EffectDefinition _def;
|
||||
readonly SkinContainer _skinContainer;
|
||||
public Transform RootTransform { get; private set; }
|
||||
public EffectInstance(EffectDefinition def) {
|
||||
_def = def;
|
||||
_skinContainer = new SkinContainer(_def.elements);
|
||||
RootTransform = new GameObject("effect:" + GetHashCode().ToString(CultureInfo.InvariantCulture)).transform;
|
||||
SkinContext = new SkinContext(RootTransform);
|
||||
ChartPlayer.etor.ContextCascadeInsertBlock();
|
||||
_skinContainer.MatchStatic(this);
|
||||
ChartPlayer.etor.ContextCascadeDiscardBlock();
|
||||
foreach (var i in RootTransform.GetComponentsInChildren<SkinComponent>())
|
||||
i.Init();
|
||||
_indexSrc = new PropSrc.Float(() => Index);
|
||||
_durationOp = new PropOp.Float(v => _duration = v);
|
||||
}
|
||||
public float Index { get; set; }
|
||||
static readonly int _var_index = IdentifierManager.SharedInstance.Request("index");
|
||||
readonly PropSrc _indexSrc;
|
||||
double _startTime;
|
||||
float _duration;
|
||||
readonly PropOp _durationOp;
|
||||
public double EndTime { get { return _startTime + _duration; } }
|
||||
public void OnEmit(double time) {
|
||||
_startTime = time;
|
||||
RootTransform.gameObject.SetActive(true);
|
||||
ChartPlayer.etor.ContextCascadeInsert();
|
||||
ChartPlayer.etor.ContextCascadeUpdate(_var_index, _indexSrc);
|
||||
ChartPlayer.etor.Evaluate(_durationOp, _def.duration);
|
||||
_skinContainer.MatchDynamic(this, 0);
|
||||
ChartPlayer.etor.ContextCascadeDiscard();
|
||||
}
|
||||
public void OnDone() {
|
||||
RootTransform.gameObject.SetActive(false);
|
||||
}
|
||||
public void Dispose() {
|
||||
GameObject.Destroy(RootTransform.gameObject);
|
||||
}
|
||||
|
||||
public string TypeName { get { throw new InvalidOperationException("Type name undefined"); } }
|
||||
public SkinContext SkinContext { get; private set; }
|
||||
public Anchor OpenedAnchor { get { throw new InvalidOperationException("Anchor not supported"); } }
|
||||
public void PushAnchorEvent(double time, int name) {
|
||||
throw new InvalidOperationException("Anchor not supported");
|
||||
}
|
||||
public void RegisterAnchor(int name) {
|
||||
throw new InvalidOperationException("Anchor not supported");
|
||||
}
|
||||
public bool TryGetAnchorsByName(int name, out IReadOnlyCollection<Anchor> result) {
|
||||
throw new InvalidOperationException("Anchor not supported");
|
||||
}
|
||||
|
||||
public int CompareTo(EffectInstance other) {
|
||||
return EndTime.CompareTo(other.EndTime);
|
||||
}
|
||||
}
|
||||
}
|
11
Assets/Cryville/Crtr/EffectInstance.cs.meta
Normal file
11
Assets/Cryville/Crtr/EffectInstance.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f442db34239c47046ba1b6fdae8e1216
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
22
Assets/Cryville/Crtr/EffectManager.cs
Normal file
22
Assets/Cryville/Crtr/EffectManager.cs
Normal file
@@ -0,0 +1,22 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Cryville.Crtr {
|
||||
public class EffectManager {
|
||||
readonly Dictionary<int, EffectGroup> _groups
|
||||
= new Dictionary<int, EffectGroup>();
|
||||
public EffectManager(PdtSkin skin) {
|
||||
foreach (var e in skin.effects) {
|
||||
_groups.Add(e.Key.Key, new EffectGroup(e.Value));
|
||||
}
|
||||
}
|
||||
public void Tick(double time) {
|
||||
foreach (var g in _groups) g.Value.Tick(time);
|
||||
}
|
||||
public void Emit(int id, float index) {
|
||||
_groups[id].Emit(index);
|
||||
}
|
||||
public void Dispose() {
|
||||
foreach (var g in _groups) g.Value.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
11
Assets/Cryville/Crtr/EffectManager.cs.meta
Normal file
11
Assets/Cryville/Crtr/EffectManager.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 980c0f18a6f491d44a866a85910cb458
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -8,10 +8,9 @@ using System.Runtime.CompilerServices;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Cryville.Crtr.Event {
|
||||
public abstract class ContainerHandler {
|
||||
public abstract class ContainerHandler : ISkinnableGroup {
|
||||
#region Struct
|
||||
public ContainerHandler() { }
|
||||
public abstract string TypeName { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Prehandling <see cref="ContainerState"/>, prehandling the events.
|
||||
@@ -42,7 +41,6 @@ namespace Cryville.Crtr.Event {
|
||||
/// <see cref="GameObject"/> group, the <see cref="Transform"/> containing all the generated elements in the <see cref="ContainerHandler"/>.
|
||||
/// </summary>
|
||||
protected Transform gogroup;
|
||||
public SkinContext SkinContext;
|
||||
|
||||
public Vector3 Position { get; protected set; }
|
||||
public Quaternion Rotation { get; protected set; }
|
||||
@@ -72,14 +70,13 @@ namespace Cryville.Crtr.Event {
|
||||
SkinContainer skinContainer;
|
||||
protected Judge judge;
|
||||
public void AttachSystems(PdtSkin skin, Judge judge) {
|
||||
skinContainer = new SkinContainer(skin);
|
||||
skinContainer = new SkinContainer(skin.elements);
|
||||
this.judge = judge;
|
||||
}
|
||||
|
||||
public readonly Dictionary<int, List<Anchor>> Anchors = new Dictionary<int, List<Anchor>>();
|
||||
public readonly Dictionary<int, Anchor> DynamicAnchors = new Dictionary<int, Anchor>();
|
||||
public readonly Dictionary<int, bool> DynamicAnchorSet = new Dictionary<int, bool>();
|
||||
public Anchor OpenedAnchor;
|
||||
public readonly Dictionary<int, double> DynamicAnchorSetTime = new Dictionary<int, double>();
|
||||
Anchor a_cur;
|
||||
Anchor a_head;
|
||||
Anchor a_tail;
|
||||
@@ -97,7 +94,7 @@ namespace Cryville.Crtr.Event {
|
||||
if (DynamicAnchors.ContainsKey(name))
|
||||
throw new ArgumentException(string.Format("The anchor \"{0}\" already exists", strname));
|
||||
DynamicAnchors.Add(name, result);
|
||||
DynamicAnchorSet.Add(name, false);
|
||||
DynamicAnchorSetTime.Add(name, double.NaN);
|
||||
}
|
||||
List<Anchor> list;
|
||||
if (!Anchors.TryGetValue(name, out list))
|
||||
@@ -127,7 +124,11 @@ namespace Cryville.Crtr.Event {
|
||||
a_tail = RegisterAnchor(_a_tail, true);
|
||||
}
|
||||
public virtual void Init() {
|
||||
skinContainer.MatchStatic(ps);
|
||||
ChartPlayer.etor.ContextState = ps;
|
||||
ChartPlayer.etor.ContextEvent = Container;
|
||||
skinContainer.MatchStatic(this);
|
||||
ChartPlayer.etor.ContextEvent = null;
|
||||
ChartPlayer.etor.ContextState = null;
|
||||
foreach (var i in gogroup.GetComponentsInChildren<SkinComponent>())
|
||||
i.Init();
|
||||
}
|
||||
@@ -143,8 +144,8 @@ namespace Cryville.Crtr.Event {
|
||||
else if (s.CloneType == 17) Init();
|
||||
}
|
||||
public virtual void StartLogicalUpdate(ContainerState s) { }
|
||||
public virtual void StartPreGraphicalUpdate(ContainerState s) { }
|
||||
public virtual void StartGraphicalUpdate(ContainerState s) {
|
||||
protected virtual void StartPreGraphicalUpdate(ContainerState s) { }
|
||||
protected virtual void StartGraphicalUpdate(ContainerState s) {
|
||||
if (gogroup) gogroup.gameObject.SetActive(true);
|
||||
}
|
||||
#endregion
|
||||
@@ -160,7 +161,7 @@ namespace Cryville.Crtr.Event {
|
||||
tev.Target.Transform.position = Position;
|
||||
tev.Target.Transform.rotation = Rotation;
|
||||
#endif
|
||||
skinContainer.MatchDynamic(s);
|
||||
MatchDynamic(s, 1);
|
||||
CloseAnchor();
|
||||
}
|
||||
if (tev.Target == a_head) {
|
||||
@@ -171,11 +172,11 @@ namespace Cryville.Crtr.Event {
|
||||
}
|
||||
anchorEvPool.Return(tev);
|
||||
}
|
||||
else if (gogroup && s.CloneType == 2) skinContainer.MatchDynamic(s);
|
||||
else if (gogroup && s.CloneType == 2) MatchDynamic(s, 1);
|
||||
}
|
||||
#region End methods
|
||||
public virtual void EndGraphicalUpdate(ContainerState s) { }
|
||||
public virtual void EndPreGraphicalUpdate(ContainerState s) { }
|
||||
protected virtual void EndGraphicalUpdate(ContainerState s) { }
|
||||
protected virtual void EndPreGraphicalUpdate(ContainerState s) { }
|
||||
public virtual void EndLogicalUpdate(ContainerState s) { }
|
||||
public virtual void EndPhysicalUpdate(ContainerState s) { }
|
||||
public virtual void Dispose() {
|
||||
@@ -185,38 +186,41 @@ namespace Cryville.Crtr.Event {
|
||||
}
|
||||
public virtual void DisposeAll() { }
|
||||
#endregion
|
||||
#region Utils
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
protected static bool CanDoGraphicalUpdate(ContainerState s) { return s.CloneType >= 2 && s.CloneType < 16; }
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
void MatchDynamic(ContainerState s, int dl) {
|
||||
ChartPlayer.etor.ContextState = s;
|
||||
ChartPlayer.etor.ContextEvent = Container;
|
||||
skinContainer.MatchDynamic(this, dl);
|
||||
ChartPlayer.etor.ContextEvent = null;
|
||||
ChartPlayer.etor.ContextState = null;
|
||||
}
|
||||
#endregion
|
||||
#region Anchor
|
||||
public virtual void Anchor() {
|
||||
foreach (var p in PropSrcs.Values) p.Invalidate();
|
||||
foreach (var a in DynamicAnchors.Keys) DynamicAnchorSet[a] = false;
|
||||
foreach (var p in PropSrcs) p.Value.Invalidate();
|
||||
foreach (var a in DynamicAnchors) DynamicAnchorSetTime[a.Key] = double.NaN;
|
||||
atime_head = cs.StampedContainer.Time;
|
||||
atime_tail = atime_head + cs.StampedContainer.Duration;
|
||||
skinContainer.MatchDynamic(cs);
|
||||
MatchDynamic(cs, 0);
|
||||
if (cs.Active) PushAnchorEvent(cs.Time, a_cur);
|
||||
if (Alive) {
|
||||
if (!DynamicAnchorSet[_a_head]) PushAnchorEvent(atime_head, a_head, -1, true);
|
||||
if (!DynamicAnchorSet[_a_tail]) PushAnchorEvent(atime_tail, a_tail, 1, true);
|
||||
foreach (var anchors in Anchors.Values) foreach (var anchor in anchors) anchor.Transform.gameObject.SetActive(false);
|
||||
if (double.IsNaN(DynamicAnchorSetTime[_a_head])) DynamicAnchorSetTime[_a_head] = atime_head;
|
||||
if (double.IsNaN(DynamicAnchorSetTime[_a_tail])) DynamicAnchorSetTime[_a_tail] = atime_tail;
|
||||
foreach (var t in DynamicAnchorSetTime) {
|
||||
if (double.IsNaN(t.Value)) continue;
|
||||
int priority = 0;
|
||||
bool forced = true;
|
||||
if (t.Key == _a_head) { priority = -1; }
|
||||
else if (t.Key == _a_tail) { priority = 1; }
|
||||
else forced = false;
|
||||
PushAnchorEvent(t.Value, DynamicAnchors[t.Key], priority, forced);
|
||||
}
|
||||
foreach (var anchors in Anchors) foreach (var anchor in anchors.Value) anchor.Transform.gameObject.SetActive(false);
|
||||
}
|
||||
static readonly SimpleObjectPool<StampedEvent.Anchor> anchorEvPool
|
||||
= new SimpleObjectPool<StampedEvent.Anchor>(1024);
|
||||
public void PushAnchorEvent(double time, int name) {
|
||||
Anchor anchor;
|
||||
if (!DynamicAnchors.TryGetValue(name, out anchor))
|
||||
throw new ArgumentException(string.Format("Specified anchor \"{0}\" not found", IdentifierManager.SharedInstance.Retrieve(name)));
|
||||
if (DynamicAnchorSet[name])
|
||||
throw new InvalidOperationException(string.Format("Specified anchor \"{0}\" has been set", IdentifierManager.SharedInstance.Retrieve(name)));
|
||||
int priority = 0;
|
||||
bool forced = true;
|
||||
if (name == _a_head) { priority = -1; atime_head = time; }
|
||||
else if (name == _a_tail) { priority = 1; atime_tail = time; }
|
||||
else forced = false;
|
||||
PushAnchorEvent(time, anchor, priority, forced);
|
||||
DynamicAnchorSet[name] = true;
|
||||
}
|
||||
void PushAnchorEvent(double time, Anchor anchor, int priority = 0, bool forced = false) {
|
||||
var tev = anchorEvPool.Rent();
|
||||
tev.Time = time;
|
||||
@@ -233,5 +237,27 @@ namespace Cryville.Crtr.Event {
|
||||
}
|
||||
#endregion
|
||||
#endregion
|
||||
|
||||
#region ISkinnableGroup
|
||||
public abstract string TypeName { get; }
|
||||
public SkinContext SkinContext { get; private set; }
|
||||
public Anchor OpenedAnchor { get; private set; }
|
||||
public bool TryGetAnchorsByName(int name, out IReadOnlyCollection<Anchor> result) {
|
||||
List<Anchor> anchors;
|
||||
var ret = Anchors.TryGetValue(name, out anchors);
|
||||
result = anchors;
|
||||
return ret;
|
||||
}
|
||||
void ISkinnableGroup.RegisterAnchor(int name) {
|
||||
RegisterAnchor(name, true);
|
||||
}
|
||||
public void PushAnchorEvent(double time, int name) {
|
||||
if (!DynamicAnchors.ContainsKey(name))
|
||||
throw new ArgumentException(string.Format("Specified anchor \"{0}\" not found", IdentifierManager.SharedInstance.Retrieve(name)));
|
||||
if (name == _a_head) atime_head = time;
|
||||
else if (name == _a_tail) atime_tail = time;
|
||||
DynamicAnchorSetTime[name] = time;
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
@@ -434,14 +434,14 @@ namespace Cryville.Crtr.Event {
|
||||
|
||||
public void BroadcastPreInit() {
|
||||
Handler.PreInit();
|
||||
foreach (var c in Children.Values) {
|
||||
c.BroadcastPreInit();
|
||||
foreach (var c in Children) {
|
||||
c.Value.BroadcastPreInit();
|
||||
}
|
||||
}
|
||||
public void BroadcastPostInit() {
|
||||
Handler.PostInit();
|
||||
foreach (var c in Children.Values) {
|
||||
c.BroadcastPostInit();
|
||||
foreach (var c in Children) {
|
||||
c.Value.BroadcastPostInit();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -461,8 +461,8 @@ namespace Cryville.Crtr.Event {
|
||||
|
||||
public void Anchor() {
|
||||
Handler.Anchor();
|
||||
foreach (var ls in Children.Values) {
|
||||
if (ls.Handler.Alive) ls.Anchor();
|
||||
foreach (var ls in Children) {
|
||||
if (ls.Value.Handler.Alive) ls.Value.Anchor();
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
@@ -63,8 +63,8 @@ namespace Cryville.Crtr.Event {
|
||||
s = RootState;
|
||||
}
|
||||
AddState(s);
|
||||
foreach (var c in s.Children.Values)
|
||||
Expand(c);
|
||||
foreach (var c in s.Children)
|
||||
Expand(c.Value);
|
||||
}
|
||||
|
||||
public void AddState(ContainerState s) {
|
||||
@@ -73,13 +73,13 @@ namespace Cryville.Crtr.Event {
|
||||
}
|
||||
|
||||
void AttachBus() {
|
||||
foreach (var s in states.Values)
|
||||
s.Bus = this;
|
||||
foreach (var s in states)
|
||||
s.Value.Bus = this;
|
||||
}
|
||||
|
||||
public void AttachSystems(PdtSkin skin, Judge judge) {
|
||||
foreach (var s in states.Values)
|
||||
s.AttachSystems(skin, judge);
|
||||
foreach (var s in states)
|
||||
s.Value.AttachSystems(skin, judge);
|
||||
}
|
||||
|
||||
List<StampedEvent.Temporary> tempEvents = new List<StampedEvent.Temporary>();
|
||||
|
@@ -14,7 +14,7 @@ namespace Cryville.Crtr.Event {
|
||||
internal class MotionCachePool : CategorizedPool<Identifier, MotionCache> {
|
||||
private class Bucket : ObjectPool<MotionCache> {
|
||||
readonly MotionRegistry _reg;
|
||||
public Bucket(string name, int capacity) : base(capacity) {
|
||||
public Bucket(Identifier name, int capacity) : base(capacity) {
|
||||
_reg = ChartPlayer.motionRegistry[name];
|
||||
}
|
||||
protected override MotionCache Construct() {
|
||||
|
@@ -6,7 +6,7 @@ namespace Cryville.Crtr.Event {
|
||||
internal class RMVPool : CategorizedPool<Identifier, RealtimeMotionValue> {
|
||||
private class Bucket : ObjectPool<RealtimeMotionValue> {
|
||||
readonly MotionRegistry _reg;
|
||||
public Bucket(string name, int capacity) : base(capacity) {
|
||||
public Bucket(Identifier name, int capacity) : base(capacity) {
|
||||
_reg = ChartPlayer.motionRegistry[name];
|
||||
}
|
||||
protected override RealtimeMotionValue Construct() {
|
||||
|
@@ -104,16 +104,16 @@ namespace Cryville.Crtr {
|
||||
}
|
||||
|
||||
ChartPlayer.motionRegistry = new Dictionary<Identifier, MotionRegistry> {
|
||||
{ "pt" , new MotionRegistry(typeof(VecPt)) },
|
||||
{ "dir" , new MotionRegistry(typeof(Vec3)) },
|
||||
{ "normal" , new MotionRegistry(typeof(Vec3)) },
|
||||
{ "sv" , new MotionRegistry(new VecPtComp(0f, 0f), new VecPtComp(0f, 1f)) },
|
||||
{ "svm" , new MotionRegistry(new Vec1m(1f)) },
|
||||
{ "dist" , new MotionRegistry(new VecPtComp(0f, 0f), new VecPtComp(0f, float.PositiveInfinity)) },
|
||||
{ "corner" , new MotionRegistry(typeof(VecI1)) },
|
||||
{ "ctrl0" , new MotionRegistry(typeof(VecCtrl)) },
|
||||
{ "ctrl1" , new MotionRegistry(typeof(VecCtrl)) },
|
||||
{ "track" , new MotionRegistry(typeof(Vec1)) },
|
||||
{ new Identifier("pt") , new MotionRegistry(typeof(VecPt)) },
|
||||
{ new Identifier("dir") , new MotionRegistry(typeof(Vec3)) },
|
||||
{ new Identifier("normal") , new MotionRegistry(typeof(Vec3)) },
|
||||
{ new Identifier("sv") , new MotionRegistry(new VecPtComp(0f, 0f), new VecPtComp(0f, 1f)) },
|
||||
{ new Identifier("svm") , new MotionRegistry(new Vec1m(1f)) },
|
||||
{ new Identifier("dist") , new MotionRegistry(new VecPtComp(0f, 0f), new VecPtComp(0f, float.PositiveInfinity)) },
|
||||
{ new Identifier("corner") , new MotionRegistry(typeof(VecI1)) },
|
||||
{ new Identifier("ctrl0") , new MotionRegistry(typeof(VecCtrl)) },
|
||||
{ new Identifier("ctrl1") , new MotionRegistry(typeof(VecCtrl)) },
|
||||
{ new Identifier("track") , new MotionRegistry(typeof(Vec1)) },
|
||||
};
|
||||
|
||||
var dir = new DirectoryInfo(Settings.Default.GameDataPath + "/charts");
|
||||
|
@@ -18,6 +18,7 @@ namespace Cryville.Crtr {
|
||||
|
||||
public static void LoadDefault() {
|
||||
if (loaded) return;
|
||||
Components.Add("anim", typeof(SkinAnimation));
|
||||
Components.Add("image", typeof(SpritePlane));
|
||||
Components.Add("mesh", typeof(MeshBase));
|
||||
Components.Add("polysec", typeof(PolygonSGO));
|
||||
|
@@ -23,7 +23,7 @@ namespace Cryville.Crtr {
|
||||
_judge = judge;
|
||||
foreach (var i in ruleset.inputs) {
|
||||
_use.Add(i.Key, 0);
|
||||
_rev.Add(i.Key, new List<string>());
|
||||
_rev.Add(i.Key, new List<Identifier>());
|
||||
}
|
||||
foreach (var i in ruleset.inputs) {
|
||||
if (i.Value.pass != null) {
|
||||
@@ -33,15 +33,15 @@ namespace Cryville.Crtr {
|
||||
}
|
||||
}
|
||||
#region Settings
|
||||
readonly Dictionary<string, InputProxyEntry> _tproxies = new Dictionary<string, InputProxyEntry>();
|
||||
readonly Dictionary<Identifier, InputProxyEntry> _tproxies = new Dictionary<Identifier, InputProxyEntry>();
|
||||
readonly Dictionary<InputSource, InputProxyEntry> _sproxies = new Dictionary<InputSource, InputProxyEntry>();
|
||||
readonly Dictionary<string, int> _use = new Dictionary<string, int>();
|
||||
readonly Dictionary<string, List<string>> _rev = new Dictionary<string, List<string>>();
|
||||
readonly Dictionary<Identifier, int> _use = new Dictionary<Identifier, int>();
|
||||
readonly Dictionary<Identifier, List<Identifier>> _rev = new Dictionary<Identifier, List<Identifier>>();
|
||||
public event EventHandler<ProxyChangedEventArgs> ProxyChanged;
|
||||
public void LoadFrom(Dictionary<string, RulesetConfig.InputEntry> config) {
|
||||
foreach (var cfg in config) {
|
||||
Set(new InputProxyEntry {
|
||||
Target = cfg.Key,
|
||||
Target = new Identifier(cfg.Key),
|
||||
Source = new InputSource {
|
||||
Handler = Game.InputManager.GetHandler(cfg.Value.handler),
|
||||
Type = cfg.Value.type
|
||||
@@ -52,7 +52,7 @@ namespace Cryville.Crtr {
|
||||
public void SaveTo(Dictionary<string, RulesetConfig.InputEntry> config) {
|
||||
config.Clear();
|
||||
foreach (var p in _tproxies) {
|
||||
config.Add(p.Key, new RulesetConfig.InputEntry {
|
||||
config.Add((string)p.Key.Name, new RulesetConfig.InputEntry {
|
||||
handler = ReflectionHelper.GetNamespaceQualifiedName(p.Value.Source.Value.Handler.GetType()),
|
||||
type = p.Value.Source.Value.Type
|
||||
});
|
||||
@@ -81,14 +81,16 @@ namespace Cryville.Crtr {
|
||||
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;
|
||||
}
|
||||
public bool IsCompleted() {
|
||||
foreach (var i in _use)
|
||||
if (!IsCompleted(i.Key)) return false;
|
||||
return true;
|
||||
}
|
||||
void IncrementUseRecursive(string name) {
|
||||
bool IsCompleted(Identifier name) {
|
||||
return name.Key == _var_pause || _use[name] != 0 || _tproxies.ContainsKey(name);
|
||||
}
|
||||
static readonly int _var_pause = IdentifierManager.SharedInstance.Request("pause");
|
||||
void IncrementUseRecursive(Identifier name) {
|
||||
BroadcastProxyChanged(name);
|
||||
var passes = _ruleset.inputs[name].pass;
|
||||
if (passes != null) {
|
||||
@@ -98,14 +100,14 @@ namespace Cryville.Crtr {
|
||||
}
|
||||
}
|
||||
}
|
||||
void IncrementReversedUseRecursive(string name) {
|
||||
void IncrementReversedUseRecursive(Identifier name) {
|
||||
foreach (var p in _rev[name]) {
|
||||
_use[p]++;
|
||||
BroadcastProxyChanged(p);
|
||||
IncrementReversedUseRecursive(p);
|
||||
}
|
||||
}
|
||||
void DecrementUseRecursive(string name) {
|
||||
void DecrementUseRecursive(Identifier name) {
|
||||
BroadcastProxyChanged(name);
|
||||
var passes = _ruleset.inputs[name].pass;
|
||||
if (passes != null) {
|
||||
@@ -115,20 +117,20 @@ namespace Cryville.Crtr {
|
||||
}
|
||||
}
|
||||
}
|
||||
void DecrementReversedUseRecursive(string name) {
|
||||
void DecrementReversedUseRecursive(Identifier name) {
|
||||
foreach (var p in _rev[name]) {
|
||||
_use[p]--;
|
||||
BroadcastProxyChanged(p);
|
||||
DecrementReversedUseRecursive(p);
|
||||
}
|
||||
}
|
||||
void BroadcastProxyChanged(string name) {
|
||||
void BroadcastProxyChanged(Identifier name) {
|
||||
var del = ProxyChanged;
|
||||
if (del != null) del(this, this[name]);
|
||||
}
|
||||
public ProxyChangedEventArgs this[string name] {
|
||||
public ProxyChangedEventArgs this[Identifier name] {
|
||||
get {
|
||||
return new ProxyChangedEventArgs(name, _tproxies.ContainsKey(name) ? _tproxies[name].Source : null, _use[name] > 0);
|
||||
return new ProxyChangedEventArgs(name, _tproxies.ContainsKey(name) ? _tproxies[name].Source : null, _use[name] > 0, !IsCompleted(name));
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
@@ -164,8 +166,8 @@ namespace Cryville.Crtr {
|
||||
protected void Dispose(bool disposing) {
|
||||
if (disposing) {
|
||||
Deactivate();
|
||||
foreach (var proxy in _tproxies.Values) {
|
||||
proxy.Source.Value.Handler.OnInput -= OnInput;
|
||||
foreach (var proxy in _tproxies) {
|
||||
proxy.Value.Source.Value.Handler.OnInput -= OnInput;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -236,13 +238,14 @@ namespace Cryville.Crtr {
|
||||
}
|
||||
}
|
||||
public void SyncTime(double time) {
|
||||
foreach (var s in _sproxies.Keys) {
|
||||
var h = s.Handler;
|
||||
foreach (var s in _sproxies) {
|
||||
var h = s.Key.Handler;
|
||||
_timeOrigins[h] = h.GetCurrentTimestamp() - time;
|
||||
}
|
||||
}
|
||||
public void ForceTick() {
|
||||
foreach (var src in _sproxies.Keys) {
|
||||
foreach (var s in _sproxies) {
|
||||
var src = s.Key;
|
||||
if (_activeCounts[src] == 0) {
|
||||
OnInput(new InputIdentifier { Source = src, Id = 0 }, new InputVector(_lockTime != null ? _lockTime.Value : src.Handler.GetCurrentTimestamp()));
|
||||
}
|
||||
@@ -250,7 +253,8 @@ namespace Cryville.Crtr {
|
||||
}
|
||||
public double GetTimestampAverage() {
|
||||
double result = 0;
|
||||
foreach (var src in _sproxies.Keys) {
|
||||
foreach (var s in _sproxies) {
|
||||
var src = s.Key;
|
||||
result += src.Handler.GetCurrentTimestamp() - _timeOrigins[src.Handler];
|
||||
}
|
||||
return result / _sproxies.Count;
|
||||
@@ -261,19 +265,21 @@ namespace Cryville.Crtr {
|
||||
}
|
||||
|
||||
public class ProxyChangedEventArgs : EventArgs {
|
||||
public string Name { get; private set; }
|
||||
public Identifier Name { get; private set; }
|
||||
public InputSource? Proxy { get; private set; }
|
||||
public bool Used { get; private set; }
|
||||
public ProxyChangedEventArgs(string name, InputSource? src, bool used) {
|
||||
public bool Required { get; private set; }
|
||||
public ProxyChangedEventArgs(Identifier name, InputSource? src, bool used, bool required) {
|
||||
Name = name;
|
||||
Proxy = src;
|
||||
Used = used;
|
||||
Required = required;
|
||||
}
|
||||
}
|
||||
|
||||
public class InputProxyEntry {
|
||||
public InputSource? Source { get; set; }
|
||||
public string Target { get; set; }
|
||||
public Identifier Target { get; set; }
|
||||
public byte[] Mapping { get; private set; }
|
||||
}
|
||||
|
||||
|
@@ -42,11 +42,12 @@ namespace Cryville.Crtr {
|
||||
_numsrc3 = new PropSrc.Float(() => _numbuf3);
|
||||
_numsrc4 = new PropSrc.Float(() => _numbuf4);
|
||||
_rs.judges.TryGetValue(new Identifier(_var_pause), out _judgePause);
|
||||
foreach (var i in rs.inputs.Keys) {
|
||||
foreach (var i in rs.inputs) {
|
||||
var id = i.Key;
|
||||
var l = new List<JudgeEvent>();
|
||||
evs.Add(i, l);
|
||||
activeEvs.Add(i, new List<JudgeEvent>());
|
||||
if (_judgePause != null && i.Key == _var_pause) {
|
||||
evs.Add(id, l);
|
||||
activeEvs.Add(id, new List<JudgeEvent>());
|
||||
if (_judgePause != null && id.Key == _var_pause) {
|
||||
l.Add(new JudgeEvent {
|
||||
StartTime = double.NegativeInfinity, EndTime = double.PositiveInfinity,
|
||||
StartClip = double.NegativeInfinity, EndClip = double.PositiveInfinity,
|
||||
@@ -82,8 +83,9 @@ namespace Cryville.Crtr {
|
||||
#region Judge
|
||||
internal readonly Dictionary<int, int> judgeMap = new Dictionary<int, int>();
|
||||
void InitJudges() {
|
||||
foreach (var i in _rs.judges.Keys) {
|
||||
judgeMap.Add(i.Key, IdentifierManager.SharedInstance.Request("judge_" + i.Name));
|
||||
foreach (var i in _rs.judges) {
|
||||
var id = i.Key;
|
||||
judgeMap.Add(id.Key, IdentifierManager.SharedInstance.Request("judge_" + id.Name));
|
||||
}
|
||||
}
|
||||
static bool _flag;
|
||||
@@ -247,9 +249,10 @@ namespace Cryville.Crtr {
|
||||
public TargetString GetFullFormattedScoreString() {
|
||||
bool flag = false;
|
||||
scoreFullBuf.Clear();
|
||||
foreach (var s in scores.Keys) {
|
||||
scoreFullBuf.AppendFormat(flag ? "\n{0}: " : "{0}: ", (string)IdentifierManager.SharedInstance.Retrieve(s));
|
||||
scoreFullBuf.AppendFormat(scoreFormatCache[s], scores[s]);
|
||||
foreach (var s in scores) {
|
||||
var id = s.Key;
|
||||
scoreFullBuf.AppendFormat(flag ? "\n{0}: " : "{0}: ", (string)IdentifierManager.SharedInstance.Retrieve(id));
|
||||
scoreFullBuf.AppendFormat(scoreFormatCache[id], scores[id]);
|
||||
flag = true;
|
||||
}
|
||||
scoreFullStr.Length = scoreFullBuf.Count;
|
||||
|
@@ -26,10 +26,8 @@ namespace Cryville.Crtr {
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
public Material NewMaterial {
|
||||
get {
|
||||
return Material.Instantiate(GenericResources.Materials["-SpriteMat"]);
|
||||
}
|
||||
public static Material NewMaterial() {
|
||||
return Material.Instantiate(GenericResources.Materials["-SpriteMat"]);
|
||||
}
|
||||
public void Init(Transform parent) {
|
||||
MeshObject = new GameObject("__mesh__");
|
||||
@@ -41,12 +39,10 @@ namespace Cryville.Crtr {
|
||||
MeshObject.AddComponent<MeshRenderer>();
|
||||
MeshFilter = MeshObject.GetComponent<MeshFilter>();
|
||||
Renderer = MeshObject.GetComponent<Renderer>();
|
||||
Renderer.material = NewMaterial;
|
||||
Initialized = true;
|
||||
}
|
||||
public void Destroy() {
|
||||
Mesh.Destroy(Mesh);
|
||||
if (Renderer.material != null) Material.Destroy(Renderer.material);
|
||||
GameObject.Destroy(MeshObject);
|
||||
}
|
||||
}
|
||||
|
@@ -58,7 +58,7 @@ namespace Cryville.Crtr {
|
||||
public override void Init() {
|
||||
base.Init();
|
||||
sgos = gogroup.GetComponentsInChildren<SectionalGameObject>();
|
||||
foreach (var judge in judges.Values) judge.InitPropSrcs();
|
||||
foreach (var judge in judges) judge.Value.InitPropSrcs();
|
||||
}
|
||||
|
||||
public override void StartPhysicalUpdate(ContainerState s) {
|
||||
@@ -67,7 +67,7 @@ namespace Cryville.Crtr {
|
||||
TransformAwake(s);
|
||||
}
|
||||
}
|
||||
public override void StartGraphicalUpdate(ContainerState s) {
|
||||
protected override void StartGraphicalUpdate(ContainerState s) {
|
||||
base.StartGraphicalUpdate(s);
|
||||
TransformAwake(s);
|
||||
if (gogroup) {
|
||||
@@ -127,7 +127,7 @@ namespace Cryville.Crtr {
|
||||
else base.Update(s, ev);
|
||||
}
|
||||
|
||||
public override void EndGraphicalUpdate(ContainerState s) {
|
||||
protected override void EndGraphicalUpdate(ContainerState s) {
|
||||
if (gogroup) {
|
||||
foreach (var i in sgos) i.Seal();
|
||||
}
|
||||
|
91
Assets/Cryville/Crtr/PdtBinder.cs
Normal file
91
Assets/Cryville/Crtr/PdtBinder.cs
Normal file
@@ -0,0 +1,91 @@
|
||||
using Cryville.Common;
|
||||
using Cryville.Common.Pdt;
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Text.RegularExpressions;
|
||||
using SIdentifier = Cryville.Common.Identifier;
|
||||
|
||||
namespace Cryville.Crtr {
|
||||
public class PdtBinder : EmptyBinder {
|
||||
public override object ChangeType(object value, Type type, CultureInfo culture) {
|
||||
if (value is PdtExpression) {
|
||||
var exp = (PdtExpression)value;
|
||||
if (type.Equals(typeof(bool))) {
|
||||
bool result = false;
|
||||
ChartPlayer.etor.Evaluate(new PropOp.Boolean(r => result = r), exp);
|
||||
return result;
|
||||
}
|
||||
else if (type.Equals(typeof(int))) {
|
||||
int result = 0;
|
||||
ChartPlayer.etor.Evaluate(new PropOp.Integer(r => result = r), exp);
|
||||
return result;
|
||||
}
|
||||
else if (type.Equals(typeof(float))) {
|
||||
float result = 0;
|
||||
ChartPlayer.etor.Evaluate(new PropOp.Float(r => result = r), exp);
|
||||
return result;
|
||||
}
|
||||
else if (type.Equals(typeof(string))) {
|
||||
string result = default(string);
|
||||
ChartPlayer.etor.Evaluate(new PropOp.String(r => result = r), exp);
|
||||
return result;
|
||||
}
|
||||
else if (type.Equals(typeof(Clip))) {
|
||||
Clip result = default(Clip);
|
||||
ChartPlayer.etor.Evaluate(new PropOp.Clip(r => result = r), exp);
|
||||
return result;
|
||||
}
|
||||
else if (type.Equals(typeof(Identifier))) {
|
||||
Identifier result = default(Identifier);
|
||||
ChartPlayer.etor.Evaluate(new pop_identstr(r => result = r), exp);
|
||||
return result;
|
||||
}
|
||||
else if (type.Equals(typeof(Identifier[]))) {
|
||||
Identifier[] result = null;
|
||||
ChartPlayer.etor.Evaluate(new pop_identstrarr(r => result = r), exp);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
else if (value is string) {
|
||||
var exp = (string)value;
|
||||
if (type.Equals(typeof(Identifier))) {
|
||||
return new Identifier(exp);
|
||||
}
|
||||
else if (type == typeof(ScoreOperation)) {
|
||||
var m = Regex.Match(exp, @"^(\S+)\s*?(\S+)?$");
|
||||
var name = new Identifier(m.Groups[1].Value);
|
||||
if (!m.Groups[2].Success) return new ScoreOperation { name = name };
|
||||
var op = new Identifier(m.Groups[2].Value);
|
||||
return new ScoreOperation { name = name, op = op };
|
||||
}
|
||||
}
|
||||
return base.ChangeType(value, type, culture);
|
||||
}
|
||||
#pragma warning disable IDE1006
|
||||
class pop_identstr : PropOp {
|
||||
readonly Action<SIdentifier> _cb;
|
||||
public pop_identstr(Action<SIdentifier> cb) { _cb = cb; }
|
||||
protected override void Execute() {
|
||||
var op = GetOperand(0);
|
||||
if (op.Type == PdtInternalType.Undefined) _cb(new SIdentifier(op.AsIdentifier()));
|
||||
else if (op.Type == PdtInternalType.String) _cb(new SIdentifier(op.AsString()));
|
||||
else throw new InvalidCastException("Not an identifier or string");
|
||||
}
|
||||
}
|
||||
class pop_identstrarr : PdtOperator {
|
||||
readonly Action<SIdentifier[]> _cb;
|
||||
public pop_identstrarr(Action<SIdentifier[]> cb) : base(16) { _cb = cb; }
|
||||
protected override void Execute() {
|
||||
var result = new SIdentifier[LoadedOperandCount];
|
||||
for (int i = 0; i < LoadedOperandCount; i++) {
|
||||
var op = GetOperand(i);
|
||||
if (op.Type != PdtInternalType.Undefined)
|
||||
throw new InvalidCastException("Not an identifier");
|
||||
result[i] = new SIdentifier(op.AsIdentifier());
|
||||
}
|
||||
_cb(result);
|
||||
}
|
||||
}
|
||||
#pragma warning restore IDE1006
|
||||
}
|
||||
}
|
11
Assets/Cryville/Crtr/PdtBinder.cs.meta
Normal file
11
Assets/Cryville/Crtr/PdtBinder.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7ba16fc9fce48644b9c7bd49f2c9121d
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -104,6 +104,13 @@ namespace Cryville.Crtr {
|
||||
public Judge ContextJudge { private get; set; }
|
||||
public PropSrc ContextSelfValue { private get; set; }
|
||||
|
||||
readonly Stack<int> ContextCascadeBlocks = new Stack<int>();
|
||||
public void ContextCascadeInsertBlock() {
|
||||
ContextCascadeBlocks.Push(_cascadeHeight);
|
||||
}
|
||||
public void ContextCascadeDiscardBlock() {
|
||||
ContextCascadeBlocks.Pop();
|
||||
}
|
||||
readonly Dictionary<int, PropSrc>[] ContextCascade = new Dictionary<int, PropSrc>[256];
|
||||
int _cascadeHeight;
|
||||
public void ContextCascadeInsert() {
|
||||
@@ -118,7 +125,7 @@ namespace Cryville.Crtr {
|
||||
}
|
||||
public PropSrc ContextCascadeLookup(int name) {
|
||||
PropSrc result;
|
||||
for (int i = _cascadeHeight - 1; i >= 0; i--) {
|
||||
for (int i = _cascadeHeight - 1; i >= ContextCascadeBlocks.Peek(); i--) {
|
||||
Dictionary<int, PropSrc> cas = ContextCascade[i];
|
||||
if (cas.TryGetValue(name, out result)) {
|
||||
return result;
|
||||
@@ -131,6 +138,7 @@ namespace Cryville.Crtr {
|
||||
}
|
||||
|
||||
public PdtEvaluator() {
|
||||
ContextCascadeBlocks.Push(0);
|
||||
for (int i = 0; i < ContextCascade.Length; i++) ContextCascade[i] = new Dictionary<int, PropSrc>();
|
||||
|
||||
_ctxops.Add(IdentifierManager.SharedInstance.Request("screen_edge"), new func_screen_edge(() => ContextTransform));
|
||||
|
@@ -60,6 +60,24 @@ namespace Cryville.Crtr {
|
||||
_cb(GetOperand(0).AsString());
|
||||
}
|
||||
}
|
||||
public class StringArray : PropOp {
|
||||
readonly Action<string[]> _cb;
|
||||
public StringArray(Action<string[]> cb) { _cb = cb; }
|
||||
protected unsafe override void Execute() {
|
||||
var op = GetOperand(0);
|
||||
int arrtype; int len;
|
||||
op.GetArraySuffix(out arrtype, out len);
|
||||
if (arrtype != PdtInternalType.String) throw new InvalidCastException("Not an array of strings");
|
||||
var result = new string[len];
|
||||
int o = 0;
|
||||
for (int i = 0; i < len; i++) {
|
||||
string v = op.AsString(o);
|
||||
o += v.Length * sizeof(char) + sizeof(int);
|
||||
result[i] = v;
|
||||
}
|
||||
_cb(result);
|
||||
}
|
||||
}
|
||||
public class TargetString : PropOp {
|
||||
readonly Func<RTargetString> _cb;
|
||||
public TargetString(Func<RTargetString> cb) { _cb = cb; }
|
||||
|
@@ -43,6 +43,7 @@ namespace Cryville.Crtr {
|
||||
buf[0] = _cb() ? (byte)1 : (byte)0;
|
||||
}
|
||||
}
|
||||
public static readonly PropSrc Error = new Arbitrary(PdtInternalType.Error, new byte[0]);
|
||||
public class Float : FixedBuffer {
|
||||
readonly Func<float> _cb;
|
||||
public Float(Func<float> cb) : base(PdtInternalType.Number, 4) { _cb = cb; }
|
||||
|
@@ -4,11 +4,8 @@ using Cryville.Crtr.Browsing;
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using SIdentifier = Cryville.Common.Identifier;
|
||||
|
||||
namespace Cryville.Crtr {
|
||||
public class Ruleset : MetaInfo {
|
||||
@@ -25,35 +22,38 @@ namespace Cryville.Crtr {
|
||||
public void LoadPdt(DirectoryInfo dir) {
|
||||
using (StreamReader pdtreader = new StreamReader(dir.FullName + "/" + data + ".pdt", Encoding.UTF8)) {
|
||||
var src = pdtreader.ReadToEnd();
|
||||
Root = (PdtRuleset)new RulesetInterpreter(src, null).Interpret();
|
||||
Root = (PdtRuleset)new RulesetInterpreter(src, null).Interpret(typeof(PdtRuleset));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Binder(typeof(PdtRulesetBinder))]
|
||||
[Binder(typeof(PdtBinder))]
|
||||
public class PdtRuleset {
|
||||
public Dictionary<Identifier, InputDefinition> inputs;
|
||||
public Dictionary<Identifier, JudgeDefinition> judges;
|
||||
public Dictionary<Identifier, ScoreDefinition> scores;
|
||||
public Constraint constraints;
|
||||
public void Optimize(PdtEvaluatorBase etor) {
|
||||
foreach (var i in inputs.Values) {
|
||||
if (i.pass != null) foreach (var e in i.pass.Values) {
|
||||
etor.Optimize(e);
|
||||
foreach (var i in inputs) {
|
||||
var input = i.Value;
|
||||
if (input.pass != null) foreach (var e in input.pass) {
|
||||
etor.Optimize(e.Value);
|
||||
}
|
||||
}
|
||||
foreach (var j in judges.Values) {
|
||||
if (j.hit != null) etor.Optimize(j.hit);
|
||||
if (j.scores != null) {
|
||||
foreach (var s in j.scores) {
|
||||
foreach (var j in judges) {
|
||||
var judge = j.Value;
|
||||
if (judge.hit != null) etor.Optimize(judge.hit);
|
||||
if (judge.scores != null) {
|
||||
foreach (var s in judge.scores) {
|
||||
if (s.Key.op != default(Identifier))
|
||||
etor.PatchCompound(s.Key.name.Key, s.Key.op.Key, s.Value);
|
||||
etor.Optimize(s.Value);
|
||||
}
|
||||
}
|
||||
}
|
||||
foreach (var s in scores.Values) {
|
||||
if (s.value != null) etor.Optimize(s.value);
|
||||
foreach (var s in scores) {
|
||||
var score = s.Value;
|
||||
if (score.value != null) etor.Optimize(score.value);
|
||||
}
|
||||
constraints.Optimize(etor);
|
||||
}
|
||||
@@ -68,8 +68,8 @@ namespace Cryville.Crtr {
|
||||
[PropertyList]
|
||||
public Dictionary<PropertyKey, PdtExpression> Properties = new Dictionary<PropertyKey, PdtExpression>();
|
||||
public void Optimize(PdtEvaluatorBase etor) {
|
||||
foreach (var e in Properties.Values) {
|
||||
etor.Optimize(e);
|
||||
foreach (var e in Properties) {
|
||||
etor.Optimize(e.Value);
|
||||
}
|
||||
foreach (var e in Elements) {
|
||||
e.Key.Optimize(etor);
|
||||
@@ -126,88 +126,6 @@ namespace Cryville.Crtr {
|
||||
Property,
|
||||
Variable,
|
||||
}
|
||||
public class PdtRulesetBinder : EmptyBinder {
|
||||
public override object ChangeType(object value, Type type, CultureInfo culture) {
|
||||
if (value is PdtExpression) {
|
||||
var exp = (PdtExpression)value;
|
||||
if (type.Equals(typeof(bool))) {
|
||||
bool result = false;
|
||||
ChartPlayer.etor.Evaluate(new PropOp.Boolean(r => result = r), exp);
|
||||
return result;
|
||||
}
|
||||
else if (type.Equals(typeof(int))) {
|
||||
int result = 0;
|
||||
ChartPlayer.etor.Evaluate(new PropOp.Integer(r => result = r), exp);
|
||||
return result;
|
||||
}
|
||||
else if (type.Equals(typeof(float))) {
|
||||
float result = 0;
|
||||
ChartPlayer.etor.Evaluate(new PropOp.Float(r => result = r), exp);
|
||||
return result;
|
||||
}
|
||||
else if (type.Equals(typeof(string))) {
|
||||
string result = default(string);
|
||||
ChartPlayer.etor.Evaluate(new PropOp.String(r => result = r), exp);
|
||||
return result;
|
||||
}
|
||||
else if (type.Equals(typeof(Clip))) {
|
||||
Clip result = default(Clip);
|
||||
ChartPlayer.etor.Evaluate(new PropOp.Clip(r => result = r), exp);
|
||||
return result;
|
||||
}
|
||||
else if (type.Equals(typeof(Identifier))) {
|
||||
Identifier result = default(Identifier);
|
||||
ChartPlayer.etor.Evaluate(new pop_identstr(r => result = r), exp);
|
||||
return result;
|
||||
}
|
||||
else if (type.Equals(typeof(Identifier[]))) {
|
||||
Identifier[] result = null;
|
||||
ChartPlayer.etor.Evaluate(new pop_identstrarr(r => result = r), exp);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
else if (value is string) {
|
||||
var exp = (string)value;
|
||||
if (type.Equals(typeof(Identifier))) {
|
||||
return (Identifier)exp;
|
||||
}
|
||||
else if (type == typeof(ScoreOperation)) {
|
||||
var m = Regex.Match(exp, @"^(\S+)\s*?(\S+)?$");
|
||||
var name = new Identifier(m.Groups[1].Value);
|
||||
if (!m.Groups[2].Success) return new ScoreOperation { name = name };
|
||||
var op = new Identifier(m.Groups[2].Value);
|
||||
return new ScoreOperation { name = name, op = op };
|
||||
}
|
||||
}
|
||||
return base.ChangeType(value, type, culture);
|
||||
}
|
||||
#pragma warning disable IDE1006
|
||||
class pop_identstr : PropOp {
|
||||
readonly Action<SIdentifier> _cb;
|
||||
public pop_identstr(Action<SIdentifier> cb) { _cb = cb; }
|
||||
protected override void Execute() {
|
||||
var op = GetOperand(0);
|
||||
if (op.Type == PdtInternalType.Undefined) _cb(new SIdentifier(op.AsIdentifier()));
|
||||
else if (op.Type == PdtInternalType.String) _cb(new SIdentifier(op.AsString()));
|
||||
else throw new InvalidCastException("Not an identifier or string");
|
||||
}
|
||||
}
|
||||
class pop_identstrarr : PdtOperator {
|
||||
readonly Action<SIdentifier[]> _cb;
|
||||
public pop_identstrarr(Action<SIdentifier[]> cb) : base(16) { _cb = cb; }
|
||||
protected override void Execute() {
|
||||
var result = new SIdentifier[LoadedOperandCount];
|
||||
for (int i = 0; i < LoadedOperandCount; i++) {
|
||||
var op = GetOperand(i);
|
||||
if (op.Type != PdtInternalType.Undefined)
|
||||
throw new InvalidCastException("Not an identifier");
|
||||
result[i] = new SIdentifier(op.AsIdentifier());
|
||||
}
|
||||
_cb(result);
|
||||
}
|
||||
}
|
||||
#pragma warning restore IDE1006
|
||||
}
|
||||
public class RulesetViolationException : Exception {
|
||||
public RulesetViolationException() { }
|
||||
public RulesetViolationException(string message) : base(message) { }
|
||||
|
@@ -5,7 +5,7 @@ using System.Reflection;
|
||||
|
||||
namespace Cryville.Crtr {
|
||||
internal class RulesetInterpreter : PdtInterpreter {
|
||||
public RulesetInterpreter(string src, Binder binder) : base(src, typeof(PdtRuleset), binder) { }
|
||||
public RulesetInterpreter(string src, Binder binder) : base(src, binder) { }
|
||||
|
||||
readonly List<RulesetSelector> s = new List<RulesetSelector>();
|
||||
readonly List<string> a = new List<string>();
|
||||
|
@@ -1,6 +1,8 @@
|
||||
using Cryville.Common;
|
||||
using Cryville.Common.Pdt;
|
||||
using Cryville.Crtr.Browsing;
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
@@ -25,12 +27,45 @@ namespace Cryville.Crtr {
|
||||
public void LoadPdt(DirectoryInfo dir) {
|
||||
using (StreamReader pdtreader = new StreamReader(dir.FullName + "/" + data + ".pdt", Encoding.UTF8)) {
|
||||
var src = pdtreader.ReadToEnd();
|
||||
Root = (PdtSkin)new SkinInterpreter(src, null).Interpret();
|
||||
var interpreter = new SkinInterpreter(src, null);
|
||||
var format = interpreter.GetFormatVersion();
|
||||
if (format.Length == 1) {
|
||||
Root = new PdtSkin();
|
||||
Root.elements = (SkinElement)new SkinInterpreter(src, new PdtBinder()).Interpret(typeof(SkinElement));
|
||||
}
|
||||
else {
|
||||
switch (format[1]) {
|
||||
case 1:
|
||||
Root = (PdtSkin)new SkinInterpreter(src, new PdtBinder()).Interpret(typeof(PdtSkin));
|
||||
break;
|
||||
default: throw new NotSupportedException("Unsupported skin format");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class PdtSkin : SkinElement { }
|
||||
public class PdtSkin {
|
||||
public Dictionary<Identifier, AnimationSpan> animations
|
||||
= new Dictionary<Identifier, AnimationSpan>();
|
||||
public Dictionary<Identifier, EffectDefinition> effects
|
||||
= new Dictionary<Identifier, EffectDefinition>();
|
||||
public SkinElement elements;
|
||||
|
||||
public void Optimize(PdtEvaluator etor) {
|
||||
foreach (var a in animations) {
|
||||
a.Value.Optimize(etor);
|
||||
}
|
||||
foreach (var e in effects) {
|
||||
var effect = e.Value;
|
||||
etor.ContextCascadeInsert();
|
||||
etor.Optimize(effect.duration);
|
||||
effect.elements.Optimize(etor);
|
||||
etor.ContextCascadeDiscard();
|
||||
}
|
||||
elements.Optimize(etor);
|
||||
}
|
||||
}
|
||||
|
||||
public class SkinElement {
|
||||
[ElementList]
|
||||
@@ -48,9 +83,9 @@ namespace Cryville.Crtr {
|
||||
|
||||
public void Optimize(PdtEvaluatorBase etor) {
|
||||
IsDynamic = true;
|
||||
foreach (var e in properties.Values) {
|
||||
etor.Optimize(e);
|
||||
if (!e.IsConstant)
|
||||
foreach (var e in properties) {
|
||||
etor.Optimize(e.Value);
|
||||
if (!e.Value.IsConstant)
|
||||
IsDynamic = true;
|
||||
}
|
||||
foreach (var e in elements) {
|
||||
@@ -61,4 +96,28 @@ namespace Cryville.Crtr {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class EffectDefinition {
|
||||
public PdtExpression duration;
|
||||
public SkinElement elements;
|
||||
}
|
||||
|
||||
public class AnimationSpan {
|
||||
[ElementList]
|
||||
public Dictionary<Clip, AnimationSpan> spans
|
||||
= new Dictionary<Clip, AnimationSpan>();
|
||||
|
||||
[PropertyList]
|
||||
public Dictionary<SkinPropertyKey, PdtExpression> properties
|
||||
= new Dictionary<SkinPropertyKey, PdtExpression>();
|
||||
|
||||
public void Optimize(PdtEvaluator etor) {
|
||||
foreach (var p in properties) {
|
||||
etor.Optimize(p.Value);
|
||||
}
|
||||
foreach (var e in spans) {
|
||||
e.Value.Optimize(etor);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -6,7 +6,7 @@ using UnityEngine.Profiling;
|
||||
|
||||
namespace Cryville.Crtr {
|
||||
public class SkinContainer {
|
||||
readonly PdtSkin skin;
|
||||
readonly SkinElement _rootElement;
|
||||
readonly DynamicStack[] _stacks = new DynamicStack[2];
|
||||
class DynamicStack {
|
||||
public readonly List<DynamicProperty> Properties = new List<DynamicProperty>();
|
||||
@@ -26,25 +26,21 @@ namespace Cryville.Crtr {
|
||||
public SkinSelectors Selectors { get; set; }
|
||||
public SkinElement Element { get; set; }
|
||||
}
|
||||
public SkinContainer(PdtSkin _skin) {
|
||||
skin = _skin;
|
||||
public SkinContainer(SkinElement rootElement) {
|
||||
_rootElement = rootElement;
|
||||
for (int i = 0; i < _stacks.Length; i++) _stacks[i] = new DynamicStack();
|
||||
}
|
||||
public void MatchStatic(ContainerState state) {
|
||||
public void MatchStatic(ISkinnableGroup group) {
|
||||
var stack = _stacks[0];
|
||||
stack.Clear();
|
||||
ChartPlayer.etor.ContextState = state;
|
||||
ChartPlayer.etor.ContextEvent = state.Container;
|
||||
MatchStatic(skin, state, stack, new RuntimeSkinContext(state.Handler.SkinContext));
|
||||
ChartPlayer.etor.ContextEvent = null;
|
||||
ChartPlayer.etor.ContextState = null;
|
||||
MatchStatic(_rootElement, group, stack, new RuntimeSkinContext(group.SkinContext));
|
||||
}
|
||||
void MatchStatic(SkinElement rel, ContainerState state, DynamicStack stack, RuntimeSkinContext ctx) {
|
||||
void MatchStatic(SkinElement rel, ISkinnableGroup group, DynamicStack stack, RuntimeSkinContext ctx) {
|
||||
var rc = ctx.ReadContext;
|
||||
ChartPlayer.etor.ContextTransform = rc.Transform;
|
||||
if (rc.PropSrcs != null) ChartPlayer.etor.ContextCascadeInsert(rc.PropSrcs);
|
||||
foreach (var p in rel.properties) {
|
||||
p.Key.ExecuteStatic(state, ctx, p.Value);
|
||||
p.Key.ExecuteStatic(group, ctx, p.Value);
|
||||
if (p.Key.IsValueRequired && !p.Value.IsConstant) stack.Properties.Add(
|
||||
new DynamicProperty { Context = ctx, Key = p.Key, Value = p.Value }
|
||||
);
|
||||
@@ -52,13 +48,13 @@ namespace Cryville.Crtr {
|
||||
ChartPlayer.etor.ContextTransform = null;
|
||||
foreach (var e in rel.elements) {
|
||||
try {
|
||||
var nctxs = e.Key.MatchStatic(state, rc);
|
||||
var nctxs = e.Key.MatchStatic(group, rc);
|
||||
if (nctxs != null) {
|
||||
var roflag = e.Key.annotations.Contains("if");
|
||||
var woflag = e.Key.annotations.Contains("then");
|
||||
foreach (var nctx in nctxs) {
|
||||
var nrctx = new RuntimeSkinContext(nctx, ctx, roflag, woflag);
|
||||
MatchStatic(e.Value, state, stack, nrctx);
|
||||
MatchStatic(e.Value, group, stack, nrctx);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -70,17 +66,15 @@ namespace Cryville.Crtr {
|
||||
}
|
||||
if (rc.PropSrcs != null) ChartPlayer.etor.ContextCascadeDiscard();
|
||||
}
|
||||
public void MatchDynamic(ContainerState state) {
|
||||
var stack = _stacks[state.CloneType >> 1];
|
||||
var nstack = (state.CloneType >> 1) + 1 < _stacks.Length ? _stacks[(state.CloneType >> 1) + 1] : null;
|
||||
if (nstack != null) nstack.Clear();
|
||||
public void MatchDynamic(ISkinnableGroup group, int dl) {
|
||||
var stack = _stacks[dl];
|
||||
if (stack.Properties.Count == 0 && stack.Elements.Count == 0) return;
|
||||
var nstack = dl + 1 < _stacks.Length ? _stacks[dl + 1] : null;
|
||||
if (nstack != null) nstack.Clear();
|
||||
Profiler.BeginSample("SkinContainer.MatchDynamic");
|
||||
ChartPlayer.etor.ContextState = state;
|
||||
ChartPlayer.etor.ContextEvent = state.Container;
|
||||
for (int i = 0; i < stack.Properties.Count; i++) {
|
||||
DynamicProperty p = stack.Properties[i];
|
||||
p.Key.ExecuteDynamic(state, p.Context, p.Value);
|
||||
p.Key.ExecuteDynamic(group, p.Context, p.Value, dl);
|
||||
}
|
||||
for (int i = 0; i < stack.Elements.Count; i++) {
|
||||
DynamicElement e = stack.Elements[i];
|
||||
@@ -88,33 +82,36 @@ namespace Cryville.Crtr {
|
||||
if (psrcs != null) ChartPlayer.etor.ContextCascadeInsert(psrcs);
|
||||
SkinContext nctx = null;
|
||||
try {
|
||||
nctx = e.Selectors.MatchDynamic(state, e.Context.ReadContext);
|
||||
nctx = e.Selectors.MatchDynamic(group, e.Context.ReadContext);
|
||||
}
|
||||
catch (SelectorNotAvailableException) {
|
||||
if (nstack == null) throw;
|
||||
nstack.Elements.Add(e);
|
||||
}
|
||||
if (nctx != null) MatchDynamic(e.Element, state, nstack, new RuntimeSkinContext(
|
||||
nctx, e.Context, e.Selectors.annotations.Contains("if"), e.Selectors.annotations.Contains("then")
|
||||
));
|
||||
if (nctx != null) {
|
||||
MatchDynamic(e.Element, group, dl, nstack, new RuntimeSkinContext(
|
||||
nctx, e.Context, e.Selectors.annotations.Contains("if"), e.Selectors.annotations.Contains("then")
|
||||
));
|
||||
if (e.Selectors.annotations.Contains("once")) {
|
||||
stack.Elements.RemoveAt(i--);
|
||||
}
|
||||
}
|
||||
if (psrcs != null) ChartPlayer.etor.ContextCascadeDiscard();
|
||||
}
|
||||
ChartPlayer.etor.ContextEvent = null;
|
||||
ChartPlayer.etor.ContextState = null;
|
||||
Profiler.EndSample();
|
||||
}
|
||||
void MatchDynamic(SkinElement rel, ContainerState state, DynamicStack stack, RuntimeSkinContext ctx) {
|
||||
void MatchDynamic(SkinElement rel, ISkinnableGroup group, int dl, DynamicStack stack, RuntimeSkinContext ctx) {
|
||||
var rc = ctx.ReadContext;
|
||||
ChartPlayer.etor.ContextTransform = rc.Transform;
|
||||
if (rc.PropSrcs != null) ChartPlayer.etor.ContextCascadeInsert(rc.PropSrcs);
|
||||
foreach (var p in rel.properties) {
|
||||
p.Key.ExecuteDynamic(state, ctx, p.Value);
|
||||
p.Key.ExecuteDynamic(group, ctx, p.Value, dl);
|
||||
}
|
||||
ChartPlayer.etor.ContextTransform = null;
|
||||
foreach (var e in rel.elements) {
|
||||
if (e.Key.IsUpdatable(state)) {
|
||||
SkinContext nctx = e.Key.MatchDynamic(state, rc);
|
||||
if (nctx != null) MatchDynamic(e.Value, state, stack, new RuntimeSkinContext(
|
||||
if (e.Key.IsUpdatable(group, dl)) {
|
||||
SkinContext nctx = e.Key.MatchDynamic(group, rc);
|
||||
if (nctx != null) MatchDynamic(e.Value, group, dl, stack, new RuntimeSkinContext(
|
||||
nctx, ctx, e.Key.annotations.Contains("if"), e.Key.annotations.Contains("then")
|
||||
));
|
||||
}
|
||||
@@ -162,4 +159,12 @@ namespace Cryville.Crtr {
|
||||
}
|
||||
}
|
||||
}
|
||||
public interface ISkinnableGroup {
|
||||
string TypeName { get; }
|
||||
SkinContext SkinContext { get; }
|
||||
Anchor OpenedAnchor { get; }
|
||||
bool TryGetAnchorsByName(int name, out IReadOnlyCollection<Anchor> result);
|
||||
void RegisterAnchor(int name);
|
||||
void PushAnchorEvent(double time, int name);
|
||||
}
|
||||
}
|
||||
|
@@ -7,12 +7,20 @@ using System.Reflection;
|
||||
|
||||
namespace Cryville.Crtr {
|
||||
public class SkinInterpreter : PdtInterpreter {
|
||||
public SkinInterpreter(string src, Binder binder) : base(src, typeof(PdtSkin), binder) { }
|
||||
public SkinInterpreter(string src, Binder binder) : base(src, binder) { }
|
||||
|
||||
readonly List<SkinSelector> s = new List<SkinSelector>();
|
||||
readonly HashSet<string> a = new HashSet<string>();
|
||||
readonly List<string> k = new List<string>(2);
|
||||
protected override object InterpretKey(Type type) {
|
||||
if (typeof(SkinElement).IsAssignableFrom(type))
|
||||
return InterpretSkinElementKey();
|
||||
else if (typeof(AnimationSpan).IsAssignableFrom(type))
|
||||
return InterpretAnimationSpanKey();
|
||||
else
|
||||
return base.InterpretKey(type);
|
||||
}
|
||||
object InterpretSkinElementKey() {
|
||||
s.Clear(); a.Clear(); k.Clear();
|
||||
bool invalidKeyFlag = false, compKeyFlag = false;
|
||||
while (true) {
|
||||
@@ -62,6 +70,12 @@ namespace Cryville.Crtr {
|
||||
Name = IdentifierManager.SharedInstance.Request(k[0])
|
||||
};
|
||||
}
|
||||
else if (a.Contains("emit")) {
|
||||
if (k.Count != 1) throw new FormatException("Invalid effect name");
|
||||
return new SkinPropertyKey.EmitEffect {
|
||||
Name = IdentifierManager.SharedInstance.Request(k[0])
|
||||
};
|
||||
}
|
||||
switch (k.Count) {
|
||||
case 1:
|
||||
if (compKeyFlag) return new SkinPropertyKey.CreateComponent {
|
||||
@@ -82,7 +96,7 @@ namespace Cryville.Crtr {
|
||||
case '{':
|
||||
return new SkinSelectors(s, a);
|
||||
case '}':
|
||||
return null;
|
||||
throw new FormatException("Invalid token");
|
||||
case '*':
|
||||
GetChar();
|
||||
compKeyFlag = true;
|
||||
@@ -100,6 +114,59 @@ namespace Cryville.Crtr {
|
||||
if (Position == pp) throw new FormatException("Invalid selector or key format");
|
||||
}
|
||||
}
|
||||
object InterpretAnimationSpanKey() {
|
||||
if ((ct & 0x0040) != 0 || cc == ',') {
|
||||
float start = 0, end = 1;
|
||||
if (cc != ',') {
|
||||
start = float.Parse(GetNumber());
|
||||
ws(); if (cc != ',') throw new FormatException("Invalid span format");
|
||||
}
|
||||
GetChar(); ws();
|
||||
if (cc != '{') end = float.Parse(GetNumber());
|
||||
ws();
|
||||
if (cc != '{') throw new FormatException("Invalid span format");
|
||||
return new Clip(start, end);
|
||||
}
|
||||
k.Clear();
|
||||
while (true) {
|
||||
int pp = Position;
|
||||
switch (cc) {
|
||||
case '.':
|
||||
GetChar();
|
||||
if (k.Count != 1)
|
||||
throw new FormatException("Invalid key format");
|
||||
k.Add(GetIdentifier());
|
||||
break;
|
||||
case ';':
|
||||
case ':':
|
||||
switch (k.Count) {
|
||||
case 1:
|
||||
return new SkinPropertyKey.SetProperty {
|
||||
Component = typeof(TransformInterface),
|
||||
Name = IdentifierManager.SharedInstance.Request(k[0])
|
||||
};
|
||||
case 2:
|
||||
return new SkinPropertyKey.SetProperty {
|
||||
Component = GetComponentByName(k[0]),
|
||||
Name = IdentifierManager.SharedInstance.Request(k[1])
|
||||
};
|
||||
default:
|
||||
throw new FormatException("Unknown error"); // Unreachable
|
||||
}
|
||||
case '{':
|
||||
throw new FormatException("Invalid token");
|
||||
case '}':
|
||||
throw new FormatException("Invalid token");
|
||||
default:
|
||||
if (k.Count != 0)
|
||||
throw new FormatException("Invalid key format");
|
||||
k.Add(GetIdentifier());
|
||||
break;
|
||||
}
|
||||
ws();
|
||||
if (Position == pp) throw new FormatException("Invalid selector or key format");
|
||||
}
|
||||
}
|
||||
static Type GetComponentByName(string name) {
|
||||
Type result;
|
||||
if (GenericResources.Components.TryGetValue(name, out result)) return result;
|
||||
|
@@ -1,7 +1,6 @@
|
||||
using Cryville.Common;
|
||||
using Cryville.Common.Pdt;
|
||||
using Cryville.Crtr.Components;
|
||||
using Cryville.Crtr.Event;
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
@@ -9,18 +8,18 @@ namespace Cryville.Crtr {
|
||||
public abstract class SkinPropertyKey {
|
||||
public abstract override string ToString();
|
||||
public abstract bool IsValueRequired { get; }
|
||||
public abstract void ExecuteStatic(ContainerState state, RuntimeSkinContext ctx, PdtExpression exp);
|
||||
public abstract void ExecuteDynamic(ContainerState state, RuntimeSkinContext ctx, PdtExpression exp);
|
||||
public abstract void ExecuteStatic(ISkinnableGroup group, RuntimeSkinContext ctx, PdtExpression exp);
|
||||
public abstract void ExecuteDynamic(ISkinnableGroup group, RuntimeSkinContext ctx, PdtExpression exp, int dl);
|
||||
public class CreateComponent : SkinPropertyKey {
|
||||
public Type Component { get; set; }
|
||||
public override string ToString() {
|
||||
return string.Format("*{0}", Component.Name);
|
||||
}
|
||||
public override bool IsValueRequired { get { return false; } }
|
||||
public override void ExecuteStatic(ContainerState state, RuntimeSkinContext ctx, PdtExpression exp) {
|
||||
public override void ExecuteStatic(ISkinnableGroup group, RuntimeSkinContext ctx, PdtExpression exp) {
|
||||
ctx.WriteTransform.gameObject.AddComponent(Component);
|
||||
}
|
||||
public override void ExecuteDynamic(ContainerState state, RuntimeSkinContext ctx, PdtExpression exp) {
|
||||
public override void ExecuteDynamic(ISkinnableGroup group, RuntimeSkinContext ctx, PdtExpression exp, int dl) {
|
||||
throw new InvalidOperationException("Component creation in dynamic context is not allowed");
|
||||
}
|
||||
}
|
||||
@@ -31,12 +30,12 @@ namespace Cryville.Crtr {
|
||||
return string.Format("{0}.{1}", Component.Name, IdentifierManager.SharedInstance.Retrieve(Name));
|
||||
}
|
||||
public override bool IsValueRequired { get { return true; } }
|
||||
public override void ExecuteStatic(ContainerState state, RuntimeSkinContext ctx, PdtExpression exp) {
|
||||
public override void ExecuteStatic(ISkinnableGroup group, RuntimeSkinContext ctx, PdtExpression exp) {
|
||||
Execute(ctx, GetPropOp(ctx.WriteTransform).Operator, exp);
|
||||
}
|
||||
public override void ExecuteDynamic(ContainerState state, RuntimeSkinContext ctx, PdtExpression exp) {
|
||||
public override void ExecuteDynamic(ISkinnableGroup group, RuntimeSkinContext ctx, PdtExpression exp, int dl) {
|
||||
var prop = GetPropOp(ctx.WriteTransform);
|
||||
if (state.CloneType > prop.UpdateCloneType) return;
|
||||
if (dl > prop.UpdateDynamicLevel) return;
|
||||
Execute(ctx, prop.Operator, exp);
|
||||
}
|
||||
void Execute(RuntimeSkinContext ctx, PdtOperator op, PdtExpression exp) {
|
||||
@@ -67,10 +66,10 @@ namespace Cryville.Crtr {
|
||||
return string.Format("@has {0}", IdentifierManager.SharedInstance.Retrieve(Name));
|
||||
}
|
||||
public override bool IsValueRequired { get { return false; } }
|
||||
public override void ExecuteStatic(ContainerState state, RuntimeSkinContext ctx, PdtExpression exp) {
|
||||
state.Handler.RegisterAnchor(Name, true);
|
||||
public override void ExecuteStatic(ISkinnableGroup group, RuntimeSkinContext ctx, PdtExpression exp) {
|
||||
group.RegisterAnchor(Name);
|
||||
}
|
||||
public override void ExecuteDynamic(ContainerState state, RuntimeSkinContext ctx, PdtExpression exp) {
|
||||
public override void ExecuteDynamic(ISkinnableGroup group, RuntimeSkinContext ctx, PdtExpression exp, int dl) {
|
||||
throw new InvalidOperationException("Anchor creation in dynamic context is not allowed");
|
||||
}
|
||||
}
|
||||
@@ -83,18 +82,37 @@ namespace Cryville.Crtr {
|
||||
return string.Format("@at {0}", IdentifierManager.SharedInstance.Retrieve(Name));
|
||||
}
|
||||
public override bool IsValueRequired { get { return true; } }
|
||||
public override void ExecuteStatic(ContainerState state, RuntimeSkinContext ctx, PdtExpression exp) {
|
||||
public override void ExecuteStatic(ISkinnableGroup group, RuntimeSkinContext ctx, PdtExpression exp) {
|
||||
throw new InvalidOperationException("Setting anchor in static context is not allowed");
|
||||
}
|
||||
float _time;
|
||||
readonly PropOp _timeOp;
|
||||
public override void ExecuteDynamic(ContainerState state, RuntimeSkinContext ctx, PdtExpression exp) {
|
||||
if (state.CloneType > 1) return;
|
||||
public override void ExecuteDynamic(ISkinnableGroup group, RuntimeSkinContext ctx, PdtExpression exp, int dl) {
|
||||
if (dl > 0) return;
|
||||
var psrcs = ctx.ReadContext.PropSrcs;
|
||||
if (psrcs != null) ChartPlayer.etor.ContextCascadeInsert(psrcs);
|
||||
ChartPlayer.etor.Evaluate(_timeOp, exp);
|
||||
if (psrcs != null) ChartPlayer.etor.ContextCascadeDiscard();
|
||||
state.Handler.PushAnchorEvent(_time, Name);
|
||||
group.PushAnchorEvent(_time, Name);
|
||||
}
|
||||
}
|
||||
public class EmitEffect : SkinPropertyKey {
|
||||
public int Name { get; set; }
|
||||
public EmitEffect() {
|
||||
_op = new PropOp.Float(v => _index = v);
|
||||
}
|
||||
public override string ToString() {
|
||||
return string.Format("@emit {0}", IdentifierManager.SharedInstance.Retrieve(Name));
|
||||
}
|
||||
public override bool IsValueRequired { get { return true; } }
|
||||
public override void ExecuteStatic(ISkinnableGroup group, RuntimeSkinContext ctx, PdtExpression exp) {
|
||||
throw new InvalidOperationException("Emitting effect in static context is not allowed");
|
||||
}
|
||||
float _index;
|
||||
readonly PropOp _op;
|
||||
public override void ExecuteDynamic(ISkinnableGroup group, RuntimeSkinContext ctx, PdtExpression exp, int dl) {
|
||||
ChartPlayer.etor.Evaluate(_op, exp);
|
||||
ChartPlayer.effectManager.Emit(Name, _index);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1,7 +1,6 @@
|
||||
using Cryville.Common;
|
||||
using Cryville.Common.Pdt;
|
||||
using Cryville.Crtr.Components;
|
||||
using Cryville.Crtr.Event;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
@@ -37,21 +36,21 @@ namespace Cryville.Crtr {
|
||||
selectors[i].Optimize(etor);
|
||||
}
|
||||
}
|
||||
public IEnumerable<SkinContext> MatchStatic(ContainerState h, SkinContext ctx) {
|
||||
public IEnumerable<SkinContext> MatchStatic(ISkinnableGroup g, SkinContext ctx) {
|
||||
IEnumerable<SkinContext> result = new SkinContext[] { ctx };
|
||||
foreach (var s in selectors) {
|
||||
result = result.SelectMany(l => s.MatchStatic(h, l));
|
||||
result = result.SelectMany(l => s.MatchStatic(g, l));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
public bool IsUpdatable(ContainerState h) {
|
||||
public bool IsUpdatable(ISkinnableGroup g, int dl) {
|
||||
foreach (var s in selectors)
|
||||
if (!s.IsUpdatable(h)) return false;
|
||||
if (!s.IsUpdatable(g, dl)) return false;
|
||||
return true;
|
||||
}
|
||||
public SkinContext MatchDynamic(ContainerState h, SkinContext ctx) {
|
||||
public SkinContext MatchDynamic(ISkinnableGroup g, SkinContext ctx) {
|
||||
foreach (var s in selectors) {
|
||||
ctx = s.MatchDynamic(h, ctx);
|
||||
ctx = s.MatchDynamic(g, ctx);
|
||||
if (ctx == null) return null;
|
||||
}
|
||||
return ctx;
|
||||
@@ -63,16 +62,16 @@ namespace Cryville.Crtr {
|
||||
public abstract override string ToString();
|
||||
|
||||
public virtual void Optimize(PdtEvaluatorBase etor) { }
|
||||
public virtual IEnumerable<SkinContext> MatchStatic(ContainerState h, SkinContext c) { throw new SelectorNotAvailableException(); }
|
||||
public virtual SkinContext MatchDynamic(ContainerState h, SkinContext c) { throw new SelectorNotAvailableException(); }
|
||||
public virtual bool IsUpdatable(ContainerState h) {
|
||||
public virtual IEnumerable<SkinContext> MatchStatic(ISkinnableGroup g, SkinContext c) { throw new SelectorNotAvailableException(); }
|
||||
public virtual SkinContext MatchDynamic(ISkinnableGroup g, SkinContext c) { throw new SelectorNotAvailableException(); }
|
||||
public virtual bool IsUpdatable(ISkinnableGroup g, int dl) {
|
||||
return true;
|
||||
}
|
||||
public class CreateObject : SkinSelector {
|
||||
public CreateObject() { }
|
||||
public override string ToString() { return "$"; }
|
||||
|
||||
public override IEnumerable<SkinContext> MatchStatic(ContainerState h, SkinContext c) {
|
||||
public override IEnumerable<SkinContext> MatchStatic(ISkinnableGroup g, SkinContext c) {
|
||||
var obj = new GameObject("__obj__");
|
||||
obj.transform.SetParent(c.Transform, false);
|
||||
obj.AddComponent<TransformInterface>();
|
||||
@@ -86,9 +85,9 @@ namespace Cryville.Crtr {
|
||||
}
|
||||
public override string ToString() { return string.Format(".{0}", IdentifierManager.SharedInstance.Retrieve(Name)); }
|
||||
|
||||
public override IEnumerable<SkinContext> MatchStatic(ContainerState h, SkinContext c) {
|
||||
List<CAnchor> anchors;
|
||||
if (h.Handler.Anchors.TryGetValue(Name, out anchors)) {
|
||||
public override IEnumerable<SkinContext> MatchStatic(ISkinnableGroup g, SkinContext c) {
|
||||
IReadOnlyCollection<CAnchor> anchors;
|
||||
if (g.TryGetAnchorsByName(Name, out anchors)) {
|
||||
return anchors.Select(a => a.SkinContext);
|
||||
}
|
||||
else return Enumerable.Empty<SkinContext>();
|
||||
@@ -101,11 +100,11 @@ namespace Cryville.Crtr {
|
||||
}
|
||||
public override string ToString() { return string.Format("..{0}", IdentifierManager.SharedInstance.Retrieve(Name)); }
|
||||
|
||||
public override SkinContext MatchDynamic(ContainerState h, SkinContext c) {
|
||||
return h.Handler.OpenedAnchor != null && h.Handler.OpenedAnchor.Name == Name ? c : null;
|
||||
public override SkinContext MatchDynamic(ISkinnableGroup g, SkinContext c) {
|
||||
return g.OpenedAnchor != null && g.OpenedAnchor.Name == Name ? c : null;
|
||||
}
|
||||
public override bool IsUpdatable(ContainerState h) {
|
||||
return h.CloneType >= 2;
|
||||
public override bool IsUpdatable(ISkinnableGroup g, int dl) {
|
||||
return dl >= 1;
|
||||
}
|
||||
}
|
||||
public class Property : SkinSelector {
|
||||
@@ -121,12 +120,12 @@ namespace Cryville.Crtr {
|
||||
public override void Optimize(PdtEvaluatorBase etor) {
|
||||
etor.Optimize(_exp);
|
||||
}
|
||||
public override IEnumerable<SkinContext> MatchStatic(ContainerState h, SkinContext c) {
|
||||
public override IEnumerable<SkinContext> MatchStatic(ISkinnableGroup g, SkinContext c) {
|
||||
var result = Match(c);
|
||||
if (result != null) return new SkinContext[] { result };
|
||||
else return Enumerable.Empty<SkinContext>();
|
||||
}
|
||||
public override SkinContext MatchDynamic(ContainerState h, SkinContext c) {
|
||||
public override SkinContext MatchDynamic(ISkinnableGroup g, SkinContext c) {
|
||||
return Match(c);
|
||||
}
|
||||
public SkinContext Match(SkinContext a) {
|
||||
@@ -148,8 +147,8 @@ namespace Cryville.Crtr {
|
||||
public ElementType(string type) { _type = type; }
|
||||
public override string ToString() { return _type; }
|
||||
|
||||
public override IEnumerable<SkinContext> MatchStatic(ContainerState h, SkinContext c) {
|
||||
return h.Handler.TypeName == _type ? new SkinContext[] { c } : Enumerable.Empty<SkinContext>();
|
||||
public override IEnumerable<SkinContext> MatchStatic(ISkinnableGroup g, SkinContext c) {
|
||||
return g.TypeName == _type ? new SkinContext[] { c } : Enumerable.Empty<SkinContext>();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -61,10 +61,9 @@ namespace Cryville.Crtr {
|
||||
return new Vector2(Texture.width, Texture.height);
|
||||
}
|
||||
}
|
||||
|
||||
public void Init() {
|
||||
if (Texture == null)
|
||||
throw new InvalidOperationException("Missing texture");
|
||||
public SpriteFrame(Texture2D tex) {
|
||||
if (tex == null) throw new ArgumentNullException("tex");
|
||||
Texture = tex;
|
||||
m_frame = new Rect(Vector2.zero, Size);
|
||||
var w = m_frame.width;
|
||||
var h = m_frame.height;
|
||||
@@ -75,10 +74,5 @@ namespace Cryville.Crtr {
|
||||
if (m_rotated) UV = new Rect(x, y, tw, -th);
|
||||
else UV = new Rect(x, y, tw, -th);
|
||||
}
|
||||
|
||||
public SpriteFrame() { }
|
||||
public SpriteFrame(Texture2D tex) {
|
||||
Texture = tex;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -27,11 +27,11 @@ namespace Cryville.Crtr {
|
||||
TransformAwake(s);
|
||||
}
|
||||
}
|
||||
public override void StartPreGraphicalUpdate(ContainerState s) {
|
||||
protected override void StartPreGraphicalUpdate(ContainerState s) {
|
||||
base.StartPreGraphicalUpdate(s);
|
||||
TransformAwake(s);
|
||||
}
|
||||
public override void StartGraphicalUpdate(ContainerState s) {
|
||||
protected override void StartGraphicalUpdate(ContainerState s) {
|
||||
base.StartGraphicalUpdate(s);
|
||||
if (gogroup) {
|
||||
TransformAwake(s);
|
||||
@@ -105,7 +105,7 @@ namespace Cryville.Crtr {
|
||||
spos = bpos - GetCurrentWorldPoint();
|
||||
}
|
||||
|
||||
public override void EndGraphicalUpdate(ContainerState s) {
|
||||
protected override void EndGraphicalUpdate(ContainerState s) {
|
||||
base.EndGraphicalUpdate(s);
|
||||
EndUpdatePosition(s);
|
||||
var p = GetCurrentWorldPoint();
|
||||
|
Binary file not shown.
@@ -410,8 +410,16 @@ namespace System.Text.Formatting {
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
void CheckCapacity (int count) {
|
||||
if (currentCount + count > buffer.Length)
|
||||
Array.Resize(ref buffer, buffer.Length * 2);
|
||||
int newCount = currentCount + count;
|
||||
if (newCount > buffer.Length) {
|
||||
int newCapacity = buffer.Length * 2;
|
||||
if (newCapacity < newCount) newCapacity = newCount;
|
||||
char[] newBuffer = new char[newCapacity];
|
||||
fixed (void* nptr = newBuffer, ptr = buffer) {
|
||||
Unsafe.CopyBlock(nptr, ptr, (uint)(currentCount * sizeof(char)));
|
||||
}
|
||||
buffer = newBuffer;
|
||||
}
|
||||
}
|
||||
|
||||
bool AppendSegment<T>(ref char* currRef, char* end, char* dest, ref int prevArgIndex, ref T args) where T : IArgSet {
|
||||
|
Reference in New Issue
Block a user