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.WriteTransform.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) { state.Handler.RegisterAnchor(Name, true); } 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 SetAnchor() { _timeOp = new PropOp.Float(v => _time = v); } 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) { 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; 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); } } public class EmitEffect : SkinPropertyKey { public int Name { get; set; } public EmitEffect() { } public override string ToString() { 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) { // TODO } public override void ExecuteDynamic(ContainerState state, RuntimeSkinContext ctx, PdtExpression exp) { // TODO } } } }