#ifndef BRICK_BASE_H #define BRICK_BASE_H #include "pievaluator.h" #include "piconfig.h" #include "pivariant.h" #include "picollection.h" #include "pimathmodule.h" #define MBRICK(brick) PIOBJECT_SUBCLASS(brick, BrickBase) friend class BrickManager; public: virtual BrickBase * copy() {brick * t = new brick(*this); t->setName(name()); t->type = type; t->copied(); return t;} inline double residue(double f, double s) {return f - floor(f / s) * s;} inline double dbool(double d) {return d > 0 ? 1. : 0;} class BrickComposite; class BrickManager; class BrickBase: public PIObject { PIOBJECT(BrickBase) friend class BrickManager; friend void buildTree(PIVector & bricks, PIVector > & tree); friend PIVector > buildSubtree(PIVector & bricks, PIVector > & tree); public: BrickBase(int inputs_num = 1, int outputs_num = 1, int parameters_num = 0); virtual ~BrickBase() {;} virtual BrickBase * copy() {return new BrickBase(*this);} enum IOType { Fixed = 0x0, VariableInputs = 0x01, VariableOutputs = 0x02, VariableInOuts = VariableInputs | VariableOutputs }; enum Mode {Synchronous, Asynchronous}; enum ParameterType {Bool, Integer, Float, String, File}; struct Parameter { Parameter() {type = BrickBase::Float;} Parameter(const char * v) {setValue(v);} Parameter(const bool & v) {setValue(v);} Parameter(const int & v) {setValue(v);} Parameter(const double & v) {setValue(v);} Parameter(const PIString & v) {setValue(v);} void setType(const ParameterType & t) {type = t;} void setValue(const char * v, bool withType = true) {setValue(PIString(v), withType);} void setValue(const bool & v, bool withType = true) {if (withType) type = BrickBase::Bool; value = v;} void setValue(const int & v, bool withType = true) {if (withType) type = BrickBase::Integer; value = v;} void setValue(const double & v, bool withType = true) {if (withType) type = BrickBase::Float; value = v;} void setValue(const PIString & v, bool withType = true) {if (withType) type = BrickBase::String; value = v;} void setValue(const PIVariant & v, bool withType = true); void setValueOnly(const PIString & v) {value = v;} bool toBool() const {return value.toBool();} int toInt() const {return value.toInt();} uint toUInt() const {return value.toInt();} double toFloat() const {return value.toDouble();} PIString toString() const {return value.toString();} ParameterType type; PIVariant value; }; virtual void reset_specified() {;} virtual void inputsCountChanged(int count) {;} virtual void outputsCountChanged(int count) {;} virtual void started() {;} virtual void finished() {;} virtual void parameterChanged(int index) {;} virtual void saveInputsToDefault() {defInputs = inputs;} virtual void resetOutputs() {outputs.fill(0.);} virtual void reset() {finished(); inputs = defInputs; dt = pt = time_ = 0.; reset_specified(); resetOutputs(); started();} virtual void proceedConnections(bool compositeToo = false); bool tick(double time); int frequencyDivider() const {return freqDivider_;} void setFrequencyDivider(const int divider) {freqDivider_ = divider;} int inputsCount() const {return inputs_count;} int outputsCount() const {return outputs_count;} int parametersCount() const {return parameters_count;} double input(const int index = 0) const {return inputs[index];} double output(const int index = 0) const {return outputs[index];} const PIVariant & parameter(const int index = 0) const {return parameters[index].value;} const BrickBase::ParameterType & parameterType(const int index = 0) const {return parameters[index].type;} double * input_ptr(const int index = 0) {return &inputs[index];} double * output_ptr(const int index = 0) {return &outputs[index];} //double * parameter_ptr(const int index = 0) {return &(parameters[index].value.toDouble());} void setInputValue(const int index, double value) {inputs[index] = value;} void setOutputValue(const int index, double value) {outputs[index] = value;} void setDefaultInputValue(const int index, double value) {defInputs[index] = value;} void setParameterValue(const int index, const char * value, bool withType = false) {setParameterValue(index, PIString(value), withType);} void setParameterValue(const int index, const bool & value, bool withType = false) {parameters[index].setValue(value, withType); parameterChanged(index);} void setParameterValue(const int index, const int & value, bool withType = false) {parameters[index].setValue(value, withType); parameterChanged(index);} void setParameterValue(const int index, const double & value, bool withType = false) {parameters[index].setValue(value, withType); parameterChanged(index);} void setParameterValue(const int index, const PIString & value, bool withType = false) {parameters[index].setValue(value, withType); parameterChanged(index);} void setParameterValue(const int index, const PIVariant & value, bool withType = false) {parameters[index].setValue(value, withType); parameterChanged(index);} void setParameterValue(const int index, const BrickBase::Parameter & value) {parameters[index] = value; parameterChanged(index);} void setParameterValueOnly(const int index, const PIString & value) {parameters[index].setValueOnly(value); parameterChanged(index);} void setInputName(const int index, const PIString & name) {inNames[index] = name;} void setOutputName(const int index, const PIString & name) {outNames[index] = name;} void setParameterName(const int index, const PIString & name) {paramNames[index] = name;} void setInputsCount(const int count) {inputs.resize(count); inputs_count = inputs.size(); inNames.resize(count); inputsCountChanged(count);} void setOutputsCount(const int count) {outputs.resize(count); outputs_count = outputs.size(); outNames.resize(count); outputsCountChanged(count);} void setParametersCount(const int count, const char * val) {parameters.resize(count, BrickBase::Parameter(PIString(val))); paramNames.resize(count); parameters_count = parameters.size();} void setParametersCount(const int count, const bool & val) {parameters.resize(count, BrickBase::Parameter(val)); paramNames.resize(count); parameters_count = parameters.size();} void setParametersCount(const int count, const int val) {parameters.resize(count, BrickBase::Parameter(val)); paramNames.resize(count); parameters_count = parameters.size();} void setParametersCount(const int count, const double & val = 0.) {parameters.resize(count, BrickBase::Parameter(val)); paramNames.resize(count); parameters_count = parameters.size();} void setParametersCount(const int count, const PIString & val) {parameters.resize(count, BrickBase::Parameter(val)); paramNames.resize(count); parameters_count = parameters.size();} const PIVector & getParameters() const {return parameters;} void setInOutCount(const int count) {setInputsCount(count); setOutputsCount(count);} int ioType() const {return io_Type;} PIString libName() const {return lib;} PIString typeName() const {return type;} PIString codeName() const {return className();} PIString parametersName() const {return parametersName_;} PIString inputName(const int index) const {return inNames[index];} PIString outputName(const int index) const {return outNames[index];} PIString parameterName(const int index) const {return paramNames[index];} PIString note() const {return note_;} void setNote(const PIString & str) {note_ = str;} PIString tag() const {return tag_;} void setTag(const PIString & str) {tag_ = str;} BrickManager * manager() const {return manager_;} void setManager(BrickManager * m) {manager_ = m;} bool isInitial() const {return initial;} void setInitial(const bool yes = true) {initial = yes;} bool isComposite() const {return composite;} void setComposite(const bool yes = true) {composite = yes;} bool isBuffered() const {return buffered;} void setBuffered(const bool yes = true) {buffered = yes;} bool isInteractive() const {return interactive;} void setInteractive(const bool yes = true) {interactive = yes;} bool isRealTimeOnly() const {return rtOnly;} void setRealTimeOnly(const bool yes = true) {rtOnly = yes;} BrickComposite * toComposite() {return reinterpret_cast(this);} struct Connection { int out_num; BrickBase * brick_to; int in_num; Connection() {;} Connection(int out_n, BrickBase * b_to, int in_n) {brick_to = b_to; out_num = out_n; in_num = in_n;} }; void addConnection(Connection conn) {connections.push_back(conn);} void clearConnections() {connections.clear();} BrickBase::Connection connection(int index) const {return connections[index];} int connectionsCount() const {return connections.size();} void removeConnection(int index) {connections.remove(index);} bool lastTick, userBool; double time_, userDouble; int level_, userInt; PIVector buffer; static bool connect(BrickBase * b_from, int out_num, BrickBase * b_to, int in_num); static bool connect(BrickBase * b_from, int out_num, BrickBase & b_to, int in_num) {return connect(b_from, out_num, &b_to, in_num);} static bool connect(BrickBase & b_from, int out_num, BrickBase * b_to, int in_num) {return connect(&b_from, out_num, b_to, in_num);} static bool connect(BrickBase & b_from, int out_num, BrickBase & b_to, int in_num) {return connect(&b_from, out_num, &b_to, in_num);} static bool disconnect(BrickBase * b_from, int out_num, BrickBase * b_to, int in_num); static bool disconnect(BrickBase * b_from, int out_num, BrickBase & b_to, int in_num) {return disconnect(b_from, out_num, &b_to, in_num);} static bool disconnect(BrickBase & b_from, int out_num, BrickBase * b_to, int in_num) {return disconnect(&b_from, out_num, b_to, in_num);} static bool disconnect(BrickBase & b_from, int out_num, BrickBase & b_to, int in_num) {return disconnect(&b_from, out_num, &b_to, in_num);} protected: virtual void copied() {;} virtual bool tick_body(double time) {return true;} PIVector inputs, outputs, defInputs; PIVector connections; PIVector parameters; PIVector inNames, outNames, paramNames; PIString parametersName_, lib, type, note_, tag_; int inputs_count, outputs_count, parameters_count, io_Type, tmp_, freqDivider_, freqCurrent_; double dt, pt; bool initial, ticked, composite, buffered, interactive, rtOnly; BrickManager * manager_; }; #endif // BRICK_BASE_H