From 9feddfb631c6004b739fc48a638a3ea0082a7443 Mon Sep 17 00:00:00 2001 From: jules Date: Tue, 19 Jun 2018 10:46:44 +0100 Subject: [PATCH] BLOCKS: enabled re-cycling of disconnected Block objects when the same block is re-connected --- .../topology/juce_PhysicalTopologySource.cpp | 175 ++++++++++++------ 1 file changed, 122 insertions(+), 53 deletions(-) diff --git a/modules/juce_blocks_basics/topology/juce_PhysicalTopologySource.cpp b/modules/juce_blocks_basics/topology/juce_PhysicalTopologySource.cpp index e18830c1fd..c65270d70e 100644 --- a/modules/juce_blocks_basics/topology/juce_PhysicalTopologySource.cpp +++ b/modules/juce_blocks_basics/topology/juce_PhysicalTopologySource.cpp @@ -317,6 +317,18 @@ struct PhysicalTopologySource::Internal bool isMaster; }; + static juce::String getVersionString (const BlocksProtocol::VersionNumber& v) + { + return juce::String (reinterpret_cast (v.version), + std::min (sizeof (v.version), static_cast (v.length))); + } + + static juce::String getNameString (const BlocksProtocol::BlockName& n) + { + return juce::String (reinterpret_cast (n.name), + std::min (sizeof (n.name), static_cast (n.length))); + } + static Block::Timestamp deviceTimestampToHost (uint32 timestamp) noexcept { return static_cast (timestamp); @@ -363,41 +375,49 @@ struct PhysicalTopologySource::Internal return false; } - static bool versionNumberAddedToBlock (const juce::Array& devices, Block::UID uid, juce::String version) noexcept + static bool versionNumberChanged (const DeviceInfo& device, juce::String version) noexcept { - for (auto&& d : devices) - { - String deviceVersion (reinterpret_cast (d.version.version), - jmin (static_cast (d.version.length), sizeof (d.version.version))); - - if (d.uid == uid && deviceVersion != version && deviceVersion.isNotEmpty()) - return true; - } + auto deviceVersion = getVersionString (device.version); + return deviceVersion != version && deviceVersion.isNotEmpty(); + } - return false; + static bool nameIsValid (const DeviceInfo& device) + { + return device.name.length > 0; } - static bool nameAddedToBlock (const juce::Array& devices, Block::UID uid) noexcept + static void setVersionNumberForBlock (const DeviceInfo& deviceInfo, Block& block) noexcept { - for (auto&& d : devices) - if (d.uid == uid && d.name.length) - return true; + if (deviceInfo.uid != block.uid) + { + jassertfalse; + return; + } - return false; + block.versionNumber = getVersionString (deviceInfo.version); } - static void setVersionNumberForBlock (const juce::Array& devices, Block& block) noexcept + static void setNameForBlock (const juce::Array& devices, Block& block) noexcept { for (auto&& d : devices) + { if (d.uid == block.uid) - block.versionNumber = juce::String ((const char*) d.version.version, d.version.length); + { + setNameForBlock (d, block); + return; + } + } } - static void setNameForBlock (const juce::Array& devices, Block& block) noexcept + static void setNameForBlock (const DeviceInfo& deviceInfo, Block& block) { - for (auto&& d : devices) - if (d.uid == block.uid) - block.name = juce::String ((const char*) d.name.name, d.name.length); + if (deviceInfo.uid != block.uid) + { + jassertfalse; + return; + } + + block.name = getNameString (deviceInfo.name); } //============================================================================== @@ -542,16 +562,9 @@ struct PhysicalTopologySource::Internal void handleVersion (BlocksProtocol::DeviceVersion version) { - for (auto i = 0; i < currentDeviceInfo.size(); ++i) - { - if (currentDeviceInfo[i].index == version.index && version.version.length > 1) - { - if (memcmp (currentDeviceInfo.getReference (i).version.version, version.version.version, sizeof (version.version))) - { - currentDeviceInfo.getReference(i).version = version.version; - } - } - } + for (auto& d : currentDeviceInfo) + if (d.index == version.index && version.version.length > 1) + d.version = version.version; } void notifyDetectorTopologyChanged() @@ -561,16 +574,9 @@ struct PhysicalTopologySource::Internal void handleName (BlocksProtocol::DeviceName name) { - for (auto i = 0; i < currentDeviceInfo.size(); ++i) - { - if (currentDeviceInfo[i].index == name.index && name.name.length > 1) - { - if (memcmp (currentDeviceInfo.getReference (i).name.name, name.name.name, sizeof (name.name))) - { - currentDeviceInfo.getReference (i).name = name.name; - } - } - } + for (auto& d : currentDeviceInfo) + if (d.index == name.index && name.name.length > 1) + d.name = name.name; } void handleControlButtonUpDown (BlocksProtocol::TopologyIndex deviceIndex, uint32 timestamp, @@ -928,29 +934,32 @@ struct PhysicalTopologySource::Internal for (int i = currentTopology.blocks.size(); --i >= 0;) { - auto block = currentTopology.blocks.getUnchecked (i); + auto currentBlock = currentTopology.blocks.getUnchecked (i); + + auto newDeviceIter = std::find_if (newDeviceInfo.begin(), newDeviceInfo.end(), + [&] (DeviceInfo& info) { return info.uid == currentBlock->uid; }); - if (! containsBlockWithUID (newDeviceInfo, block->uid)) + if (newDeviceIter == newDeviceInfo.end()) { - if (auto bi = BlockImplementation::getFrom (*block)) + if (auto bi = BlockImplementation::getFrom (*currentBlock)) bi->invalidate(); - currentTopology.blocks.remove (i); + disconnectedBlocks.addIfNotAlreadyThere (currentTopology.blocks.removeAndReturn (i)); } else { - if (versionNumberAddedToBlock (newDeviceInfo, block->uid, block->versionNumber)) - setVersionNumberForBlock (newDeviceInfo, *block); - - if (nameAddedToBlock (newDeviceInfo, block->uid)) - setNameForBlock (newDeviceInfo, *block); + updateCurrentBlockInfo (currentBlock, *newDeviceIter); } } + static const int maxBlocksToSave = 100; + + if (disconnectedBlocks.size() > maxBlocksToSave) + disconnectedBlocks.removeRange (0, 2 * (disconnectedBlocks.size() - maxBlocksToSave)); + for (auto& info : newDeviceInfo) - if (info.serial.isValid()) - if (! containsBlockWithUID (currentTopology.blocks, getBlockUIDFromSerialNumber (info.serial))) - currentTopology.blocks.add (new BlockImplementation (info.serial, *this, info.version, info.name, info.isMaster)); + if (info.serial.isValid() && ! containsBlockWithUID (currentTopology.blocks, getBlockUIDFromSerialNumber (info.serial))) + addBlock (info); currentTopology.connections.swapWith (newDeviceConnections); } @@ -1136,6 +1145,7 @@ struct PhysicalTopologySource::Internal juce::Array activeTouchSurfaces; BlockTopology currentTopology; + juce::ReferenceCountedArray disconnectedBlocks; private: void timerCallback() override @@ -1194,6 +1204,52 @@ struct PhysicalTopologySource::Internal return false; } + void addBlock (DeviceInfo info) + { + if (! reactivateBlockIfKnown (info)) + addNewBlock (info); + } + + bool reactivateBlockIfKnown (DeviceInfo info) + { + auto uid = getBlockUIDFromSerialNumber (info.serial); + + for (int i = 0; i < disconnectedBlocks.size(); ++i) + { + if (disconnectedBlocks.getUnchecked (i)->uid == uid) + { + auto block = disconnectedBlocks.removeAndReturn (i); + + if (auto blockImpl = BlockImplementation::getFrom (*block)) + { + blockImpl->revalidate (info.version, info.name, info.isMaster); + currentTopology.blocks.add (block); + return true; + } + } + } + + return false; + } + + void addNewBlock (DeviceInfo info) + { + currentTopology.blocks.add (new BlockImplementation (info.serial, *this, info.version, + info.name, info.isMaster)); + } + + void updateCurrentBlockInfo (Block::Ptr blockToUpdate, DeviceInfo& updatedInfo) + { + if (versionNumberChanged (updatedInfo, blockToUpdate->versionNumber)) + setVersionNumberForBlock (updatedInfo, *blockToUpdate); + + if (nameIsValid (updatedInfo)) + setNameForBlock (updatedInfo, *blockToUpdate); + + if (updatedInfo.isMaster != blockToUpdate->isMasterBlock()) + BlockImplementation::getFrom (*blockToUpdate)->setToMaster (updatedInfo.isMaster); + } + juce::OwnedArray connectedDeviceGroups; //============================================================================== @@ -1293,6 +1349,19 @@ struct PhysicalTopologySource::Internal isStillConnected = false; } + void revalidate (BlocksProtocol::VersionNumber newVersion, BlocksProtocol::BlockName newName, bool master) + { + versionNumber = getVersionString (newVersion); + name = getNameString (newName); + isMaster = master; + isStillConnected = true; + } + + void setToMaster (bool shouldBeMaster) + { + isMaster = shouldBeMaster; + } + Type getType() const override { return modelData.apiType; } juce::String getDeviceDescription() const override { return modelData.description; } int getWidth() const override { return modelData.widthUnits; }