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; namespace Cryville.Crtr { public class Ruleset : MetaInfo { public const long CURRENT_FORMAT = 2; [JsonRequired] public long format; public string @base; [JsonIgnore] public PdtRuleset Root { get; private set; } 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(); } } } [Binder(typeof(PdtBinder))] public class PdtRuleset { public Dictionary inputs; public Dictionary judges; public Dictionary 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 j in judges.Values) { if (j.hit != null) etor.Optimize(j.hit); if (j.scores != null) { foreach (var s in j.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); } constraints.Optimize(etor); } public void PrePatch(Chart chart) { constraints.PrePatch(chart); } } public class Constraint { static readonly PropOp.Arbitrary _arbop = new PropOp.Arbitrary(); [ElementList] public Dictionary Elements = new Dictionary(); [PropertyList] public Dictionary Properties = new Dictionary(); public void Optimize(PdtEvaluatorBase etor) { foreach (var e in Properties.Values) { etor.Optimize(e); } foreach (var e in Elements) { e.Key.Optimize(etor); e.Value.Optimize(etor); } } public void PrePatch(ChartEvent ev) { var etor = ChartPlayer.etor; PropSrc src; etor.ContextCascadeInsert(); etor.ContextEvent = ev; foreach (var prop in Properties) { var name = prop.Key.Name; switch (prop.Key.Type) { case PropertyType.Property: if (ev.PropSrcs.TryGetValue(name, out src)) etor.ContextSelfValue = src; etor.Evaluate(ev.PropOps[name], prop.Value); etor.ContextSelfValue = null; break; case PropertyType.Variable: _arbop.Name = name; etor.Evaluate(_arbop, prop.Value); break; default: throw new NotSupportedException("Unknown property key type"); } } etor.ContextEvent = null; foreach (var el in Elements) { var targets = el.Key.Match(ev); if (targets == null) continue; foreach (var target in targets) el.Value.PrePatch(target); } etor.ContextCascadeDiscard(); } } public class PropertyKey { public PropertyType Type { get; private set; } public int Name { get; private set; } public PropertyKey(PropertyType type, string name) { Type = type; Name = IdentifierManager.SharedInstance.Request(name); } public override string ToString() { switch (Type) { case PropertyType.Property: return (string)IdentifierManager.SharedInstance.Retrieve(Name); case PropertyType.Variable: return string.Format("@var {0}", IdentifierManager.SharedInstance.Retrieve(Name)); default: return string.Format("<{0}> {1}", Type, IdentifierManager.SharedInstance.Retrieve(Name)); } } } public enum PropertyType { Property, Variable, } public class RulesetViolationException : Exception { public RulesetViolationException() { } public RulesetViolationException(string message) : base(message) { } public RulesetViolationException(string message, Exception innerException) : base(message, innerException) { } } }