[add] Added ElementScheduledController template class.

This commit is contained in:
falsycat 2019-10-07 00:00:00 +00:00
parent d752f85e39
commit 52187dae9a
4 changed files with 125 additions and 66 deletions

View File

@ -15,13 +15,20 @@ class CircleElement : ElementInterface {
/// ///
static struct Instance { static struct Instance {
/// this should be transposed /// 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 { override DamageCalculationResult CalculateDamage(vec2 p1, vec2 p2) const {

View File

@ -3,71 +3,26 @@ module sjplayer.CircleElementScheduledController;
import std.typecons; import std.typecons;
import gl4d;
import sjscript;
import sjplayer.CircleElement, import sjplayer.CircleElement,
sjplayer.ScheduledControllerFactory, sjplayer.ElementScheduledController,
sjplayer.ScheduledControllerInterface, sjplayer.ScheduledControllerFactory;
sjplayer.VarStoreInterface,
sjplayer.util.MatrixFactory,
sjplayer.util.Parameter;
/// ///
class CircleElementScheduledController : alias CircleElementScheduledController = ElementScheduledController!(
AbstractScheduledControllerWithOperationImpl { CircleElement,
public: [
/// "damage": "damage",
this( "nearness_coe": "nearness_coe",
CircleElement element, "weight": "weight",
in VarStoreInterface varstore, "smooth": "smooth",
in ParametersBlock[] operations) { "color_r": "color.r",
super(varstore, operations); "color_g": "color.g",
element_ = element; "color_b": "color.b",
} "color_a": "color.a",
]
protected: );
override void PrepareOperation(ref in ParametersBlock params) { static assert(CircleElementScheduledController.AliveManagementAvailable);
element_.alive = true; static assert(CircleElementScheduledController.MatrixModificationAvailable);
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 CircleElementScheduledControllerFactory = alias CircleElementScheduledControllerFactory =

View File

@ -14,6 +14,9 @@ interface ElementInterface {
float nearness; float nearness;
} }
///
void Initialize();
/// ///
DamageCalculationResult CalculateDamage(vec2 p1, vec2 p2) const; DamageCalculationResult CalculateDamage(vec2 p1, vec2 p2) const;
} }

View File

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