[update] Unified ScheduledControllerFactory module into ElementScheduledController.

This commit is contained in:
falsycat 2019-10-07 00:00:00 +00:00
parent 16fdc64281
commit cdb2c80b65
3 changed files with 90 additions and 101 deletions

View File

@ -4,8 +4,7 @@ module sjplayer.CircleElementScheduledController;
import std.typecons; import std.typecons;
import sjplayer.CircleElement, import sjplayer.CircleElement,
sjplayer.ElementScheduledController, sjplayer.ElementScheduledController;
sjplayer.ScheduledControllerFactory;
/// ///
alias CircleElementScheduledController = ElementScheduledController!( alias CircleElementScheduledController = ElementScheduledController!(

View File

@ -1,18 +1,26 @@
/// License: MIT /// License: MIT
module sjplayer.ElementScheduledController; module sjplayer.ElementScheduledController;
import std.traits, import std.algorithm,
std.array,
std.conv,
std.meta,
std.range.primitives,
std.traits,
std.typecons; std.typecons;
import gl4d; import gl4d;
import sjscript; import sjscript;
import sjplayer.ElementInterface, import sjplayer.ContextBuilderInterface,
sjplayer.ElementInterface,
sjplayer.ProgramSet,
sjplayer.ScheduledControllerInterface, sjplayer.ScheduledControllerInterface,
sjplayer.VarStoreInterface, sjplayer.VarStoreInterface,
sjplayer.util.MatrixFactory, sjplayer.util.MatrixFactory,
sjplayer.util.Parameter; sjplayer.util.Parameter,
sjplayer.util.Period;
/// ///
class ElementScheduledController( class ElementScheduledController(
@ -91,3 +99,81 @@ class ElementScheduledController(
MatrixFactory matrix_factory_; MatrixFactory matrix_factory_;
} }
} }
///
struct ElementScheduledControllerFactory(ScheduledController, ElementDrawer)
if (is(ScheduledController : ScheduledControllerInterface) &&
is(ElementDrawer : ElementDrawerInterface)) {
public:
/// ScheduledController's first constructor's first argument type.
alias Element =
Parameters!(__traits(getOverloads, ScheduledController, "__ctor")[0])[0];
static assert(is(Element : ElementInterface));
/// ElementDrawer's first constructor's first argument type.
alias ElementProgram =
Parameters!(__traits(getOverloads, ElementDrawer, "__ctor")[0])[0];
static assert(staticIndexOf!(
ElementProgram, ProgramSet.Programs.Types) >= 0);
static assert(is(Element[] :
Parameters!(__traits(getOverloads, ElementDrawer, "__ctor")[0])[1]));
///
this(ProgramSet programs, VarStoreInterface varstore) {
program_ = programs.Get!ElementProgram;
varstore_ = varstore;
}
///
void Create(R)(R params, ContextBuilderInterface builder)
if (isInputRange!R && is(ElementType!R == ParametersBlock)) {
auto parallelized = params.ParallelizeParams();
auto elements = appender!(Element[]);
foreach (ref serial; parallelized) {
auto element = new Element;
elements ~= element;
builder.AddElement(element);
builder.AddScheduledController(
new ScheduledController(element, varstore_, serial));
}
if (elements[].length > 0) {
builder.AddElementDrawer(new ElementDrawer(program_, elements[]));
}
}
private:
ElementProgram program_;
VarStoreInterface varstore_;
}
private ParametersBlock[][] ParallelizeParams(R)(R params)
if (isInputRange!R && is(ElementType!R == ParametersBlock)) {
ParametersBlock[][] parallelized;
foreach (ref param; params) {
auto inserted = false;
foreach (ref serial; parallelized) {
const found_index = serial.
countUntil!(x => x.period.start > param.period.start);
const insert_index =
found_index >= 0? found_index.to!size_t: serial.length;
const intersect_prev = insert_index >= 1 &&
IsPeriodIntersectedToPeriod(serial[insert_index-1].period, param.period);
const intersect_next = insert_index < serial.length &&
IsPeriodIntersectedToPeriod(serial[insert_index].period, param.period);
if (!intersect_prev && !intersect_next) {
serial = serial[0..insert_index]~ param ~serial[insert_index..$];
inserted = true;
break;
}
}
if (!inserted) {
parallelized ~= [param];
}
}
return parallelized;
}

View File

@ -1,96 +0,0 @@
/// License: MIT
module sjplayer.ScheduledControllerFactory;
import std.algorithm,
std.array,
std.conv,
std.meta,
std.range.primitives,
std.traits;
import sjscript;
import sjplayer.ContextBuilderInterface,
sjplayer.ElementInterface,
sjplayer.ProgramSet,
sjplayer.ScheduledControllerInterface,
sjplayer.VarStoreInterface,
sjplayer.util.Period;
///
struct ElementScheduledControllerFactory(ScheduledController, ElementDrawer)
if (is(ScheduledController : ScheduledControllerInterface) &&
is(ElementDrawer : ElementDrawerInterface)) {
public:
/// ScheduledController's first constructor's first argument type.
alias Element =
Parameters!(__traits(getOverloads, ScheduledController, "__ctor")[0])[0];
static assert(is(Element : ElementInterface));
/// ElementDrawer's first constructor's first argument type.
alias ElementProgram =
Parameters!(__traits(getOverloads, ElementDrawer, "__ctor")[0])[0];
static assert(staticIndexOf!(
ElementProgram, ProgramSet.Programs.Types) >= 0);
static assert(is(Element[] :
Parameters!(__traits(getOverloads, ElementDrawer, "__ctor")[0])[1]));
///
this(ProgramSet programs, VarStoreInterface varstore) {
program_ = programs.Get!ElementProgram;
varstore_ = varstore;
}
///
void Create(R)(R params, ContextBuilderInterface builder)
if (isInputRange!R && is(ElementType!R == ParametersBlock)) {
auto parallelized = params.ParallelizeParams();
auto elements = appender!(Element[]);
foreach (ref serial; parallelized) {
auto element = new Element;
elements ~= element;
builder.AddElement(element);
builder.AddScheduledController(
new ScheduledController(element, varstore_, serial));
}
if (elements[].length > 0) {
builder.AddElementDrawer(new ElementDrawer(program_, elements[]));
}
}
private:
ElementProgram program_;
VarStoreInterface varstore_;
}
private ParametersBlock[][] ParallelizeParams(R)(R params)
if (isInputRange!R && is(ElementType!R == ParametersBlock)) {
ParametersBlock[][] parallelized;
foreach (ref param; params) {
auto inserted = false;
foreach (ref serial; parallelized) {
const found_index = serial.
countUntil!(x => x.period.start > param.period.start);
const insert_index =
found_index >= 0? found_index.to!size_t: serial.length;
const intersect_prev = insert_index >= 1 &&
IsPeriodIntersectedToPeriod(serial[insert_index-1].period, param.period);
const intersect_next = insert_index < serial.length &&
IsPeriodIntersectedToPeriod(serial[insert_index].period, param.period);
if (!intersect_prev && !intersect_next) {
serial = serial[0..insert_index]~ param ~serial[insert_index..$];
inserted = true;
break;
}
}
if (!inserted) {
parallelized ~= [param];
}
}
return parallelized;
}