Refactor SkinPropertyKey.
This commit is contained in:
@@ -1,13 +1,8 @@
|
||||
using Cryville.Common;
|
||||
using Cryville.Common.Pdt;
|
||||
using Cryville.Crtr.Browsing;
|
||||
using Cryville.Crtr.Components;
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
|
||||
namespace Cryville.Crtr {
|
||||
@@ -37,7 +32,6 @@ namespace Cryville.Crtr {
|
||||
|
||||
public class PdtSkin : SkinElement { }
|
||||
|
||||
[Binder(typeof(SkinElementBinder))]
|
||||
public class SkinElement {
|
||||
[ElementList]
|
||||
public Dictionary<SkinSelectors, SkinElement> elements
|
||||
@@ -67,36 +61,4 @@ namespace Cryville.Crtr {
|
||||
}
|
||||
}
|
||||
}
|
||||
public struct SkinPropertyKey {
|
||||
public Type Component;
|
||||
public int Name;
|
||||
}
|
||||
public class SkinElementBinder : EmptyBinder {
|
||||
public override object ChangeType(object value, Type type, CultureInfo culture) {
|
||||
if (value is string && type == typeof(SkinPropertyKey)) {
|
||||
var cp = ((string)value).Split('.');
|
||||
switch (cp.Length) {
|
||||
case 1:
|
||||
var key = cp[0];
|
||||
if (key[0] == '*')
|
||||
return new SkinPropertyKey { Component = GetComponentByName(key.Substring(1)) };
|
||||
else
|
||||
return new SkinPropertyKey { Component = typeof(TransformInterface), Name = IdentifierManager.SharedInstance.Request(key) };
|
||||
case 2:
|
||||
return new SkinPropertyKey { Component = GetComponentByName(cp[0]), Name = IdentifierManager.SharedInstance.Request(cp[1]) };
|
||||
}
|
||||
}
|
||||
return base.ChangeType(value, type, culture);
|
||||
}
|
||||
|
||||
static readonly char[] nssep = new char[]{':'};
|
||||
Type GetComponentByName(string name) {
|
||||
var nstuple = name.Split(nssep, 2);
|
||||
var ns = nssep.Length == 2 ? nstuple[0] : "generic";
|
||||
name = nssep.Length == 2 ? nstuple[1] : nstuple[0];
|
||||
if (ns == "generic")
|
||||
return GenericResources.Components[name];
|
||||
throw new ArgumentException(string.Format("Component type {0} not found", name));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1,8 +1,5 @@
|
||||
using Cryville.Common;
|
||||
using Cryville.Common.Pdt;
|
||||
using Cryville.Crtr.Components;
|
||||
using Cryville.Crtr.Event;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Profiling;
|
||||
@@ -38,14 +35,10 @@ namespace Cryville.Crtr {
|
||||
ChartPlayer.etor.ContextTransform = rc.Transform;
|
||||
if (rc.PropSrcs != null) ChartPlayer.etor.ContextCascadeInsert(rc.PropSrcs);
|
||||
foreach (var p in rel.properties) {
|
||||
if (p.Key.Name == 0)
|
||||
rc.Transform.gameObject.AddComponent(p.Key.Component);
|
||||
else {
|
||||
ChartPlayer.etor.Evaluate(GetPropOp(ctx.WriteTransform, p.Key).Operator, p.Value);
|
||||
if (!p.Value.IsConstant) dynprops.Add(
|
||||
new DynamicProperty { Context = ctx, Key = p.Key, Value = p.Value }
|
||||
);
|
||||
}
|
||||
p.Key.ExecuteStatic(state, ctx, p.Value);
|
||||
if (p.Key.IsValueRequired && !p.Value.IsConstant) dynprops.Add(
|
||||
new DynamicProperty { Context = ctx, Key = p.Key, Value = p.Value }
|
||||
);
|
||||
}
|
||||
ChartPlayer.etor.ContextTransform = null;
|
||||
foreach (var r in rel.elements) {
|
||||
@@ -73,12 +66,7 @@ namespace Cryville.Crtr {
|
||||
ChartPlayer.etor.ContextEvent = state.Container;
|
||||
for (int i = 0; i < dynprops.Count; i++) {
|
||||
DynamicProperty p = dynprops[i];
|
||||
var psrcs = p.Context.ReadContext.PropSrcs;
|
||||
if (psrcs != null) ChartPlayer.etor.ContextCascadeInsert(psrcs);
|
||||
var prop = GetPropOp(p.Context.WriteTransform, p.Key);
|
||||
if (state.CloneType > prop.UpdateCloneType) continue;
|
||||
ChartPlayer.etor.Evaluate(prop.Operator, p.Value);
|
||||
if (psrcs != null) ChartPlayer.etor.ContextCascadeDiscard();
|
||||
p.Key.ExecuteDynamic(state, p.Context, p.Value);
|
||||
}
|
||||
for (int i = 0; i < dynelems.Count; i++) {
|
||||
DynamicElement e = dynelems[i];
|
||||
@@ -99,11 +87,7 @@ namespace Cryville.Crtr {
|
||||
ChartPlayer.etor.ContextTransform = rc.Transform;
|
||||
if (rc.PropSrcs != null) ChartPlayer.etor.ContextCascadeInsert(rc.PropSrcs);
|
||||
foreach (var p in rel.properties) {
|
||||
if (p.Key.Name == 0)
|
||||
throw new InvalidOperationException("Component creation in dynamic context is not allowed");
|
||||
var prop = GetPropOp(ctx.WriteTransform, p.Key);
|
||||
if (state.CloneType > prop.UpdateCloneType) continue;
|
||||
ChartPlayer.etor.Evaluate(prop.Operator, p.Value);
|
||||
p.Key.ExecuteDynamic(state, ctx, p.Value);
|
||||
}
|
||||
ChartPlayer.etor.ContextTransform = null;
|
||||
foreach (var r in rel.elements) {
|
||||
@@ -115,21 +99,6 @@ namespace Cryville.Crtr {
|
||||
}
|
||||
if (rc.PropSrcs != null) ChartPlayer.etor.ContextCascadeDiscard();
|
||||
}
|
||||
SkinProperty GetPropOp(Transform obj, SkinPropertyKey key) {
|
||||
var ctype = key.Component;
|
||||
var comp = (SkinComponent)obj.GetComponent(ctype);
|
||||
if (comp == null) throw new InvalidOperationException(string.Format(
|
||||
"Trying to set property {0} but the component is not found",
|
||||
IdentifierManager.SharedInstance.Retrieve(key.Name)
|
||||
));
|
||||
SkinProperty result;
|
||||
if (!comp.Properties.TryGetValue(key.Name, out result))
|
||||
throw new ArgumentException(string.Format(
|
||||
"Property {0} not found on component",
|
||||
IdentifierManager.SharedInstance.Retrieve(key.Name)
|
||||
));
|
||||
return result;
|
||||
}
|
||||
}
|
||||
public class SkinContext {
|
||||
public Transform Transform { get; private set; }
|
||||
|
@@ -1,4 +1,6 @@
|
||||
using Cryville.Common.Pdt;
|
||||
using Cryville.Common;
|
||||
using Cryville.Common.Pdt;
|
||||
using Cryville.Crtr.Components;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
@@ -8,10 +10,11 @@ namespace Cryville.Crtr {
|
||||
public SkinInterpreter(string src, Binder binder) : base(src, typeof(PdtSkin), binder) { }
|
||||
|
||||
readonly List<SkinSelector> s = new List<SkinSelector>();
|
||||
readonly List<string> a = new List<string>();
|
||||
readonly HashSet<string> a = new HashSet<string>();
|
||||
readonly List<string> k = new List<string>(2);
|
||||
protected override object InterpretKey(Type type) {
|
||||
s.Clear(); a.Clear();
|
||||
string key = "";
|
||||
s.Clear(); a.Clear(); k.Clear();
|
||||
bool invalidKeyFlag = false, compKeyFlag = false;
|
||||
while (true) {
|
||||
int pp = Position;
|
||||
switch (cc) {
|
||||
@@ -22,19 +25,22 @@ namespace Cryville.Crtr {
|
||||
case '$':
|
||||
GetChar();
|
||||
s.Add(new SkinSelector.CreateObject());
|
||||
key = null;
|
||||
invalidKeyFlag = true;
|
||||
break;
|
||||
case '.':
|
||||
GetChar();
|
||||
if (cc == '.') {
|
||||
GetChar();
|
||||
s.Add(new SkinSelector.AtAnchor(GetIdentifier()));
|
||||
key = null;
|
||||
invalidKeyFlag = true;
|
||||
}
|
||||
else {
|
||||
var p3 = GetIdentifier();
|
||||
s.Add(new SkinSelector.Anchor(p3));
|
||||
if (key != null) key += "." + p3;
|
||||
if (!invalidKeyFlag) {
|
||||
if (k.Count != 1) invalidKeyFlag = true;
|
||||
else k.Add(p3);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case '>':
|
||||
@@ -43,24 +49,61 @@ namespace Cryville.Crtr {
|
||||
break;
|
||||
case ';':
|
||||
case ':':
|
||||
return key;
|
||||
if (invalidKeyFlag) throw new FormatException("Invalid key format");
|
||||
if (a.Contains("has")) {
|
||||
if (k.Count != 1) throw new FormatException("Invalid anchor name");
|
||||
return new SkinPropertyKey.CreateAnchor {
|
||||
Name = IdentifierManager.SharedInstance.Request(k[0])
|
||||
};
|
||||
}
|
||||
else if (a.Contains("at")) {
|
||||
if (k.Count != 1) throw new FormatException("Invalid anchor name");
|
||||
return new SkinPropertyKey.SetAnchor {
|
||||
Name = IdentifierManager.SharedInstance.Request(k[0])
|
||||
};
|
||||
}
|
||||
switch (k.Count) {
|
||||
case 1:
|
||||
if (compKeyFlag) return new SkinPropertyKey.CreateComponent {
|
||||
Component = GetComponentByName(k[0])
|
||||
};
|
||||
else 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 '{':
|
||||
return new SkinSelectors(s, a);
|
||||
case '}':
|
||||
return null;
|
||||
case '*':
|
||||
GetChar();
|
||||
key += "*";
|
||||
compKeyFlag = true;
|
||||
break;
|
||||
default:
|
||||
var p4 = GetIdentifier();
|
||||
s.Add(new SkinSelector.ElementType(p4));
|
||||
if (key != null) key += p4;
|
||||
if (!invalidKeyFlag) {
|
||||
if (k.Count != 0) invalidKeyFlag = true;
|
||||
else k.Add(p4);
|
||||
}
|
||||
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;
|
||||
throw new ArgumentException(string.Format("Component type {0} not found", name));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
91
Assets/Cryville/Crtr/SkinPropertyKey.cs
Normal file
91
Assets/Cryville/Crtr/SkinPropertyKey.cs
Normal file
@@ -0,0 +1,91 @@
|
||||
using Cryville.Common;
|
||||
using Cryville.Common.Pdt;
|
||||
using Cryville.Crtr.Components;
|
||||
using Cryville.Crtr.Event;
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
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 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) {
|
||||
ctx.ReadContext.Transform.gameObject.AddComponent(Component);
|
||||
}
|
||||
public override void ExecuteDynamic(ContainerState state, RuntimeSkinContext ctx, PdtExpression exp) {
|
||||
throw new InvalidOperationException("Component creation in dynamic context is not allowed");
|
||||
}
|
||||
}
|
||||
public class SetProperty : SkinPropertyKey {
|
||||
public Type Component { get; set; }
|
||||
public int Name { get; set; }
|
||||
public override string ToString() {
|
||||
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) {
|
||||
Execute(ctx, GetPropOp(ctx.WriteTransform).Operator, exp);
|
||||
}
|
||||
public override void ExecuteDynamic(ContainerState state, RuntimeSkinContext ctx, PdtExpression exp) {
|
||||
var prop = GetPropOp(ctx.WriteTransform);
|
||||
if (state.CloneType > prop.UpdateCloneType) return;
|
||||
Execute(ctx, prop.Operator, exp);
|
||||
}
|
||||
void Execute(RuntimeSkinContext ctx, PdtOperator op, PdtExpression exp) {
|
||||
var psrcs = ctx.ReadContext.PropSrcs;
|
||||
if (psrcs != null) ChartPlayer.etor.ContextCascadeInsert(psrcs);
|
||||
ChartPlayer.etor.Evaluate(op, exp);
|
||||
if (psrcs != null) ChartPlayer.etor.ContextCascadeDiscard();
|
||||
}
|
||||
SkinProperty GetPropOp(Transform obj) {
|
||||
var ctype = Component;
|
||||
var comp = (SkinComponent)obj.GetComponent(ctype);
|
||||
if (comp == null) throw new InvalidOperationException(string.Format(
|
||||
"Trying to set property {0} but the component is not found",
|
||||
IdentifierManager.SharedInstance.Retrieve(Name)
|
||||
));
|
||||
SkinProperty result;
|
||||
if (!comp.Properties.TryGetValue(Name, out result))
|
||||
throw new InvalidOperationException(string.Format(
|
||||
"Property {0} not found on component",
|
||||
IdentifierManager.SharedInstance.Retrieve(Name)
|
||||
));
|
||||
return result;
|
||||
}
|
||||
}
|
||||
public class CreateAnchor : SkinPropertyKey {
|
||||
public int Name { get; set; }
|
||||
public override string ToString() {
|
||||
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) {
|
||||
// TODO
|
||||
}
|
||||
public override void ExecuteDynamic(ContainerState state, RuntimeSkinContext ctx, PdtExpression exp) {
|
||||
throw new InvalidOperationException("Anchor creation in dynamic context is not allowed");
|
||||
}
|
||||
}
|
||||
public class SetAnchor : SkinPropertyKey {
|
||||
public int Name { get; set; }
|
||||
public override string ToString() {
|
||||
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) {
|
||||
// TODO
|
||||
}
|
||||
public override void ExecuteDynamic(ContainerState state, RuntimeSkinContext ctx, PdtExpression exp) {
|
||||
// TODO
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
11
Assets/Cryville/Crtr/SkinPropertyKey.cs.meta
Normal file
11
Assets/Cryville/Crtr/SkinPropertyKey.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 701f7f917dc59c540b105732747aeb67
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
Reference in New Issue
Block a user