[update] Improved the exception handlings in sjplayer.

This commit is contained in:
falsycat 2019-10-10 00:00:00 +00:00
parent 109ae328b8
commit 79bfed8d19
5 changed files with 64 additions and 19 deletions

View File

@ -4,12 +4,14 @@ module sjplayer.AbstractScheduledController;
import std.algorithm,
std.array,
std.exception,
std.format,
std.range.primitives,
std.typecons;
import sjscript;
import sjplayer.ScheduledControllerInterface,
import sjplayer.ScriptRuntimeException,
sjplayer.ScheduledControllerInterface,
sjplayer.VarStoreInterface,
sjplayer.util.Parameter,
sjplayer.util.Period;
@ -34,23 +36,31 @@ abstract class AbstractScheduledController : ScheduledControllerInterface {
public:
float opIndex(string name) const {
if (!time_.isNull && name == "time") return time_.get;
return this_.GetVariable(name);
const temp = this_.GetVariable(name);
if (!temp.isNull) return temp.get;
throw new ScriptRuntimeException(
"unknown variable `%s`".format(name), srcline_, srcchar_);
}
private:
AbstractScheduledController this_;
Nullable!float time_;
size_t srcline_, srcchar_;
}
void PrepareOperation(ref in ParametersBlock params) {
user_vars_.clear();
auto vars = VarStore(this);
auto vars = VarStore(
this, Nullable!float.init, params.pos.stline, params.pos.stchar);
params.parameters.
filter!(x => x.type == ParameterType.OnceAssign).
each !(x => SetParameter(x, vars));
}
void ProcessOperation(float time, ref in ParametersBlock params) {
auto vars = VarStore(this, time.nullable);
auto vars = VarStore(
this, time.nullable, params.pos.stline, params.pos.stchar);
params.parameters.
filter!(x => x.type != ParameterType.OnceAssign).
each !(x => SetParameter(x, vars));
@ -58,13 +68,21 @@ abstract class AbstractScheduledController : ScheduledControllerInterface {
void FinalizeOperation(ref in ParametersBlock params) {
}
float GetVariable(string name) const {
if (name in user_vars_) return user_vars_[name];
return varstore_[name];
Nullable!float GetVariable(string name) const {
if (name in user_vars_) {
return Nullable!float(user_vars_[name]);
}
auto temp = varstore_[name];
if (!temp.isNull) return temp;
// TODO: std constants
return Nullable!float.init;
}
void SetParameter(ref in Parameter param, ref in VarStore vars) {
(param.name.length >= 2 && param.name[0..2] == "__").
enforce("user defined variables must be prefixed '__'");
if (param.name.length < 2 || param.name[0..2] != "__") {
throw new ScriptRuntimeException(
"user defined variables must be prefixed as '__'",
param.pos.stline, param.pos.stchar);
}
user_vars_[param.name] = 0;
param.CalculateParameter(user_vars_[param.name], vars);
}
@ -114,7 +132,11 @@ ParametersBlock[] SortParametersBlock(R)(R params)
auto before = Period(-1, 0);
foreach (param; result) {
(!param.period.IsPeriodIntersectedToPeriod(before)).enforce();
if (param.period.IsPeriodIntersectedToPeriod(before)) {
throw new ScriptRuntimeException(
"the period is duplicated",
param.pos.stline, param.pos.stchar);
}
}
return result;
}

View File

@ -64,17 +64,17 @@ class ScheduledController(
}
}
override float GetVariable(string name) const {
override Nullable!float GetVariable(string name) const {
switch (name) {
static foreach (map_name, code; ParameterNameMap) {
case map_name:
return mixin("target_."~code);
return Nullable!float(mixin("target_."~code));
}
default:
}
static if (MatrixModificationAvailable) {
const value = matrix_factory_.GetValueByName(name);
if (!value.isNull) return value.get;
if (!value.isNull) return value;
}
return super.GetVariable(name);
}

View File

@ -0,0 +1,20 @@
/// License: MIT
module sjplayer.ScriptRuntimeException;
import sjscript;
///
class ScriptRuntimeException : Exception {
public:
///
this(
string msg, size_t srcline, size_t srcchar,
string file = __FILE__, size_t line = __LINE__) {
super(msg, file, line);
this.srcline = srcline;
this.srcchar = srcchar;
}
///
size_t srcline, srcchar;
}

View File

@ -2,7 +2,8 @@
module sjplayer.VarStore;
import std.exception,
std.format;
std.format,
std.typecons;
import sjplayer.Actor,
sjplayer.VarStoreInterface;
@ -15,12 +16,12 @@ class VarStore : VarStoreInterface {
actor_ = actor;
}
override float opIndex(string name) const {
override Nullable!float opIndex(string name) const {
switch (name) {
case "actor_x": return actor_.pos.x;
case "actor_y": return actor_.pos.y;
case "actor_x": return Nullable!float(actor_.pos.x);
case "actor_y": return Nullable!float(actor_.pos.y);
default: throw new Exception("unknown variable %s".format(name));
default: return Nullable!float.init;
}
}

View File

@ -1,11 +1,13 @@
/// License: MIT
module sjplayer.VarStoreInterface;
import std.typecons;
import sjscript;
///
interface VarStoreInterface {
public:
///
float opIndex(string name) const;
Nullable!float opIndex(string name) const;
}