80 lines
2.1 KiB
C++
80 lines
2.1 KiB
C++
#include "pattern.h"
|
|
using Xybrid::Data::Pattern;
|
|
using Row = Pattern::Row;
|
|
using Channel = Pattern::Channel;
|
|
|
|
#include "data/project.h"
|
|
|
|
Row Pattern::fallbackRow(-1337, -1337);
|
|
Channel Pattern::fallbackChannel(0);
|
|
std::array<unsigned char, 2> Row::fallbackParam {'.', 0};
|
|
|
|
Row::Row(const Row& o) noexcept {
|
|
*this = o;
|
|
}
|
|
|
|
Row& Row::operator=(const Row& o) noexcept {
|
|
port = o.port;
|
|
note = o.note;
|
|
// copy-constructor the underlying vector
|
|
if (o.params) params.reset(new std::vector<std::array<unsigned char, 2>>(*o.params));
|
|
else params.reset();
|
|
return *this;
|
|
}
|
|
|
|
Channel::Channel(int numRows, QString name) : Channel() {
|
|
this->name = name;
|
|
rows.resize(static_cast<size_t>(numRows));
|
|
}
|
|
|
|
Pattern::Pattern() {
|
|
|
|
}
|
|
|
|
Pattern::Pattern(int rows, int channels) : Pattern() {
|
|
for (int i = 0; i < channels; i++) this->channels.emplace_back();
|
|
setLength(rows);
|
|
}
|
|
|
|
void Pattern::setLength(int r) {
|
|
if (r < 1) r = 1;
|
|
rows = r;
|
|
for (auto & c : channels) {
|
|
c.rows.resize(static_cast<size_t>(rows));
|
|
}
|
|
}
|
|
|
|
void Pattern::addChannel(int at) {
|
|
if (at < 0 || at > static_cast<int>(channels.size())) at = static_cast<int>(channels.size());
|
|
channels.insert(channels.begin() + at, rows);
|
|
}
|
|
|
|
void Pattern::deleteChannel(int at) {
|
|
if (at < 0 || at >= static_cast<int>(channels.size())) at = static_cast<int>(channels.size()) - 1;
|
|
channels.erase(channels.begin() + at);
|
|
}
|
|
|
|
bool Pattern::valid() const {
|
|
return (project && index < project->patterns.size() && this == project->patterns[index].get());
|
|
}
|
|
bool Pattern::validFor(const Project* p) const {
|
|
return valid() && project == p;
|
|
}
|
|
bool Pattern::validFor(const std::shared_ptr<Project>& p) const {
|
|
return valid() && project == p.get();
|
|
}
|
|
|
|
Channel& Pattern::channel(int c) {
|
|
auto cc = static_cast<size_t>(c);
|
|
if (cc >= channels.size()) return fallbackChannel;
|
|
return channels[cc];
|
|
}
|
|
|
|
Row& Pattern::rowAt(int c, int r) {
|
|
auto nc = this->channels.size();
|
|
if (nc == 0 || rows == 0) return fallbackRow;
|
|
c = c % static_cast<int>(nc);
|
|
r = r % rows;
|
|
return channels[static_cast<size_t>(c)].rows[static_cast<size_t>(r)];
|
|
}
|