CCA
Splitter.h
Go to the documentation of this file.
00001 /* ============================================================
00002  *
00003  * This file is a part of CCA project
00004  *
00005  * Copyright (C) 2011 by Arne Nordmann <anordman at cor-lab dot uni-bielefeld dot de>
00006  *
00007  * This file may be licensed under the terms of the
00008  * GNU Lesser General Public License Version 3 (the ``LGPL''),
00009  * or (at your option) any later version.
00010  *
00011  * Software distributed under the License is distributed
00012  * on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
00013  * express or implied. See the LGPL for the specific language
00014  * governing rights and limitations.
00015  *
00016  * You should have received a copy of the LGPL along with this
00017  * program. If not, go to http://www.gnu.org/licenses/lgpl.html
00018  * or write to the Free Software Foundation, Inc.,
00019  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00020  *
00021  * The development of this software was supported by:
00022  *   CoR-Lab, Research Institute for Cognition and Robotics
00023  *     Bielefeld University
00024  *
00025  * ============================================================ */
00026 
00027 #pragma once
00028 
00029 #include <string>
00030 #include <vector>
00031 
00032 #include <boost/shared_ptr.hpp>
00033 
00034 #include "cca/Node.h"
00035 #include "cca/processing/PortTriggered.h"
00036 
00037 namespace cca {
00038 
00044 template<class DTOTYPE>
00045 class Splitter: public Node {
00046 public:
00047 
00056     Splitter(std::string nodename, unsigned int dimensionality) :
00057             Node(nodename), dim(dimensionality),
00058                     splitConfig(nemo::IntVector(nemo::dim(dimensionality), 1)),
00059                     ip(), ops() {
00060 
00061         ip = InputPort<DTOTYPE>::create();
00062         registerPort("in", ip);
00063 
00064         for (unsigned int port = 0; port < this->dim; ++port) {
00065             ops.push_back(OutputPort<DTOTYPE>::create());
00066             std::stringstream oss;
00067             oss << "out" << port;
00068             registerPort(oss.str(), ops[port]);
00069         }
00070 
00071         // Default Processing Strategy - restless
00072         this->setProcessingStrategy(PortTriggered::port("in"));
00073     }
00074 
00085     Splitter(std::string nodename, nemo::IntVector config) :
00086             Node(nodename), dim(0), splitConfig(config), ip(), ops() {
00087 
00088         ip = InputPort<DTOTYPE>::create();
00089         registerPort("in", ip);
00090 
00091         int count = 0;
00092         for (unsigned int port = 0; port < splitConfig.dimension(); ++port) {
00093             ops.push_back(OutputPort<DTOTYPE>::create());
00094             std::stringstream oss;
00095             oss << "out" << port;
00096             registerPort(oss.str(), ops[port]);
00097             count += config[port];
00098         }
00099         this->dim = count;
00100 
00101         // Default Processing Strategy - restless
00102         this->setProcessingStrategy(PortTriggered::port("in"));
00103     }
00104 
00105     ~Splitter() {
00106     }
00107 
00112     void onProcess() {
00113         if (!ip->empty()) {
00114             typename InputPort<DTOTYPE>::DataPtr in = this->ip->get();
00115 
00116             if (in->getDimension() != this->dim) {
00117                 throw std::runtime_error(
00118                         "Splitter " + this->getName()
00119                                 + "::onProcess(): Configured splitter dimension and dimension of incoming DTO doesn`t agree.");
00120             }
00121 
00122             std::vector<typename InputPort<DTOTYPE>::DataPtr> splitted =
00123                     in->template split<DTOTYPE>(splitConfig);
00124 
00125             for (unsigned int item = 0; item < splitConfig.dimension();
00126                     ++item) {
00127                 ops[item]->publish(splitted[item]);
00128             }
00129         }
00130     }
00131 
00139     static NodePtr create(std::string nodename, unsigned int number) {
00140         return NodePtr(new Splitter<DTOTYPE>(nodename, number));
00141     }
00142 
00153     static NodePtr create(std::string nodename, nemo::IntVector config) {
00154         return NodePtr(new Splitter<DTOTYPE>(nodename, config));
00155     }
00156 
00170     static NodePtr create(std::string nodename, int first,
00171             int second) {
00172         return NodePtr(
00173                 new Splitter<DTOTYPE>(nodename, nemo::IntVector(first, second)));
00174     }
00175 
00191     static NodePtr create(std::string nodename, int first,
00192             int second, int third) {
00193         return NodePtr(
00194                 new Splitter<DTOTYPE>(nodename,
00195                         nemo::IntVector(first, second, third)));
00196     }
00197 
00205     static NodePtr create(unsigned int number) {
00206         return NodePtr(new Splitter<DTOTYPE>("Splitter", number));
00207     }
00208 
00215     friend std::ostream & operator<<(std::ostream& os,
00216             const Splitter<DTOTYPE> &node) {
00217         os.precision(3); // Precision when printing double values
00218         os << std::endl << "<Splitter '" << node.getName() << "'>" << std::endl;
00219         return os;
00220     }
00221 
00232     virtual void configureOutputPortByIndex(unsigned int index,
00233             PortConfigurationPtr portcfg) {
00234         std::stringstream portname;
00235         portname << "out" << index;
00236         this->configureOutputPort(portname.str(), portcfg);
00237     }
00238 
00247     virtual void configureOutputPortByIndex(unsigned int index,
00248             const std::string &scope) {
00249         std::stringstream portname;
00250         portname << "out" << index;
00251         this->configureOutputPort(portname.str(), scope);
00252     }
00253 
00254 private:
00255     unsigned int dim;
00256     nemo::IntVector splitConfig;
00257     typename InputPort<DTOTYPE>::Ptr ip;
00258     std::vector<typename OutputPort<DTOTYPE>::Ptr> ops;
00259 };
00260 
00261 }