diff --git a/sjplayer/src/sjplayer/CircleElement.d b/sjplayer/src/sjplayer/CircleElement.d index 68a4c85..b5ce776 100644 --- a/sjplayer/src/sjplayer/CircleElement.d +++ b/sjplayer/src/sjplayer/CircleElement.d @@ -15,13 +15,20 @@ class CircleElement : ElementInterface { /// static struct Instance { /// this should be transposed - align(1) mat3 matrix; + align(1) mat3 matrix = mat3.identity; /// - align(1) float weight; + align(1) float weight = 1; /// - align(1) float smooth; + align(1) float smooth = 0; /// - align(1) vec4 color; + align(1) vec4 color = vec4(0, 0, 0, 0); + } + + override void Initialize() { + alive = false; + damage = 0; + nearness_coe = 0; + instance = instance.init; } override DamageCalculationResult CalculateDamage(vec2 p1, vec2 p2) const { diff --git a/sjplayer/src/sjplayer/CircleElementScheduledController.d b/sjplayer/src/sjplayer/CircleElementScheduledController.d index 55e6ed8..b298d8d 100644 --- a/sjplayer/src/sjplayer/CircleElementScheduledController.d +++ b/sjplayer/src/sjplayer/CircleElementScheduledController.d @@ -3,71 +3,26 @@ module sjplayer.CircleElementScheduledController; import std.typecons; -import gl4d; - -import sjscript; - import sjplayer.CircleElement, - sjplayer.ScheduledControllerFactory, - sjplayer.ScheduledControllerInterface, - sjplayer.VarStoreInterface, - sjplayer.util.MatrixFactory, - sjplayer.util.Parameter; + sjplayer.ElementScheduledController, + sjplayer.ScheduledControllerFactory; /// -class CircleElementScheduledController : - AbstractScheduledControllerWithOperationImpl { - public: - /// - this( - CircleElement element, - in VarStoreInterface varstore, - in ParametersBlock[] operations) { - super(varstore, operations); - element_ = element; - } - - protected: - override void PrepareOperation(ref in ParametersBlock params) { - element_.alive = true; - element_.damage = 0; - element_.nearness_coe = 0; - element_.matrix = mat3.identity.transposed; - element_.weight = 1; - element_.smooth = 0.01; - element_.color = vec4(1, 1, 1, 1); - - matrix_factory_ = matrix_factory_.init; - - super.PrepareOperation(params); - } - override void ProcessOperation(float time, ref in ParametersBlock params) { - super.ProcessOperation(time, params); - element_.matrix = matrix_factory_.Create().transposed; - } - override void FinalizeOperation(ref in ParametersBlock params) { - element_.alive = false; - } - - override void SetParameter(Nullable!float time, ref in Parameter param) { - auto vars = VarStore(this, time); - switch (param.name) { - case "damage": return param.CalculateParameter(element_.damage, vars); - case "nearness_coe": return param.CalculateParameter(element_.nearness_coe, vars); - case "weight": return param.CalculateParameter(element_.weight, vars); - case "smooth": return param.CalculateParameter(element_.smooth, vars); - default: - } - if (param.CalculateMatrixParameter(matrix_factory_, vars)) return; - - return super.SetParameter(time, param); - } - - private: - CircleElement element_; - - MatrixFactory matrix_factory_; -} +alias CircleElementScheduledController = ElementScheduledController!( + CircleElement, + [ + "damage": "damage", + "nearness_coe": "nearness_coe", + "weight": "weight", + "smooth": "smooth", + "color_r": "color.r", + "color_g": "color.g", + "color_b": "color.b", + "color_a": "color.a", + ] + ); +static assert(CircleElementScheduledController.AliveManagementAvailable); +static assert(CircleElementScheduledController.MatrixModificationAvailable); /// alias CircleElementScheduledControllerFactory = diff --git a/sjplayer/src/sjplayer/ElementInterface.d b/sjplayer/src/sjplayer/ElementInterface.d index 5ed8a58..b52c6e0 100644 --- a/sjplayer/src/sjplayer/ElementInterface.d +++ b/sjplayer/src/sjplayer/ElementInterface.d @@ -14,6 +14,9 @@ interface ElementInterface { float nearness; } + /// + void Initialize(); + /// DamageCalculationResult CalculateDamage(vec2 p1, vec2 p2) const; } diff --git a/sjplayer/src/sjplayer/ElementScheduledController.d b/sjplayer/src/sjplayer/ElementScheduledController.d new file mode 100644 index 0000000..707f4af --- /dev/null +++ b/sjplayer/src/sjplayer/ElementScheduledController.d @@ -0,0 +1,94 @@ +/// License: MIT +module sjplayer.ElementScheduledController; + +import std.traits, + std.typecons; + +import gl4d; + +import sjscript; + +import sjplayer.ElementInterface, + sjplayer.ScheduledControllerInterface, + sjplayer.VarStoreInterface, + sjplayer.util.MatrixFactory, + sjplayer.util.Parameter; + +/// +class ElementScheduledController( + Element, string[string] ParameterNameMap) : + AbstractScheduledControllerWithOperationImpl + if (is(Element : ElementInterface)) { + public: + /// + enum AliveManagementAvailable = + is(typeof((Element e) => e.alive)) && + is(ReturnType!((Element e) => e.alive) == bool); + /// + enum MatrixModificationAvailable = + is(typeof((Element e) => e.matrix)) && + is(ReturnType!((Element e) => e.matrix) == mat3); + + /// + this( + Element element, + in VarStoreInterface varstore, + in ParametersBlock[] operations) { + super(varstore, operations); + element_ = element; + } + + protected: + override void PrepareOperation(ref in ParametersBlock params) { + element_.Initialize(); + static if (AliveManagementAvailable) { + element_.alive = true; + } + static if (MatrixModificationAvailable) { + matrix_factory_ = matrix_factory_.init; + } + super.PrepareOperation(params); + } + override void ProcessOperation(float time, ref in ParametersBlock params) { + super.ProcessOperation(time, params); + static if (MatrixModificationAvailable) { + element_.matrix = matrix_factory_.Create().transposed; + } + } + override void FinalizeOperation(ref in ParametersBlock params) { + static if (AliveManagementAvailable) { + element_.alive = false; + } + } + + override float GetVariable(string name) const { + switch (name) { + static foreach (map_name, code; ParameterNameMap) { + case map_name: + return mixin("element_."~code); + } + default: return super.GetVariable(name); + } + } + override void SetParameter(Nullable!float time, ref in Parameter param) { + auto vars = VarStore(this, time); + switch (param.name) { + static foreach (map_name, code; ParameterNameMap) { + case map_name: + param.CalculateParameter(mixin("element_."~code), vars); + return; + } + default: + } + static if (MatrixModificationAvailable) { + if (param.CalculateMatrixParameter(matrix_factory_, vars)) return; + } + super.SetParameter(time, param); + } + + Element element_; + + static if (MatrixModificationAvailable) { + MatrixFactory matrix_factory_; + } +}