Browse Source

Use Module::Expander struct for accessing expander messages.

tags/v1.0.0
Andrew Belt 5 years ago
parent
commit
54544bbe93
4 changed files with 63 additions and 71 deletions
  1. +33
    -30
      include/engine/Module.hpp
  2. +2
    -2
      src/app/RackWidget.cpp
  3. +22
    -33
      src/engine/Engine.cpp
  4. +6
    -6
      src/engine/Module.cpp

+ 33
- 30
include/engine/Module.hpp View File

@@ -37,36 +37,39 @@ struct Module {
std::vector<Light> lights;
std::vector<ParamQuantity*> paramQuantities;

/** ID of the Module immediately to the left, or -1 if nonexistent. */
int leftModuleId = -1;
/** Pointer to the left Module, or NULL if nonexistent. */
Module *leftModule = NULL;
/** Double buffer for receiving messages from the left adjacent module.
If this module intends to receive messages from the left, allocate both message buffers with identical blocks of memory (arrays, structs, etc).
Remember to free the buffer in the Module destructor.
Example:

leftProducerMessage = new MyModuleMessage;
leftConsumerMessage = new MyModuleMessage;

Modules must check a foreign module's `model` before attempting to write its message buffer.
Once the module is checked, you can reinterpret_cast its leftProducerMessage for speed.

Once you write a message, set leftMessageFlipRequested to true, to request that the messages are flipped at the end of the timestep.
Thus, message-passing has 1-sample latency.

You may choose for the Module to write to its own message buffer for consumption by other modules, i.e. "pull" rather than "push".
As long as this convention is followed by the left module, this is fine.
*/
void *leftProducerMessage = NULL;
void *leftConsumerMessage = NULL;
bool leftMessageFlipRequested = false;

int rightModuleId = -1;
Module *rightModule = NULL;
void *rightProducerMessage = NULL;
void *rightConsumerMessage = NULL;
bool rightMessageFlipRequested = true;
/** Represents a message-passing channel for an adjacent module. */
struct Expander {
/** ID of the expander module, or -1 if nonexistent. */
int moduleId = -1;
/** Pointer to the expander Module, or NULL if nonexistent. */
Module *module = NULL;
/** Double buffer for receiving messages from the expander module.
If you intend to receive messages from an expander, allocate both message buffers with identical blocks of memory (arrays, structs, etc).
Remember to free the buffer in the Module destructor.
Example:

rightExpander.producerMessage = new MyExpanderMessage;
rightExpander.consumerMessage = new MyExpanderMessage;

You must check the expander module's `model` before attempting to write its message buffer.
Once the module is checked, you can reinterpret_cast its producerMessage at no performance cost.

Producer messages are intended to be write-only.
Consumer messages are intended to be read-only.

Once you write a message, set messageFlipRequested to true to request that the messages are flipped at the end of the timestep.
This means that message-passing has 1-sample latency.

You may choose for your Module to instead write to its own message buffer for consumption by other modules, i.e. the expander "pulls" rather than this module "pushing".
As long as this convention is followed by the other module, this is fine.
*/
void *producerMessage = NULL;
void *consumerMessage = NULL;
bool messageFlipRequested = false;
};

Expander leftExpander;
Expander rightExpander;

/** Seconds spent in the process() method, with exponential smoothing.
Only written when CPU timing is enabled, since time measurement is expensive.


+ 2
- 2
src/app/RackWidget.cpp View File

@@ -352,8 +352,8 @@ static void RackWidget_updateAdjacent(RackWidget *that) {
}

ModuleWidget *mw = dynamic_cast<ModuleWidget*>(w);
mw->module->rightModuleId = mwRight ? mwRight->module->id : -1;
mw->module->leftModuleId = mwLeft ? mwLeft->module->id : -1;
mw->module->leftExpander.moduleId = mwLeft ? mwLeft->module->id : -1;
mw->module->rightExpander.moduleId = mwRight ? mwRight->module->id : -1;
}
}



+ 22
- 33
src/engine/Engine.cpp View File

@@ -305,39 +305,26 @@ static void Engine_step(Engine *that) {

// Flip messages for each module
for (Module *module : that->internal->modules) {
if (module->leftMessageFlipRequested) {
std::swap(module->leftProducerMessage, module->leftConsumerMessage);
module->leftMessageFlipRequested = false;
if (module->leftExpander.messageFlipRequested) {
std::swap(module->leftExpander.producerMessage, module->leftExpander.consumerMessage);
module->leftExpander.messageFlipRequested = false;
}
if (module->rightMessageFlipRequested) {
std::swap(module->rightProducerMessage, module->rightConsumerMessage);
module->rightMessageFlipRequested = false;
if (module->rightExpander.messageFlipRequested) {
std::swap(module->rightExpander.producerMessage, module->rightExpander.consumerMessage);
module->rightExpander.messageFlipRequested = false;
}
}
}

static void Engine_updateAdjacent(Engine *that, Module *m) {
// Sync leftModule
if (m->leftModuleId >= 0) {
if (!m->leftModule || m->leftModule->id != m->leftModuleId) {
m->leftModule = that->getModule(m->leftModuleId);
static void Engine_updateExpander(Engine *that, Module::Expander *expander) {
if (expander->moduleId >= 0) {
if (!expander->module || expander->module->id != expander->moduleId) {
expander->module = that->getModule(expander->moduleId);
}
}
else {
if (m->leftModule) {
m->leftModule = NULL;
}
}

// Sync rightModule
if (m->rightModuleId >= 0) {
if (!m->rightModule || m->rightModule->id != m->rightModuleId) {
m->rightModule = that->getModule(m->rightModuleId);
}
}
else {
if (m->rightModule) {
m->rightModule = NULL;
if (expander->module) {
expander->module = NULL;
}
}
}
@@ -411,8 +398,10 @@ static void Engine_run(Engine *that) {
if (!internal->paused) {
std::lock_guard<std::recursive_mutex> lock(internal->mutex);

// Update expander pointers
for (Module *module : internal->modules) {
Engine_updateAdjacent(that, module);
Engine_updateExpander(that, &module->leftExpander);
Engine_updateExpander(that, &module->rightExpander);
}

// Step modules
@@ -532,15 +521,15 @@ void Engine::removeModule(Module *module) {
if (paramHandle->moduleId == module->id)
paramHandle->module = NULL;
}
// Update adjacent modules
// Update expander pointers
for (Module *m : internal->modules) {
if (m->leftModule == module) {
m->leftModuleId = -1;
m->leftModule = NULL;
if (m->leftExpander.module == module) {
m->leftExpander.moduleId = -1;
m->leftExpander.module = NULL;
}
if (m->rightModule == module) {
m->rightModuleId = -1;
m->rightModule = NULL;
if (m->rightExpander.module == module) {
m->rightExpander.moduleId = -1;
m->rightExpander.module = NULL;
}
}
// Trigger Remove event


+ 6
- 6
src/engine/Module.cpp View File

@@ -61,12 +61,12 @@ json_t *Module::toJson() {
}

// leftModuleId
if (leftModuleId >= 0)
json_object_set_new(rootJ, "leftModuleId", json_integer(leftModuleId));
if (leftExpander.moduleId >= 0)
json_object_set_new(rootJ, "leftModuleId", json_integer(leftExpander.moduleId));

// rightModuleId
if (rightModuleId >= 0)
json_object_set_new(rootJ, "rightModuleId", json_integer(rightModuleId));
if (rightExpander.moduleId >= 0)
json_object_set_new(rootJ, "rightModuleId", json_integer(rightExpander.moduleId));

return rootJ;
}
@@ -115,12 +115,12 @@ void Module::fromJson(json_t *rootJ) {
// leftModuleId
json_t *leftModuleIdJ = json_object_get(rootJ, "leftModuleId");
if (leftModuleIdJ)
leftModuleId = json_integer_value(leftModuleIdJ);
leftExpander.moduleId = json_integer_value(leftModuleIdJ);

// rightModuleId
json_t *rightModuleIdJ = json_object_get(rootJ, "rightModuleId");
if (rightModuleIdJ)
rightModuleId = json_integer_value(rightModuleIdJ);
rightExpander.moduleId = json_integer_value(rightModuleIdJ);
}




Loading…
Cancel
Save