Files
crtr/Assets/Cryville/Crtr/Skin.cs

148 lines
3.8 KiB
C#

using Cryville.Common;
using Cryville.Common.Collections.Generic;
using Cryville.Common.Pdt;
using Cryville.Crtr.Extension;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
namespace Cryville.Crtr {
public class Skin : MetaInfo {
public const long CURRENT_FORMAT = 2;
[JsonRequired]
public long format;
public string @base;
[JsonRequired]
public string ruleset;
public List<string> frames = new List<string>();
[JsonIgnore]
public PdtSkin Root { get; private set; }
public void LoadPdt(DirectoryInfo dir) {
using (StreamReader pdtreader = new StreamReader(dir.FullName + "/" + data + ".pdt", Encoding.UTF8)) {
var src = pdtreader.ReadToEnd();
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 {
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.ContextCascadeUpdate(EffectInstance._VAR_EFFECT_INDEX, PropSrc.Error);
foreach(var s in effect.states) {
etor.Optimize(s.Value.duration);
}
effect.elements.Optimize(etor);
etor.ContextCascadeDiscard();
}
elements.Optimize(etor);
}
}
public class SkinElement {
[ElementList]
public PairList<SkinSelectors, SkinElement> elements
= new PairList<SkinSelectors, SkinElement>();
[PropertyList]
public PairList<SkinPropertyKey, PdtExpression> properties
= new PairList<SkinPropertyKey, PdtExpression>();
public bool IsDynamic {
get;
private set;
}
public void Optimize(PdtEvaluatorBase etor) {
IsDynamic = true;
foreach (var e in properties) {
etor.Optimize(e.Value);
if (!e.Value.IsConstant)
IsDynamic = true;
}
foreach (var e in elements) {
e.Key.Optimize(etor);
e.Value.Optimize(etor);
if (e.Value.IsDynamic)
IsDynamic = true;
}
}
}
public class EffectDefinition {
static Identifier _ident_init = new Identifier("init");
#pragma warning disable IDE1006
public PdtExpression duration {
set {
EffectState s;
if (!states.TryGetValue(_ident_init, out s))
throw new InvalidOperationException("Cannot set duration and states at the same time");
s.duration = value;
}
}
#pragma warning restore IDE1006
public Identifier init = _ident_init;
public Dictionary<Identifier, EffectState> states = new Dictionary<Identifier, EffectState> {
{ _ident_init, new EffectState() { rewind = _ident_init } }
};
public SkinElement elements;
}
public class EffectState {
public PdtExpression duration;
public Identifier rewind;
public Identifier next;
}
public class AnimationSpan {
[ElementList]
public PairList<Clip, AnimationSpan> spans
= new PairList<Clip, AnimationSpan>();
[PropertyList]
public PairList<SkinPropertyKey, PdtExpression> properties
= new PairList<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);
}
}
}
}