diff --git a/.gitignore b/.gitignore index b2ed1d2..4cf90c5 100644 --- a/.gitignore +++ b/.gitignore @@ -6,6 +6,7 @@ node_modules .cljs_node_repl .cpcache .cache +.DS_Store *.swp diff --git a/js/packages/core/__tests__/__snapshots__/core.test.js.snap b/js/packages/core/__tests__/__snapshots__/core.test.js.snap index 3e98a21..24fa4ca 100644 --- a/js/packages/core/__tests__/__snapshots__/core.test.js.snap +++ b/js/packages/core/__tests__/__snapshots__/core.test.js.snap @@ -529,6 +529,9 @@ exports[`garbage collection 1`] = ` exports[`garbage collection 2`] = ` [ + [ + 5, + ], [ 1, 520300429, @@ -537,9 +540,6 @@ exports[`garbage collection 2`] = ` 1, 1423955117, ], - [ - 5, - ], ] `; diff --git a/js/packages/core/index.ts b/js/packages/core/index.ts index 82e8ad2..8281d64 100644 --- a/js/packages/core/index.ts +++ b/js/packages/core/index.ts @@ -75,11 +75,11 @@ class Delegate { this.batch = { createNode: [], - deleteNode: [], appendChild: [], setProperty: [], activateRoots: [], commitUpdates: [], + deleteNode: [] }; } @@ -128,11 +128,11 @@ class Delegate { getPackedInstructions() { return [ ...this.batch.createNode, - ...this.batch.deleteNode, ...this.batch.appendChild, ...this.batch.setProperty, ...this.batch.activateRoots, ...this.batch.commitUpdates, + ...this.batch.deleteNode, ]; } } diff --git a/runtime/elem/GraphRenderSequence.h b/runtime/elem/GraphRenderSequence.h index 9432fd5..eae39e7 100644 --- a/runtime/elem/GraphRenderSequence.h +++ b/runtime/elem/GraphRenderSequence.h @@ -92,9 +92,9 @@ namespace elem // Next we prepare the render operation bufferMap.emplace(node->getId(), ba.next()); + auto* outputData = bufferMap.at(node->getId()); - renderOps.push_back([=, bufferMap = this->bufferMap](HostContext& ctx) { - auto* outputData = bufferMap.at(node->getId()); + renderOps.push_back([=](HostContext& ctx) { node->process(BlockContext { ctx.inputData, @@ -117,18 +117,18 @@ namespace elem } // Next we prepare the render operation - bufferMap.emplace(node->getId(), ba.next()); + auto* outputData = ba.next(); + bufferMap.emplace(node->getId(), outputData); // Allocate room for the child pointers here, gets moved into the lambda capture group below std::vector ptrs(children.size()); + auto const numChildren = children.size(); - renderOps.push_back([=, bufferMap = this->bufferMap, ptrs = std::move(ptrs)](HostContext& ctx) mutable { - auto* outputData = bufferMap.at(node->getId()); - auto const numChildren = children.size(); + for (size_t j = 0; j < numChildren; ++j) { + ptrs[j] = bufferMap.at(children[j]); + } - for (size_t j = 0; j < numChildren; ++j) { - ptrs[j] = bufferMap.at(children[j]); - } + renderOps.push_back([=, ptrs = std::move(ptrs)](HostContext& ctx) mutable { node->process(BlockContext { const_cast(ptrs.data()), diff --git a/runtime/elem/Runtime.h b/runtime/elem/Runtime.h index 051393e..b6a1b06 100644 --- a/runtime/elem/Runtime.h +++ b/runtime/elem/Runtime.h @@ -332,42 +332,68 @@ namespace elem // Populate and activate from the incoming event std::set active; - for (auto const& v : roots) { + for (auto const& v : roots) + { if (!v.isNumber()) + { + ELEM_DBG("[Error] activateRoot - Invalid nodeId format."); return ReturnCode::InvalidInstructionFormat(); + } - int32_t nodeId = static_cast((js::Number) v); + int32_t nodeId = static_cast((js::Number)v); ELEM_DBG("[Native] activateRoot " << nodeIdToHex(nodeId)); - if (nodeTable.find(nodeId) == nodeTable.end()) + // Using find() method for safe access to nodeTable elements + auto it = nodeTable.find(nodeId); + if (it == nodeTable.end()) + { + ELEM_DBG("[Error] activateRoot - NodeId not found: " << nodeIdToHex(nodeId)); return ReturnCode::NodeNotFound(); + } - if (auto ptr = std::dynamic_pointer_cast>(nodeTable.at(nodeId))) { - ptr->setProperty("active", true); + // Attempt to cast the found node to a RootNode type and activate it + auto ptr = std::dynamic_pointer_cast>(it->second); + if (ptr) + { + ptr->activate(currentRoots.empty() ? FloatType(1) : FloatType(0)); active.insert(nodeId); + ELEM_DBG("[Success] Activated root: " << nodeIdToHex(nodeId)); + } + else + { + ELEM_DBG("[Error] Failed to cast to RootNode or activate: " << nodeIdToHex(nodeId)); } } - // Deactivate any prior roots - for (auto const& n : currentRoots) { - if (auto ptr = std::dynamic_pointer_cast>(nodeTable.at(n))) { + // Deactivate any prior roots not included in the incoming active set + for (auto const& n : currentRoots) + { + auto it = nodeTable.find(n); + if (it != nodeTable.end()) + { + auto ptr = std::dynamic_pointer_cast>(it->second); // If any current root was not marked active in this event, we deactivate it - if (active.count(n) == 0) { - ptr->setProperty("active", false); - } - - // And if it's still running, we hang onto it - if (ptr->stillRunning()) { - active.insert(n); + if (ptr) + { + if (active.count(n) == 0) + { + ptr->setProperty("active", false); + ELEM_DBG("[Success] Deactivated root: " << nodeIdToHex(n)); + } + // And if it's still running, we hang onto it + if (ptr->stillRunning()) + { + active.insert(n); + } } } } - // Merge - currentRoots = active; + currentRoots.swap(active); return ReturnCode::Ok(); } + //============================================================================== template void Runtime::processQueuedEvents(std::function&& evtCallback) diff --git a/runtime/elem/builtins/Core.h b/runtime/elem/builtins/Core.h index 89ce2f5..f0845c6 100644 --- a/runtime/elem/builtins/Core.h +++ b/runtime/elem/builtins/Core.h @@ -32,6 +32,12 @@ namespace elem return (t >= 0.5 || (std::abs(c - t) >= std::numeric_limits::epsilon())); } + void activate(FloatType initialGain = FloatType(0)) + { + setProperty("active", true); + currentGain.store(initialGain); + } + int setProperty(std::string const& key, js::Value const& val) override { if (key == "active") {