1
0
Fork 0

basic operations for managing a patch

This commit is contained in:
Kevin Matz 2023-04-01 11:17:56 -04:00
parent 6486775626
commit 3ee4cbb858
2 changed files with 130 additions and 0 deletions

View File

@ -22,6 +22,7 @@
SOFTWARE.
*/
#include "dmx.h"
#include "patch.h"
namespace DMX {
@ -34,4 +35,118 @@ Patch::Patch()
}
/**
* @brief Add a Device to the patch.
* @param dev
*/
void Patch::addDevice(const std::shared_ptr<Device> dev)
{
devices_.emplace(dev);
}
/**
* @brief Remove a Device from the patch.
* @param dev
*/
void Patch::remDevice(const std::shared_ptr<Device> dev)
{
for (auto it = devices_.begin(); it != devices_.end();)
{
if (it->expired()) // purge stale devices
it = devices_.erase(it);
else if (it->lock() == dev)
it = devices_.erase(it);
else
++it;
}
}
/**
* @brief Check if a Device is in the patch.
* @param dev
* @return
*/
bool Patch::hasDevice(const std::shared_ptr<Device> dev)
{
for (auto it = devices_.begin(); it != devices_.end();)
{
if (it->expired()) // purge stale devices
it = devices_.erase(it);
else if (it->lock() == dev)
return true;
else
++it;
}
return false;
}
/**
* @brief Get the list of patched Devices.
* @return
*/
const std::set<std::weak_ptr<Device>> * Patch::devices() const
{
return &devices_;
}
/**
* @brief Check the patch for device footprint conflicts
* @return
*/
std::set<std::weak_ptr<Device>> Patch::conflicts()
{
std::set<std::weak_ptr<Device>> bad;
for (auto it = devices_.begin(); it != devices_.end();)
{
if (it->expired()) { // purge stale devices
it = devices_.erase(it);
continue;
}
auto dev = it->lock();
// footprint cannot overlow universe
if (dev->address() + dev->footprint() >= E111_LAST_SLOT) {
bad.emplace(dev);
++it;
continue;
}
// start address cannot overlap the prior device
if (it != devices_.begin()) {
auto prev = std::prev(it)->lock();
if (dev->address() < prev->address() + prev->footprint()) {
bad.emplace(dev);
++it;
continue;
}
}
// footprint cannot overlap the next device
auto nextItr = std::next(it);
while(true) {
if (nextItr == devices_.end()) // device is the last member of the patch
break;
if (nextItr->expired()) { // next device is stale, purge it
nextItr = devices_.erase(nextItr);
continue;
}
auto next = nextItr->lock();
if (dev->address() + dev->footprint() >= next->address())
bad.emplace(dev);
break;
}
++it;
}
return bad;
}
} // namespace DMX

View File

@ -23,6 +23,11 @@
*/
#pragma once
#include "device.h"
#include <memory>
#include <set>
namespace DMX {
/**
@ -32,6 +37,16 @@ class Patch
{
public:
explicit Patch();
void addDevice(const std::shared_ptr<Device>);
void remDevice(const std::shared_ptr<Device>);
bool hasDevice(const std::shared_ptr<Device>);
const std::set<std::weak_ptr<Device>> *devices() const;
std::set<std::weak_ptr<Device>> conflicts();
private:
std::set<std::weak_ptr<Device>> devices_;
};
} // namespace DMX