00001 #ifndef __INSTANTIO_OUTSLOT_H
00002 #define __INSTANTIO_OUTSLOT_H
00003
00004 #ifdef _MSC_VER
00005 # pragma once
00006 #endif
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include "InstantIODef.h"
00027 #include "BasicOutSlot.h"
00028 #include "InSlot.h"
00029 #include "Data.h"
00030 #include "TypeName.h"
00031 #include <string>
00032 #include <vector>
00033 #include <typeinfo>
00034 #ifdef __sgi
00035 # include <assert.h>
00036 #else
00037 # include <cassert>
00038 #endif
00039
00040
00041 namespace InstantIO
00042 {
00043
00044
00045 template <class T> class InSlot;
00046
00047
00143 template <class T> class OutSlot: public BasicOutSlot
00144 {
00145
00147 friend class InSlot<T>;
00148
00149 public:
00150
00154 inline OutSlot()
00155 : BasicOutSlot(), inSlots_(), currentValue_()
00156 {}
00157
00165 inline explicit OutSlot(const std::string &description)
00166 : BasicOutSlot(description), inSlots_(), currentValue_()
00167 {}
00168
00173 inline explicit OutSlot(const Data<T> &defaultValue)
00174 : BasicOutSlot(), inSlots_(), currentValue_(defaultValue)
00175 {}
00176
00185 inline OutSlot(const std::string &description, const Data<T> &defaultValue)
00186 : BasicOutSlot(description), inSlots_(), currentValue_(defaultValue)
00187 {}
00188
00192 virtual ~OutSlot() {};
00193
00203 virtual const char *getTypeName() const
00204 { return TypeName<T>::getName(); };
00205
00211 virtual const std::type_info &getTypeID() const
00212 { return typeid(T); };
00213
00226 inline bool isConnected() const
00227 {
00228 lock();
00229 bool result = inSlots_.empty() == false;
00230 unlock();
00231 return result;
00232 }
00233
00244 inline const Data<T> getValue() const
00245 {
00246 lock();
00247 Data<T> result = currentValue_;
00248 unlock();
00249 return result;
00250 }
00251
00258 virtual void push(const Data<T> &value)
00259 {
00260 lock();
00261 currentValue_ = value;
00262 valueIsValid_ = true;
00263 typename InSlotVector::iterator it;
00264 for (it = inSlots_.begin(); it != inSlots_.end(); ++it)
00265 {
00266 assert(it->first != 0);
00267 it->first->push(value);
00268 }
00269 unlock();
00270 };
00271
00291 virtual void connect(BasicInSlot *inSlot)
00292 {
00293 InSlot<T> *is = dynamic_cast<InSlot<T>*>(inSlot);
00294 if (is != 0)
00295 {
00296
00297
00298
00299 is->addOutSlot(this);
00300 addInSlot(is);
00301 }
00302 };
00303
00319 virtual void disconnect(BasicInSlot *inSlot)
00320 {
00321 InSlot<T> *is = dynamic_cast<InSlot<T>*>(inSlot);
00322 if (is != 0)
00323 {
00324
00325
00326
00327 removeInSlot(is);
00328 is->removeOutSlot(this);
00329 }
00330 };
00331
00332 private:
00333
00335 typedef std::pair<InSlot<T>*, unsigned long> RefCountedInSlot;
00336
00338 typedef std::vector<RefCountedInSlot> InSlotVector;
00339
00345 void addInSlot(InSlot<T> *inSlot)
00346 {
00347 assert(inSlot != 0);
00348 bool empty = false;
00349
00350
00351
00352
00353
00354
00355 listenersLock();
00356 lock();
00357 typename InSlotVector::iterator it = findInSlot(inSlot);
00358 if (it == inSlots_.end())
00359 {
00360 empty = inSlots_.empty();
00361 inSlots_.push_back(RefCountedInSlot(inSlot, 1));
00362 if (valueIsValid_ == true)
00363 inSlot->push(currentValue_);
00364 }
00365 else
00366 ++(it->second);
00367 unlock();
00368 if (empty == true)
00369 startOutSlot();
00370 listenersUnlock();
00371 };
00372
00378 void removeInSlot(InSlot<T> *inSlot)
00379 {
00380 assert(inSlot != 0);
00381
00382
00383
00384
00385
00386
00387 listenersLock();
00388 lock();
00389 typename InSlotVector::iterator it = findInSlot(inSlot);
00390 if ((it != inSlots_.end()) && (--(it->second) == 0))
00391 inSlots_.erase(it);
00392 unlock();
00393 if (inSlots_.empty())
00394 stopOutSlot();
00395 listenersUnlock();
00396 };
00397
00404 typename InSlotVector::iterator findInSlot(InSlot<T> *inSlot)
00405 {
00406
00407 assert(inSlot != 0);
00408 typename InSlotVector::iterator it;
00409 for (it = inSlots_.begin(); it != inSlots_.end(); ++it)
00410 if (it->first == inSlot)
00411 break;
00412 return it;
00413 };
00414
00416
00417 InSlotVector inSlots_;
00418
00420
00421 Data<T> currentValue_;
00422
00424 OutSlot(const OutSlot<T> &);
00425
00427 const OutSlot<T> &operator=(const OutSlot<T> &);
00428 };
00429
00430
00431 }
00432
00433
00434 #endif //__INSTANTIO_OUTSLOT_H