patch Personalities, not devices.
This commit is contained in:
parent
3ee4cbb858
commit
7d1c756d89
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue