00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00027
00028 #include <sstream>
00029 #include "ShDebug.hpp"
00030 #include "ShVariableNode.hpp"
00031 #include "ShError.hpp"
00032 #include "ShAlgebra.hpp"
00033 #include "ShFixedManipulator.hpp"
00034 #include "ShEnvironment.hpp"
00035
00036 namespace SH {
00037
00038 ShFixedManipulatorNode::ShFixedManipulatorNode() {
00039 }
00040
00041 ShFixedManipulatorNode::~ShFixedManipulatorNode() {
00042 }
00043
00044 ShKeepNode::ShKeepNode(int numChannels)
00045 : m_numChannels(numChannels) {
00046 }
00047
00048 ShProgram ShKeepNode::applyToInputs(ShManipVarIterator &finger, ShManipVarIterator end) const {
00049 ShProgram result = SH_BEGIN_PROGRAM() {
00050 for(int i = 0; i < m_numChannels; ++i, ++finger) {
00051 if(finger == end) {
00052 shError(ShAlgebraException("Not enough ShProgram channels for shKeep manipulator"));
00053 }
00054 ShVariable inout = (*finger)->clone(SH_INOUT);
00055 }
00056 } SH_END;
00057 return result;
00058 }
00059
00060 ShProgram ShKeepNode::applyToOutputs(ShManipVarIterator &finger, ShManipVarIterator end) const {
00061 return applyToInputs(finger, end);
00062 }
00063
00064 ShFixedManipulator shKeep(int numChannels) {
00065 return new ShKeepNode(numChannels);
00066 }
00067
00068
00069 ShLoseNode::ShLoseNode(int numChannels)
00070 : m_numChannels(numChannels) {
00071 }
00072
00073 ShProgram ShLoseNode::applyToInputs(ShManipVarIterator &finger, ShManipVarIterator end) const {
00074
00075 ShProgram result = SH_BEGIN_PROGRAM() {
00076 for(int i = 0; i < m_numChannels; ++i, ++finger) {
00077 if(finger == end) {
00078 shError(ShAlgebraException("Not enough ShProgram input channels for shLose manipulator"));
00079 }
00080 ShVariable output((*finger)->clone(SH_OUTPUT));
00081 }
00082 } SH_END;
00083 return result;
00084 }
00085
00086 ShProgram ShLoseNode::applyToOutputs(ShManipVarIterator &finger, ShManipVarIterator end) const {
00087 ShProgram result = SH_BEGIN_PROGRAM() {
00088 for(int i = 0; i < m_numChannels; ++i, ++finger) {
00089 if(finger == end) {
00090 shError(ShAlgebraException("Not enough ShProgram output channels for shLose manipulator"));
00091 }
00092 ShVariable input((*finger)->clone(SH_INPUT));
00093 }
00094 } SH_END;
00095 return result;
00096 }
00097
00098 ShFixedManipulator shLose(int numChannels) {
00099 return new ShLoseNode(numChannels);
00100 }
00101
00102 ShDupNode::ShDupNode(int numDups)
00103 : m_numDups(numDups) {
00104 }
00105
00106 ShProgram ShDupNode::applyToInputs(ShManipVarIterator &finger, ShManipVarIterator end) const {
00107 ShProgram result = SH_BEGIN_PROGRAM() {
00108 ShVariable input;
00109 for(int i = 0; i < m_numDups; ++i, ++finger) {
00110 if(finger == end) {
00111 shError(ShAlgebraException("Not enough ShProgram input channels for shDup manipulator"));
00112 }
00113 if(i == 0) {
00114 input = (*finger)->clone(SH_INPUT);
00115 }
00116 if((*finger)->size() != input.size()) {
00117 shError(ShAlgebraException("Duplicating type " + input.node()->nameOfType()
00118 + " to incompatible type " + (*finger)->nameOfType()));
00119 }
00120 ShVariable output((*finger)->clone(SH_OUTPUT));
00121 shASN(output, input);
00122 }
00123 } SH_END;
00124 return result;
00125 }
00126
00127 ShProgram ShDupNode::applyToOutputs(ShManipVarIterator &finger, ShManipVarIterator end) const {
00128 ShProgram result = SH_BEGIN_PROGRAM() {
00129 if(finger == end) {
00130 shError(ShAlgebraException("Not enough ShProgram output channels for shDup manipulator"));
00131 }
00132 ShVariable input((*finger)->clone(SH_INPUT));
00133
00134 for(int i = 0; i < m_numDups; ++i) {
00135 ShVariable output((*finger)->clone(SH_OUTPUT));
00136 shASN(output, input);
00137 }
00138 ++finger;
00139 } SH_END;
00140 return result;
00141 }
00142
00143 ShFixedManipulator shDup(int numDups) {
00144 return new ShDupNode(numDups);
00145 }
00146
00147 ShProgramManipNode::ShProgramManipNode(const ShProgram &p)
00148 : p(p) {
00149 }
00150
00151 ShProgram ShProgramManipNode::applyToInputs(ShManipVarIterator &finger, ShManipVarIterator end) const {
00152 std::size_t i;
00153 for(i = 0; i < p.node()->outputs.size() && finger != end; ++i, ++finger);
00154
00155 return p;
00156 }
00157
00158 ShProgram ShProgramManipNode::applyToOutputs(ShManipVarIterator &finger, ShManipVarIterator end) const {
00159 std::size_t i;
00160 for(i = 0; i < p.node()->inputs.size() && finger != end; ++i, ++finger);
00161
00162 return p;
00163 }
00164
00165 ShTreeManipNode::ShTreeManipNode(const ShFixedManipulator &a, const ShFixedManipulator &b)
00166 : a(a), b(b) {
00167 SH_DEBUG_ASSERT(a);
00168 SH_DEBUG_ASSERT(b);
00169 }
00170
00171 ShProgram ShTreeManipNode::applyToInputs(ShManipVarIterator &finger, ShManipVarIterator end) const {
00172 ShProgram aProgram = a->applyToInputs(finger, end);
00173 ShProgram bProgram = b->applyToInputs(finger, end);
00174 return aProgram & bProgram;
00175 }
00176
00177 ShProgram ShTreeManipNode::applyToOutputs(ShManipVarIterator &finger, ShManipVarIterator end) const {
00178 ShProgram aProgram = a->applyToOutputs(finger, end);
00179 ShProgram bProgram = b->applyToOutputs(finger, end);
00180 return aProgram & bProgram;
00181 }
00182
00183 ShProgram operator<<(const ShProgram &p, const ShFixedManipulator &m) {
00184 ShManipVarIterator finger = p.node()->inputs.begin();
00185 ShProgram manipulator = m->applyToInputs(finger, p.node()->inputs.end());
00186 return p << manipulator;
00187 }
00188
00189 ShProgram operator<<(const ShFixedManipulator &m, const ShProgram &p) {
00190 ShManipVarIterator finger = p.node()->outputs.begin();
00191 ShProgram manipulator = m->applyToOutputs(finger, p.node()->outputs.end());
00192 return manipulator << p;
00193 }
00194
00195 ShFixedManipulator operator&(const ShFixedManipulator &m, const ShFixedManipulator &n) {
00196 return new ShTreeManipNode(m, n);
00197 }
00198
00199 ShFixedManipulator operator&(const ShFixedManipulator &m, const ShProgram &p) {
00200 return m & new ShProgramManipNode(p);
00201 }
00202 ShFixedManipulator operator&(const ShProgram &p, const ShFixedManipulator &m) {
00203 return new ShProgramManipNode(p) & m;
00204 }
00205
00206 }
00207