1
0
Fork 0
mirror of https://github.com/juce-framework/JUCE.git synced 2026-01-10 23:44:24 +00:00

BLOCKS API: Improved reference-counting of Block objects in PhysicalTopologySource::Detector

This commit is contained in:
Daniel Walz 2018-08-30 12:12:37 +01:00 committed by Julian Storer
parent 67d2ff2ec8
commit 8e0c8fc89d
2 changed files with 108 additions and 111 deletions

View file

@ -863,7 +863,6 @@ struct PhysicalTopologySource::Internal
~Detector()
{
jassert (activeTopologySources.isEmpty());
jassert (activeControlButtons.isEmpty());
}
using Ptr = juce::ReferenceCountedObjectPtr<Detector>;
@ -977,26 +976,20 @@ struct PhysicalTopologySource::Internal
{
JUCE_ASSERT_MESSAGE_MANAGER_IS_LOCKED
for (auto&& b : currentTopology.blocks)
if (b->uid == deviceID)
if (auto bi = BlockImplementation::getFrom (*b))
bi->handleSharedDataACK (packetCounter);
if (auto* bi = getBlockImplementationWithUID (deviceID))
bi->handleSharedDataACK (packetCounter);
}
void handleFirmwareUpdateACK (Block::UID deviceID, uint8 resultCode, uint32 resultDetail)
{
for (auto&& b : currentTopology.blocks)
if (b->uid == deviceID)
if (auto bi = BlockImplementation::getFrom (*b))
bi->handleFirmwareUpdateACK (resultCode, resultDetail);
if (auto* bi = getBlockImplementationWithUID (deviceID))
bi->handleFirmwareUpdateACK (resultCode, resultDetail);
}
void handleConfigUpdateMessage (Block::UID deviceID, int32 item, int32 value, int32 min, int32 max)
{
for (auto&& b : currentTopology.blocks)
if (b->uid == deviceID)
if (auto bi = BlockImplementation::getFrom (*b))
bi->handleConfigUpdateMessage (item, value, min, max);
if (auto* bi = getBlockImplementationWithUID (deviceID))
bi->handleConfigUpdateMessage (item, value, min, max);
}
void notifyBlockOfConfigChange (BlockImplementation& bi, uint32 item)
@ -1012,61 +1005,44 @@ struct PhysicalTopologySource::Internal
void handleConfigSetMessage (Block::UID deviceID, int32 item, int32 value)
{
for (auto&& b : currentTopology.blocks)
if (auto* bi = getBlockImplementationWithUID (deviceID))
{
if (b->uid == deviceID)
{
if (auto bi = BlockImplementation::getFrom (*b))
{
bi->handleConfigSetMessage (item, value);
notifyBlockOfConfigChange (*bi, uint32 (item));
}
}
bi->handleConfigSetMessage (item, value);
notifyBlockOfConfigChange (*bi, uint32 (item));
}
}
void handleConfigFactorySyncEndMessage (Block::UID deviceID)
{
for (auto&& b : currentTopology.blocks)
if (b->uid == deviceID)
if (auto bi = BlockImplementation::getFrom (*b))
notifyBlockOfConfigChange (*bi, bi->getMaxConfigIndex());
if (auto* bi = getBlockImplementationWithUID (deviceID))
notifyBlockOfConfigChange (*bi, bi->getMaxConfigIndex());
}
void handleConfigFactorySyncResetMessage (Block::UID deviceID)
{
for (auto&& b : currentTopology.blocks)
if (b->uid == deviceID)
if (auto bi = BlockImplementation::getFrom (*b))
bi->resetConfigListActiveStatus();
if (auto* bi = getBlockImplementationWithUID (deviceID))
bi->resetConfigListActiveStatus();
}
void handleLogMessage (Block::UID deviceID, const String& message) const
{
JUCE_ASSERT_MESSAGE_MANAGER_IS_LOCKED
for (auto&& b : currentTopology.blocks)
if (b->uid == deviceID)
if (auto bi = BlockImplementation::getFrom (*b))
bi->handleLogMessage (message);
if (auto* bi = getBlockImplementationWithUID (deviceID))
bi->handleLogMessage (message);
}
void handleButtonChange (Block::UID deviceID, Block::Timestamp timestamp, uint32 buttonIndex, bool isDown) const
{
JUCE_ASSERT_MESSAGE_MANAGER_IS_LOCKED
for (auto b : activeControlButtons)
if (auto* bi = getBlockImplementationWithUID (deviceID))
{
if (b->block.uid == deviceID)
{
if (auto bi = BlockImplementation::getFrom (b->block))
{
bi->pingFromDevice();
bi->pingFromDevice();
if (buttonIndex < (uint32) bi->modelData.buttons.size())
b->broadcastButtonChange (timestamp, bi->modelData.buttons[(int) buttonIndex].type, isDown);
}
}
if (isPositiveAndBelow (buttonIndex, bi->getButtons().size()))
if (auto* cbi = dynamic_cast<ControlButtonImplementation*> (bi->getButtons().getUnchecked (int (buttonIndex))))
cbi->broadcastButtonChange (timestamp, bi->modelData.buttons[(int) buttonIndex].type, isDown);
}
}
@ -1074,34 +1050,34 @@ struct PhysicalTopologySource::Internal
{
JUCE_ASSERT_MESSAGE_MANAGER_IS_LOCKED
for (auto t : activeTouchSurfaces)
auto block = currentTopology.getBlockWithUID (deviceID);
if (block != nullptr)
{
if (t->block.uid == deviceID)
if (auto* surface = dynamic_cast<TouchSurfaceImplementation*> (block->getTouchSurface()))
{
TouchSurface::Touch scaledEvent (touchEvent);
scaledEvent.x *= t->block.getWidth();
scaledEvent.y *= t->block.getHeight();
scaledEvent.startX *= t->block.getWidth();
scaledEvent.startY *= t->block.getHeight();
scaledEvent.x *= block->getWidth();
scaledEvent.y *= block->getHeight();
scaledEvent.startX *= block->getWidth();
scaledEvent.startY *= block->getHeight();
t->broadcastTouchChange (scaledEvent);
surface->broadcastTouchChange (scaledEvent);
}
}
}
void cancelAllActiveTouches() noexcept
{
for (auto surface : activeTouchSurfaces)
surface->cancelAllActiveTouches();
for (auto& block : currentTopology.blocks)
if (auto* surface = block->getTouchSurface())
surface->cancelAllActiveTouches();
}
void handleCustomMessage (Block::UID deviceID, Block::Timestamp timestamp, const int32* data)
{
for (auto&& b : currentTopology.blocks)
if (b->uid == deviceID)
if (auto bi = BlockImplementation::getFrom (*b))
bi->handleCustomMessage (timestamp, data);
if (auto* bi = getBlockImplementationWithUID (deviceID))
bi->handleCustomMessage (timestamp, data);
}
//==============================================================================
@ -1131,7 +1107,7 @@ struct PhysicalTopologySource::Internal
static Detector* getFrom (Block& b) noexcept
{
if (auto* bi = BlockImplementation::getFrom (b))
return &(bi->detector);
return (bi->detector);
jassertfalse;
return nullptr;
@ -1151,12 +1127,24 @@ struct PhysicalTopologySource::Internal
return nullptr;
}
const DeviceConnection* getDeviceConnectionFor (const Block& b) const
{
for (const auto& d : connectedDeviceGroups)
{
for (const auto& info : d->currentDeviceInfo)
{
if (info.uid == b.uid)
return d->getDeviceConnection();
}
}
return nullptr;
}
std::unique_ptr<MIDIDeviceDetector> defaultDetector;
DeviceDetector& deviceDetector;
juce::Array<PhysicalTopologySource*> activeTopologySources;
juce::Array<ControlButtonImplementation*> activeControlButtons;
juce::Array<TouchSurfaceImplementation*> activeTouchSurfaces;
BlockTopology currentTopology;
juce::ReferenceCountedArray<Block, CriticalSection> disconnectedBlocks;
@ -1264,6 +1252,14 @@ struct PhysicalTopologySource::Internal
BlockImplementation::getFrom (*blockToUpdate)->setToMaster (updatedInfo.isMaster);
}
BlockImplementation* getBlockImplementationWithUID (Block::UID deviceID) const noexcept
{
if (auto&& block = currentTopology.getBlockWithUID (deviceID))
return BlockImplementation::getFrom (*block);
return nullptr;
}
juce::OwnedArray<ConnectedDeviceGroup> connectedDeviceGroups;
//==============================================================================
@ -1309,6 +1305,7 @@ struct PhysicalTopologySource::Internal
TopologyBroadcastThrottle topologyBroadcastThrottle;
JUCE_DECLARE_WEAK_REFERENCEABLE (Detector)
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Detector)
};
@ -1337,15 +1334,6 @@ struct PhysicalTopologySource::Internal
}
}
Block::Ptr findBlockWithUid (const BlockTopology& topology, Block::UID uid)
{
for (auto& block : topology.blocks)
if (block->uid == uid)
return *block;
return {};
}
// returns the distance from corner clockwise
int getUnitForIndex (Block::Ptr block, Block::ConnectionPort::DeviceEdge edge, int index)
{
@ -1398,7 +1386,7 @@ struct PhysicalTopologySource::Internal
|| (connection.device2 == block->uid && ! visited.contains (connection.device1)))
{
const auto theirUid = connection.device1 == block->uid ? connection.device2 : connection.device1;
const auto neighbourPtr = findBlockWithUid (topology, theirUid);
const auto neighbourPtr = topology.getBlockWithUID (theirUid);
if (auto* neighbour = dynamic_cast<BlockImplementation*> (neighbourPtr.get()))
{
@ -1452,7 +1440,7 @@ struct PhysicalTopologySource::Internal
juce::String ((const char*) blockName.name, blockName.length)),
modelData (serial),
remoteHeap (modelData.programAndHeapSize),
detector (detectorToUse),
detector (&detectorToUse),
isMaster (master)
{
sendCommandMessage (BlocksProtocol::beginAPIMode);
@ -1492,10 +1480,6 @@ struct PhysicalTopologySource::Internal
if (auto surface = dynamic_cast<TouchSurfaceImplementation*> (touchSurface.get()))
surface->disableTouchSurface();
for (auto* b : controlButtons)
if (auto controlButton = dynamic_cast<ControlButtonImplementation*> (b))
controlButton->disableControlButton();
}
void revalidate (BlocksProtocol::VersionNumber newVersion, BlocksProtocol::BlockName newName, bool master)
@ -1508,10 +1492,6 @@ struct PhysicalTopologySource::Internal
if (auto surface = dynamic_cast<TouchSurfaceImplementation*> (touchSurface.get()))
surface->activateTouchSurface();
for (auto* b : controlButtons)
if (auto controlButton = dynamic_cast<ControlButtonImplementation*> (b))
controlButton->activateControlButton();
updateMidiConnectionListener();
}
@ -1522,7 +1502,10 @@ struct PhysicalTopologySource::Internal
void updateMidiConnectionListener()
{
listenerToMidiConnection = dynamic_cast<MIDIDeviceConnection*> (detector.getDeviceConnectionFor (*this));
if (detector == nullptr)
return;
listenerToMidiConnection = dynamic_cast<MIDIDeviceConnection*> (detector->getDeviceConnectionFor (*this));
if (listenerToMidiConnection != nullptr)
listenerToMidiConnection->addListener (this);
@ -1537,7 +1520,7 @@ struct PhysicalTopologySource::Internal
float getMillimetersPerUnit() const override { return 47.0f; }
bool isHardwareBlock() const override { return true; }
juce::Array<Block::ConnectionPort> getPorts() const override { return modelData.ports; }
bool isConnected() const override { return isStillConnected && detector.isConnected (uid); }
bool isConnected() const override { return isStillConnected && detector && detector->isConnected (uid); }
bool isMasterBlock() const override { return isMaster; }
Block::UID getConnectedMasterUID() const override { return masterUID; }
int getRotation() const override { return rotation; }
@ -1570,7 +1553,10 @@ struct PhysicalTopologySource::Internal
float getBatteryLevel() const override
{
if (auto status = detector.getLastStatus (uid))
if (detector == nullptr)
return 0.0f;
if (auto status = detector->getLastStatus (uid))
return status->batteryLevel.toUnipolarFloat();
return 0.0f;
@ -1578,7 +1564,10 @@ struct PhysicalTopologySource::Internal
bool isBatteryCharging() const override
{
if (auto status = detector.getLastStatus (uid))
if (detector == nullptr)
return false;
if (auto status = detector->getLastStatus (uid))
return status->batteryCharging.get() != 0;
return false;
@ -1591,14 +1580,22 @@ struct PhysicalTopologySource::Internal
int getDeviceIndex() const noexcept
{
return isConnected() ? detector.getIndexFromDeviceID (uid) : -1;
if (detector == nullptr)
return -1;
return isConnected() ? detector->getIndexFromDeviceID (uid) : -1;
}
template <typename PacketBuilder>
bool sendMessageToDevice (const PacketBuilder& builder)
{
lastMessageSendTime = juce::Time::getCurrentTime();
return detector.sendMessageToDevice (uid, builder);
if (detector != nullptr)
{
lastMessageSendTime = juce::Time::getCurrentTime();
return detector->sendMessageToDevice (uid, builder);
}
return false;
}
bool sendCommandMessage (uint32 commandID)
@ -2045,7 +2042,7 @@ struct PhysicalTopologySource::Internal
using RemoteHeapType = littlefoot::LittleFootRemoteHeap<BlockImplementation>;
RemoteHeapType remoteHeap;
Detector& detector;
WeakReference<Detector> detector;
juce::Time lastMessageSendTime, lastMessageReceiveTime;
BlockConfigManager config;
@ -2074,8 +2071,9 @@ struct PhysicalTopologySource::Internal
const juce::MidiInput* getMidiInput() const
{
if (auto c = dynamic_cast<MIDIDeviceConnection*> (detector.getDeviceConnectionFor (*this)))
return c->midiInput.get();
if (detector != nullptr)
if (auto c = dynamic_cast<const MIDIDeviceConnection*> (detector->getDeviceConnectionFor (*this)))
return c->midiInput.get();
jassertfalse;
return nullptr;
@ -2088,8 +2086,9 @@ struct PhysicalTopologySource::Internal
const juce::MidiOutput* getMidiOutput() const
{
if (auto c = dynamic_cast<MIDIDeviceConnection*> (detector.getDeviceConnectionFor (*this)))
return c->midiOutput.get();
if (detector != nullptr)
if (auto c = dynamic_cast<const MIDIDeviceConnection*> (detector->getDeviceConnectionFor (*this)))
return c->midiOutput.get();
jassertfalse;
return nullptr;
@ -2270,18 +2269,12 @@ struct PhysicalTopologySource::Internal
void activateTouchSurface()
{
if (auto det = Detector::getFrom (block))
det->activeTouchSurfaces.add (this);
startTimer (500);
}
void disableTouchSurface()
{
stopTimer();
if (auto det = Detector::getFrom (block))
det->activeTouchSurfaces.removeFirstMatchingValue (this);
}
int getNumberOfKeywaves() const noexcept override
@ -2385,24 +2378,10 @@ struct PhysicalTopologySource::Internal
ControlButtonImplementation (BlockImplementation& b, int index, BlocksProtocol::BlockDataSheet::ButtonInfo info)
: ControlButton (b), blockImpl (b), buttonInfo (info), buttonIndex (index)
{
activateControlButton();
}
~ControlButtonImplementation()
{
disableControlButton();
}
void activateControlButton()
{
if (auto det = Detector::getFrom (block))
det->activeControlButtons.add (this);
}
void disableControlButton()
{
if (auto det = Detector::getFrom (block))
det->activeControlButtons.removeFirstMatchingValue (this);
}
ButtonFunction getType() const override { return buttonInfo.type; }

View file

@ -48,6 +48,24 @@ struct BlockTopology
bool operator== (const BlockTopology&) const noexcept;
bool operator!= (const BlockTopology&) const noexcept;
Block::Ptr getBlockWithUID (Block::UID deviceID)
{
for (auto&& block : blocks)
if (block->uid == deviceID)
return block;
return {};
}
const Block::Ptr getBlockWithUID (Block::UID deviceID) const
{
for (auto&& block : blocks)
if (block->uid == deviceID)
return block;
return {};
}
};
} // namespace juce