Pull up ISkinnableGroup.

This commit is contained in:
2023-02-17 15:19:18 +08:00
parent 7015426300
commit db0165d145
6 changed files with 98 additions and 68 deletions

View File

@@ -19,7 +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);
SubmitProperty("part", new PropOp.Enum<Part>(v => part = v, v => (Part)v), 1);
}
protected override void OnDestroy() {
@@ -67,7 +67,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

View File

@@ -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;
}
}
}

View File

@@ -8,7 +8,7 @@ using System.Runtime.CompilerServices;
using UnityEngine;
namespace Cryville.Crtr.Event {
public class ContainerState {
public class ContainerState : ISkinnableGroup {
#region Struct
public EventBus Bus;
public EventContainer Container;
@@ -466,5 +466,26 @@ namespace Cryville.Crtr.Event {
}
}
#endregion
#region ISkinnableGroup
public int DynamicLevel { get { return CloneType >> 1; } }
public string TypeName { get { return Handler.TypeName; } }
public ContainerState State { get { return this; } }
EventContainer ISkinnableGroup.Container { get { return Container; } }
public SkinContext SkinContext { get { return Handler.SkinContext; } }
public Anchor OpenedAnchor { get { return Handler.OpenedAnchor; } }
public bool TryGetAnchorsByName(int name, out IReadOnlyCollection<Anchor> result) {
List<Anchor> anchors;
var ret = Handler.Anchors.TryGetValue(name, out anchors);
result = anchors;
return ret;
}
public void RegisterAnchor(int name) {
Handler.RegisterAnchor(name, true);
}
public void PushAnchorEvent(double time, int name) {
Handler.PushAnchorEvent(time, name);
}
#endregion
}
}

View File

@@ -30,21 +30,21 @@ namespace Cryville.Crtr {
_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(_rootElement, state, stack, new RuntimeSkinContext(state.Handler.SkinContext));
if (group.State != null) ChartPlayer.etor.ContextState = group.State;
if (group.Container != null) ChartPlayer.etor.ContextEvent = group.Container;
MatchStatic(_rootElement, group, stack, new RuntimeSkinContext(group.SkinContext));
ChartPlayer.etor.ContextEvent = null;
ChartPlayer.etor.ContextState = null;
}
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 +52,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 +70,17 @@ 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;
public void MatchDynamic(ISkinnableGroup group) {
var stack = _stacks[group.DynamicLevel];
var nstack = group.DynamicLevel + 1 < _stacks.Length ? _stacks[group.DynamicLevel + 1] : null;
if (nstack != null) nstack.Clear();
if (stack.Properties.Count == 0 && stack.Elements.Count == 0) return;
Profiler.BeginSample("SkinContainer.MatchDynamic");
ChartPlayer.etor.ContextState = state;
ChartPlayer.etor.ContextEvent = state.Container;
if (group.State != null) ChartPlayer.etor.ContextState = group.State;
if (group.Container != null) ChartPlayer.etor.ContextEvent = group.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);
}
for (int i = 0; i < stack.Elements.Count; i++) {
DynamicElement e = stack.Elements[i];
@@ -88,13 +88,13 @@ 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(
if (nctx != null) MatchDynamic(e.Element, group, nstack, new RuntimeSkinContext(
nctx, e.Context, e.Selectors.annotations.Contains("if"), e.Selectors.annotations.Contains("then")
));
if (psrcs != null) ChartPlayer.etor.ContextCascadeDiscard();
@@ -103,18 +103,18 @@ namespace Cryville.Crtr {
ChartPlayer.etor.ContextState = null;
Profiler.EndSample();
}
void MatchDynamic(SkinElement rel, ContainerState state, DynamicStack stack, RuntimeSkinContext ctx) {
void MatchDynamic(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.ExecuteDynamic(state, ctx, p.Value);
p.Key.ExecuteDynamic(group, ctx, p.Value);
}
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)) {
SkinContext nctx = e.Key.MatchDynamic(group, rc);
if (nctx != null) MatchDynamic(e.Value, group, stack, new RuntimeSkinContext(
nctx, ctx, e.Key.annotations.Contains("if"), e.Key.annotations.Contains("then")
));
}
@@ -162,4 +162,15 @@ namespace Cryville.Crtr {
}
}
}
public interface ISkinnableGroup {
int DynamicLevel { get; }
string TypeName { get; }
ContainerState State { get; }
EventContainer Container { 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);
}
}

View File

@@ -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);
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) {
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) {
var prop = GetPropOp(ctx.WriteTransform);
if (state.CloneType > prop.UpdateCloneType) return;
if (group.DynamicLevel > 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) {
throw new InvalidOperationException("Anchor creation in dynamic context is not allowed");
}
}
@@ -83,18 +82,18 @@ 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) {
if (group.DynamicLevel > 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 {
@@ -104,10 +103,10 @@ namespace Cryville.Crtr {
return string.Format("@emit {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) {
// TODO
}
public override void ExecuteDynamic(ContainerState state, RuntimeSkinContext ctx, PdtExpression exp) {
public override void ExecuteDynamic(ISkinnableGroup group, RuntimeSkinContext ctx, PdtExpression exp) {
// TODO
}
}

View File

@@ -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) {
foreach (var s in selectors)
if (!s.IsUpdatable(h)) return false;
if (!s.IsUpdatable(g)) 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) {
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) {
return g.DynamicLevel >= 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>();
}
}
}