Files
qad/mbricks/brick_manager.cpp
Бычков Андрей b3e47dfc99 actual version libs withiout pip
git-svn-id: svn://db.shs.com.ru/libs@2 a8b55f48-bf90-11e4-a774-851b48703e85
2015-03-24 08:14:45 +00:00

322 lines
7.9 KiB
C++

#include "brick_manager.h"
#include "brick_composite.h"
BrickManager::BrickManager(double frequency, double time_step) {
timer = new PITimer(run, this, PITimer::ThreadRT);
setFrequency(frequency, time_step);
ctime = 0.;
paused = false;
wasReset = true;
mode_ = BrickBase::Asynchronous;
BrickComposite::fillBaseBricks();
}
void BrickManager::setFrequency(double frequency, double time_step) {
freq = frequency;
tstep = (time_step == 0.) ? 1. / frequency : time_step;
if (!isRunning()) return;
stop();
start();
}
void BrickManager::addBrick(BrickBase * brick, bool uniqueName) {
//lock();
pause();
brick->saveInputsToDefault();
if (uniqueName) brick->setName(getUniqueName(brick->name()));
brick->setManager(this);
bricks.push_back(brick);
if (mode_ == BrickBase::Asynchronous) buildSchemeTree();
resume();
//unlock();
}
void BrickManager::removeBrick(BrickBase * brick) {
for (uint i = 0; i < bricks.size(); ++i) {
if (bricks[i] == brick) {
disconnectBrick(brick);
bricks.remove(i);
buildSchemeTree();
return;
}
}
}
void BrickManager::replaceBrick(BrickBase * old_b, BrickBase * new_b) {
PIVector<BrickBase::Connection> conns = old_b->connections;
PIFlags<BrickBase::IOType> ion = new_b->io_Type;
BrickBase * cb;
new_b->setName(getUniqueName(new_b->name()));
new_b->freqDivider_ = old_b->freqDivider_;
new_b->manager_ = old_b->manager_;
if (ion[BrickBase::VariableInputs])
new_b->setInputsCount(old_b->inputsCount());
if (ion[BrickBase::VariableOutputs])
new_b->setOutputsCount(old_b->outputsCount());
for (uint i = 0; i < bricks.size(); ++i) {
cb = bricks[i];
if (cb == old_b) {
bricks[i] = new_b;
for (uint j = 0; j < conns.size(); ++j) {
if (conns[j].out_num > new_b->outputsCount()) continue;
new_b->addConnection(conns[j]);
}
continue;
}
for (int j = 0; j < cb->connectionsCount(); ++j) {
if (cb->connections[j].brick_to != old_b) continue;
if (cb->connections[j].out_num > new_b->inputsCount())
cb->removeConnection(j);
else
cb->connections[j].brick_to = new_b;
}
}
PIVector<BrickBase * > * tl;
for (uint i = 0; i < tree.size(); ++i) {
tl = &tree[i];
for (uint j = 0; j < tl->size(); ++j) {
if (tl->at(j) != old_b) continue;
(*tl)[j] = new_b;
}
}
int pc = piMin<int>(old_b->parametersCount(), new_b->parametersCount()), ic = piMin<int>(old_b->inputsCount(), new_b->inputsCount());
for (int i = 0; i < pc; ++i)
new_b->setParameterValueOnly(i, old_b->parameter(i).toString());
for (int i = 0; i < ic; ++i)
new_b->setInputValue(i, old_b->input(i));
//delete old_b;
}
void BrickManager::tick(bool realTime) {
//cout << "tick\n";
if (paused) return;
wasReset = false;
if (realTime) {
//lock();
switch (mode_) {
case BrickBase::Synchronous:
for (uint i = 0; i < bricks.size(); ++i)
bricks[i]->tick(ctime);
proceedConnections();
break;
case BrickBase::Asynchronous:
PIVector<BrickBase * > * tl;
for (uint i = 0; i < tree.size(); ++i) {
tl = &tree[i];
for (uint j = 0; j < tl->size(); ++j)
(*tl)[j]->tick(ctime);
for (uint j = 0; j < tl->size(); ++j)
(*tl)[j]->proceedConnections();
}
break;
}
ctime += tstep;
//unlock();
} else {
switch (mode_) {
case BrickBase::Synchronous:
for (uint i = 0; i < bricks.size(); ++i)
if (!bricks[i]->isRealTimeOnly())
bricks[i]->tick(ctime);
proceedConnections();
break;
case BrickBase::Asynchronous:
PIVector<BrickBase * > * tl;
for (uint i = 0; i < tree.size(); ++i) {
tl = &tree[i];
for (uint j = 0; j < tl->size(); ++j)
if (!(*tl)[j]->isRealTimeOnly())
(*tl)[j]->tick(ctime);
for (uint j = 0; j < tl->size(); ++j)
(*tl)[j]->proceedConnections();
}
break;
}
ctime += tstep;
}
//cout << bricks[0]->output() << endl;
}
void BrickManager::proceedConnections(bool compositeToo) {
for (uint i = 0; i < bricks.size(); ++i)
bricks[i]->proceedConnections(compositeToo);
}
void BrickManager::start() {
paused = false;
startBricks();
timer->stop();
#ifdef WINDOWS
timer->waitForFinish();
#endif
timer->start(1000. / freq);
}
void BrickManager::stop() {
paused = false;
timer->stop();
stopBricks();
}
void BrickManager::reset() {
paused = false;
wasReset = true;
if (isRunning()) lock();
for (int i = 0; i < 3; ++i) {
resetOutputs();
proceedConnections(true);
}
saveInputsToDefault();
for (uint i = 0; i < bricks.size(); ++i)
bricks[i]->reset();
ctime = 0.;
if (isRunning()) unlock();
}
void BrickManager::resetOutputs() {
for (uint i = 0; i < bricks.size(); ++i)
bricks[i]->resetOutputs();
}
void BrickManager:: resetScheme() {
stop();
paused = false;
tree.clear();
for (uint i = 0; i < bricks.size(); ++i)
delete bricks[i];
bricks.clear();
}
bool BrickManager::loadScheme(const PIString & file) {
PIConfig sr(file);
if (!sr.isOpened()) return false;
resetScheme();
setFrequency(sr.getValue("Real-time Frequency", 100), sr.getValue("Real-time Step", 0.));
setMode((BrickBase::Mode)(int)sr.getValue("Mode", 1));
PIMathSolver::method_global = static_cast<PIMathSolver::Method>((int)sr.getValue("PIMathSolver", 0));
PIStringList names = sr.getValue("Bricks", PIStringList());
PIString prefix, cname;
BrickBase * b, * bf, * bt;
if (BrickComposite::baseBricks.size() == 0)
BrickComposite::fillBaseBricks();
for (int i = 0; i < names.size_s(); ++i) {
prefix = names[i] + " ";
cname = sr.getValue(prefix + "codeName", "");
b = BrickComposite::findBaseBrick(cname);
if (b == 0) {
piCout << "Error while loading scheme: can`t find brick \"" << cname << "\"";
continue;
} else
b = b->copy();
loadBrick(sr, prefix, b);
bricks.push_back(b);
}
int cnt = sr.getValue("Connections count", 0);
for (int i = 0; i < cnt; ++i) {
prefix = "Connection " + PIString::fromNumber(i) + " ";
bf = findBrick(sr.getValue(prefix + "from Name", "").value().stdString());
bt = findBrick(sr.getValue(prefix + "to Name", "").value().stdString());
if (bf == 0 || bt == 0) {
piCout << "Error while loading scheme: can`t create connection " << i;
continue;
}
BrickBase::connect(bf, sr.getValue(prefix + "from Port", 0), bt, sr.getValue(prefix + "to Port", 0));
}
buildSchemeTree();
startBricks();
return true;
}
void BrickManager::disconnectBrick(BrickBase * brick) {
for (uint i = 0; i < bricks.size(); ++i) {
for (int j = 0; j < bricks[i]->connectionsCount(); ++j) {
if (bricks[i]->connection(j).brick_to == brick)
bricks[i]->removeConnection(j);
}
}
}
void BrickManager::loadBrick(PIConfig & sr, const PIString & prefix, BrickBase * b) {
BrickComposite::loadBrick(sr, prefix, b, this);
}
void BrickManager::saveInputsToDefault() {
for (uint i = 0; i < bricks.size(); ++i)
bricks[i]->saveInputsToDefault();
}
bool BrickManager::checkUniqueName(const PIString & name, BrickBase * brick) {
for (uint i = 0; i < bricks.size(); ++i)
if ((bricks[i]->name() == name) && (bricks[i] != brick))
return false;
return true;
}
PIString BrickManager::getUniqueName(const PIString & name) {
int cind = 0, di = 0;
if (name.size() > 0) {
di = name.size_s() - 1;
while (name[di].isDigit()) --di;
di = name.size_s() - di - 1;
}
PIString cname, bname;
if (di > 0) bname = PIString(name).cutRight(di);
else bname = name + "_";
cname = bname + PIString::fromNumber(cind);
bool ok = false;
while (!ok) {
ok = true;
for (uint i = 0; i < bricks.size(); ++i) {
if (bricks[i]->name() == cname) {
cind++;
ok = false;
break;
}
}
cname = bname + PIString::fromNumber(cind);
}
return cname;
}
BrickBase* BrickManager::findBrick(const PIString & name) {
for (uint i = 0; i < bricks.size(); ++i)
if (bricks[i]->name() == name)
return bricks[i];
return 0;
}
void BrickManager::setMode(BrickBase::Mode m) {
mode_ = m;
if (mode_ == BrickBase::Asynchronous) buildSchemeTree();
else
for (uint i = 0; i < bricks.size(); ++i)
bricks[i]->level_ = -666;
}
void BrickManager::buildSchemeTree() {
buildTree(bricks, tree);
}