1
0
Fork 0

patch Personalities, not devices.

This commit is contained in:
Kevin Matz 2023-04-01 15:31:22 -04:00
parent 3ee4cbb858
commit 7d1c756d89
2 changed files with 78 additions and 101 deletions

View File

@ -37,116 +37,84 @@ 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
* @brief Add a Personality to the patch.
* @param device
* @param address
* @return
*/
bool Patch::hasDevice(const std::shared_ptr<Device> dev)
bool Patch::patch(std::shared_ptr<Personality> device, uint16_t address)
{
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;
if (address == 0 || address > E111_LAST_SLOT)
return false;
if (address + device->footprint() >= E111_LAST_SLOT)
return false;
members_.emplace_back(device,address);
return true;
}
/**
* @brief Get the list of patched Devices.
* @return
* @brief Unpatch all occurances of a Peronality in the patch.
* @param device
*/
const std::set<std::weak_ptr<Device>> * Patch::devices() const
void Patch::unpatch(std::shared_ptr<Personality> device)
{
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();)
for (auto it = members_.begin(); it != members_.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;
auto wp = it->first;
if (wp.expired()) {
it = members_.erase(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);
auto personality = wp.lock();
if (personality == device) {
it = members_.erase(it);
continue;
}
auto next = nextItr->lock();
if (dev->address() + dev->footprint() >= next->address())
bad.emplace(dev);
break;
}
++it;
}
}
/**
* @brief Unpatch a Personality given it's postion in the patch.
* @param index
*/
void Patch::unpatch(size_t index)
{
members_.erase(members_.begin() + index);
}
/**
* @brief Return a list of the patch members.
* @return
*/
const std::vector<std::pair<std::weak_ptr<Personality>,uint16_t>> * Patch::listing()
{
return &members_;
}
/**
* @brief Attach the patch to a Universe.
* @param universe
*/
void Patch::setUniverse(std::shared_ptr<Universe> universe)
{
universe_ = universe;
data_change_token = universe->onDataChange([this](DMX::Universe*){universeDataChanged();});
}
/**
* @brief Update Devices when the Universe data changes.
*/
void Patch::universeDataChanged()
{
return bad;
}
} // namespace DMX

View File

@ -23,10 +23,12 @@
*/
#pragma once
#include "device.h"
#include "personality.h"
#include "universe.h"
#include <cstdint>
#include <memory>
#include <set>
#include <vector>
namespace DMX {
@ -38,15 +40,22 @@ 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>);
void setUniverse(std::shared_ptr<Universe>);
const std::set<std::weak_ptr<Device>> *devices() const;
std::set<std::weak_ptr<Device>> conflicts();
bool patch(std::shared_ptr<Personality> device, uint16_t address);
void unpatch(std::shared_ptr<Personality> device);
void unpatch(size_t index);
const std::vector<std::pair<std::weak_ptr<Personality>,uint16_t>> * listing();
protected:
void universeDataChanged();
private:
std::set<std::weak_ptr<Device>> devices_;
std::vector<std::pair<std::weak_ptr<Personality>,uint16_t>> members_;
std::weak_ptr<Universe> universe_;
std::shared_ptr<void> data_change_token;
};
} // namespace DMX