[update] Improved specs of ScheduledController's protected methods.

This commit is contained in:
falsycat 2019-10-06 00:00:00 +00:00
parent a85dcb8f3e
commit 3216a4eadd
2 changed files with 37 additions and 26 deletions

View File

@ -1,6 +1,8 @@
/// License: MIT /// License: MIT
module sjplayer.CircleElementScheduledController; module sjplayer.CircleElementScheduledController;
import std.typecons;
import gl4d; import gl4d;
import sjscript; import sjscript;
@ -32,16 +34,15 @@ class CircleElementScheduledController :
element_.weight = 1; element_.weight = 1;
element_.smooth = 0.01; element_.smooth = 0.01;
element_.color = vec4(1, 1, 1, 1); element_.color = vec4(1, 1, 1, 1);
super.PrepareOperation(params);
} }
override void FinalizeOperation(ref in ParametersBlock params) { override void FinalizeOperation(ref in ParametersBlock params) {
element_.alive = false; element_.alive = false;
} }
override float GetVariable(string name) const { override void SetParameter(Nullable!float time, ref in Parameter param) {
throw new Exception("not implemented"); // TODO: // TODO:
} super.SetParameter(time, param);
override void SetParameter(ref in Parameter param) {
throw new Exception("not implemented"); // TODO:
} }
private: private:

View File

@ -4,7 +4,8 @@ module sjplayer.ScheduledControllerInterface;
import std.algorithm, import std.algorithm,
std.array, std.array,
std.exception, std.exception,
std.format; std.format,
std.typecons;
import sjscript; import sjscript;
@ -34,7 +35,7 @@ abstract class AbstractScheduledController : ScheduledControllerInterface {
const last_operation = &operations_[next_operation_index_-1]; const last_operation = &operations_[next_operation_index_-1];
if (IsTimeInPeriod(time, last_operation.period)) { if (IsTimeInPeriod(time, last_operation.period)) {
ProcessOperation(*last_operation); ProcessOperation(time, *last_operation);
return; return;
} }
FinalizeOperation(*last_operation); FinalizeOperation(*last_operation);
@ -45,7 +46,7 @@ abstract class AbstractScheduledController : ScheduledControllerInterface {
const next_operation = &operations_[next_operation_index_]; const next_operation = &operations_[next_operation_index_];
if (IsTimeInPeriod(time, next_operation.period)) { if (IsTimeInPeriod(time, next_operation.period)) {
PrepareOperation(*next_operation); PrepareOperation(*next_operation);
ProcessOperation(*next_operation); ProcessOperation(time, *next_operation);
++next_operation_index_; ++next_operation_index_;
} }
} }
@ -53,7 +54,7 @@ abstract class AbstractScheduledController : ScheduledControllerInterface {
protected: protected:
abstract void PrepareOperation(ref in ParametersBlock params); abstract void PrepareOperation(ref in ParametersBlock params);
abstract void ProcessOperation(ref in ParametersBlock params); abstract void ProcessOperation(float time, ref in ParametersBlock params);
abstract void FinalizeOperation(ref in ParametersBlock params); abstract void FinalizeOperation(ref in ParametersBlock params);
@ -79,31 +80,40 @@ abstract class AbstractScheduledControllerWithOperationImpl :
static struct VarStore { static struct VarStore {
public: public:
float opIndex(string name) { float opIndex(string name) {
float result = void; if (!time_.isNull && name == "time") return time_.get;
if (!this_.GetVariable(name).collectException(result)) return result; return this_.GetVariable(name);
if (!this_.varstore_[name] .collectException(result)) return result;
if (!this_.user_vars_[name] .collectException(result)) return result;
throw new Exception("unknown variable %s".format(name));
} }
private: private:
AbstractScheduledControllerWithOperationImpl this_; AbstractScheduledControllerWithOperationImpl this_;
Nullable!float time_;
} }
override void ProcessOperation(ref in ParametersBlock params) { override void PrepareOperation(ref in ParametersBlock params) {
foreach (const ref param; params.parameters) { params.parameters.
if (param.name.length >= 2 && param.name[0..2] == "__") { filter!(x => x.type == ParameterType.OnceAssign).
user_vars_[param.name[2..$]] = each !(x => SetParameter(Nullable!float.init, x));
param.rhs.CalculateExpression(VarStore(this)); }
continue; override void ProcessOperation(float time, ref in ParametersBlock params) {
} params.parameters.
SetParameter(param); filter!(x => x.type != ParameterType.OnceAssign).
each !(x => SetParameter(time.nullable, x));
}
float GetVariable(string name) const {
if (name in user_vars_) return user_vars_[name];
return varstore_[name];
}
void SetParameter(Nullable!float time, ref in Parameter param) {
(param.name.length >= 2 && param.name[0..2] == "__").
enforce("user defined variables must be prefixed '__'");
auto value = param.rhs.CalculateExpression(VarStore(this, time));
if (param.type == ParameterType.AddAssign) {
value += user_vars_[param.name];
} }
user_vars_[param.name] = value;
} }
abstract float GetVariable(string name) const;
abstract void SetParameter(ref in Parameter param);
private: private:
const VarStoreInterface varstore_; const VarStoreInterface varstore_;