OSSIM - Open Source Software Image Map  Version 1.9.0 (20180803)
ossimConnectableContainer.cpp
Go to the documentation of this file.
1 //*******************************************************************
2 // Copyright (C) 2000 ImageLinks Inc.
3 //
4 // License: See top level LICENSE.txt file.
5 //
6 // Author: Garrett Potts
7 //
8 //*************************************************************************
9 // $Id: ossimConnectableContainer.cpp 21850 2012-10-21 20:09:55Z dburken $
10 
18 #include <ossim/base/ossimTrace.h>
21 #include <algorithm>
22 #include <stack>
23 
24 static ossimTrace traceDebug("ossimConnectableContainer:debug");
25 
27 
29 {
30 public:
32  :theContainer(container),
34  {}
37 
39  {
41  if(object&&theContainer)
42  {
43  if(theContainer->removeChild(object))
44  {
45  object->removeListener((ossimConnectableObjectListener*) this);
46  }
47  }
49 
50  }
52  {
54  }
56  {
58  }
59 
61  {
62  if(theEnabledFlag)
63  {
64  if(event.getObject())
65  {
67  event.getObject());
68  if(connectable)
69  {
70  ossimPropertyEvent evt(event.getObject());
71  connectable->propagateEventToOutputs(evt);
72  }
73  }
74  }
75  }
78 
79 };
80 
82  :ossimConnectableObject(owner, 0, 0, true, true),
84 {
87 }
88 
90 {
91  // will need to destory and detach all children
92  //
94 
96  {
97  delete theChildListener;
98  }
99  theChildListener = 0;
100 }
101 
103  bool recurse)
104 {
105  ossimConnectableObject* result = NULL;
106  connectablObjectMapType::iterator current;
107 
108  current = theObjectMap.begin();
109  while(current != theObjectMap.end())
110  {
111  if(((*current).second)->canCastTo(typeInfo))
112  {
113  return (*current).second.get();
114  }
115  ++current;
116  }
117 
118  if(recurse)
119  {
120  current = theObjectMap.begin();
121  while(current != theObjectMap.end())
122  {
124 
125  if(child)
126  {
127  result = child->findFirstObjectOfType(typeInfo);
128  if(result)
129  {
130  return result;
131  }
132  }
133  ++current;
134  }
135  }
136 
137  return result;
138 }
139 
141  bool recurse)
142 {
143  ossimConnectableObject* result = NULL;
144  connectablObjectMapType::iterator current;
145 
146  current = theObjectMap.begin();
147  while(current != theObjectMap.end())
148  {
149  if( ((*current).second)->canCastTo(className) )
150  {
151  return (*current).second.get();
152  }
153  ++current;
154  }
155 
156  if(recurse)
157  {
158  current = theObjectMap.begin();
159  while(current != theObjectMap.end())
160  {
162 
163  if(child)
164  {
165  result = child->findFirstObjectOfType(className);
166  if(result)
167  {
168  return result;
169  }
170  }
171  ++current;
172  }
173  }
174 
175  return result;
176 }
177 
179  bool recurse)
180 {
182 
183  connectablObjectMapType::iterator current;
184 
185  current = theObjectMap.begin();
186  while(current != theObjectMap.end())
187  {
188  if(((*current).second)->canCastTo(typeInfo))
189  {
190  result.push_back( (*current).second.get());
191  }
192  ++current;
193  }
194 
195  if(recurse)
196  {
197  current = theObjectMap.begin();
198  while(current != theObjectMap.end())
199  {
201 
202  if(child)
203  {
205  temp = child->findAllObjectsOfType(typeInfo, recurse);
206  for(long index=0; index < (long)temp.size();++index)
207  {
208  result.push_back(temp[index]);
209  }
210  }
211  ++current;
212  }
213  }
214  return result;
215 }
216 
218  bool recurse)
219 {
221 
222  connectablObjectMapType::iterator current;
223 
224  current = theObjectMap.begin();
225  while(current != theObjectMap.end())
226  {
227  if(((*current).second)->canCastTo(className))
228  {
229  result.push_back( (*current).second.get());
230  }
231  ++current;
232  }
233 
234  if(recurse)
235  {
236  current = theObjectMap.begin();
237  while(current != theObjectMap.end())
238  {
240 
241  if(child)
242  {
244  temp = child->findAllObjectsOfType(className, true);
245  for(long index=0; index < (long)temp.size();++index)
246  {
247  result.push_back(temp[index]);
248  }
249  }
250  ++current;
251  }
252  }
253  return result;
254 }
255 
257  bool recurse)
258 {
259  connectablObjectMapType::iterator current;
260 
261  current = theObjectMap.begin();
262 
263  while(current != theObjectMap.end())
264  {
265  if((*current).second.valid() && ((*current).second->getId()==id))
266  {
267  return (*current).second.get();
268  }
269  ++current;
270  }
271 
272  if(recurse)
273  {
274  current = theObjectMap.begin();
275 
276  while(current != theObjectMap.end())
277  {
279 
280  if(child)
281  {
282  ossimConnectableObject* object = child->findObject(id, true);
283 
284  if(object) return object;
285  }
286  ++current;
287  }
288  }
289  return NULL;
290 }
291 
293  bool recurse)
294 {
295  connectablObjectMapType::iterator current;
296 
297  current = theObjectMap.begin();
298 
299  while(current != theObjectMap.end())
300  {
301  if((*current).second.valid() && ((*current).second==obj))
302  {
303  return (*current).second.get();
304  }
305  ++current;
306  }
307 
308  if(recurse)
309  {
310  current = theObjectMap.begin();
311 
312  while(current != theObjectMap.end())
313  {
315 
316  if(child)
317  {
318  ossimConnectableObject* object = child->findObject(obj, true);
319 
320  if(object) return object;
321  }
322  ++current;
323  }
324  }
325 
326  return NULL;
327 }
328 
330 {
331  connectablObjectMapType::iterator current;
332  std::vector<ossimRefPtr<ossimConnectableObject> > objectList;
333 
334 
335  current = theObjectMap.begin();
336 
337  setId(ossimIdManager::instance()->generateId());
338  while(current != theObjectMap.end())
339  {
340  objectList.push_back((*current).second.get());
341  ++current;
342  }
343  theObjectMap.clear();
344 
345  for(long index = 0; index < (long)objectList.size(); ++index)
346  {
348  objectList[index].get());
349  if(container)
350  {
351  container->makeUniqueIds();
352  theObjectMap.insert(std::make_pair(objectList[index]->getId().getId(),
353  objectList[index].get()));
354  }
355  else
356  {
357  objectList[index]->setId(ossimIdManager::instance()->generateId());
358  theObjectMap.insert(std::make_pair(objectList[index]->getId().getId(),
359  objectList[index].get()));
360  }
361  }
362 }
363 
365 {
366  ossim_uint32 result = 0;
367 
368  connectablObjectMapType::const_iterator current;
369 
370  current = theObjectMap.begin();
371 
372  while(current != theObjectMap.end())
373  {
374  ++result;
375 
376  if(recurse)
377  {
379  if(child)
380  {
381  result += child->getNumberOfObjects(true);
382  }
383  }
384  ++current;
385  }
386 
387  return result;
388 }
389 
391 {
392  if(object)
393  {
394  // if it's not already a child
395 
396  ossimIdVisitor visitor(
397  object->getId(),
399  accept( visitor );
400 
401  // if(!findObject(object->getId()))
402  if ( !visitor.getObject() )
403  {
404  object->changeOwner(this);
405  theObjectMap.insert(std::make_pair(object->getId().getId(), object));
406  object->addListener(theChildListener);
407  }
408 
409  return true;
410  }
411 
412  return false;
413 }
414 
416 {
417  ossimConnectableObject* result = NULL;
418 
419  if(object)
420  {
421  connectablObjectMapType::iterator childIter = theObjectMap.find(object->getId().getId());
422  if(childIter != theObjectMap.end())
423  {
424  result = (*childIter).second.get();
425  if(result->getOwner() == this)
426  {
427  result->changeOwner(NULL);
429 // result->removeListener(this);
430  }
431  theObjectMap.erase(childIter);
432  }
433  }
434 
435  return (result!=NULL);
436 }
437 
439  const char* prefix)
440 {
441  static const char* MODULE = "ossimConnectableContainer::loadState(kwl, prefix)";
442 
443  ossimString copyPrefix = prefix;
444  bool result = ossimConnectableObject::loadState(kwl, copyPrefix.c_str());
445 
446  std::map<ossimId, std::vector<ossimId> > idMapping;
447  result = addAllObjects(idMapping, kwl, prefix);
448  if(!result)
449  {
451  << MODULE << " error: " << "problems adding sources" << std::endl;
452  }
453  result = connectAllObjects(idMapping);
454  if(!result)
455  {
457  << MODULE << " error: " << "problems connecting sources\n";
458  }
459 
460  return result;
461 }
462 
464  const char* prefix)const
465 {
466  bool result = true;
467  connectablObjectMapType::const_iterator current;
468 
469  ossim_int32 childIndex = 1;
470  current = theObjectMap.begin();
471  while(current != theObjectMap.end())
472  {
473  ossimString newPrefix = ( (ossimString(prefix) +
474  ossimString("object") +
475  ossimString::toString(childIndex) + "."));
476  if((*current).second.valid())
477  {
478  bool test = ((*current).second)->saveState(kwl, newPrefix);
479  if(!test)
480  {
481  result = false;
482  }
483  }
484  ++childIndex;
485  ++current;
486  }
487  if(result)
488  {
489  result = ossimConnectableObject::saveState(kwl, prefix);
490  }
491 
492  return result;
493 }
494 
495 void ossimConnectableContainer::getChildren(std::vector<ossimConnectableObject*>& children,
496  bool immediateChildrenOnlyFlag)
497 {
498  connectablObjectMapType::iterator current;
499  current = theObjectMap.begin();
500  std::vector<ossimConnectableObject*> temp;
501 
502  while(current != theObjectMap.end())
503  {
504  temp.push_back((*current).second.get());
505  }
506  ossim_uint32 i;
507  for(i = 0; i < temp.size();++i)
508  {
509 
510  if(!immediateChildrenOnlyFlag)
511  {
513  (*current).second.get());
514  if(!inter)
515  {
516  children.push_back(temp[i]);
517  }
518  }
519  else
520  {
521  children.push_back(temp[i]);
522  }
523  }
524 
525  if(!immediateChildrenOnlyFlag)
526  {
527  for(i = 0; i < temp.size(); ++i)
528  {
530  (*current).second.get());
531 
532  if(inter)
533  {
534  inter->getChildren(children,
535  immediateChildrenOnlyFlag);
536  }
537  }
538  }
539 }
540 
542 {
543  connectablObjectMapType::iterator current;
545  current = theObjectMap.begin();
547 
548  while(theObjectMap.size())
549  {
550  current = theObjectMap.begin();
551  temp = (*current).second.get();
552  if(temp)
553  {
555  temp->disconnect();
556  (*current).second = NULL;
557  }
558  theObjectMap.erase(current);
559  }
560 }
561 
563 {
564  connectablObjectMapType::iterator current;
566  current = theObjectMap.begin();
567 
568  while(current != theObjectMap.end())
569  {
570  temp = (*current).second.get();
571  if(temp)
572  {
574 // temp->removeListener((ossimConnectableObjectListener*) this);
575  }
576  ++current;
577  }
578 }
579 
581  std::vector<ossimId> >& idMapping,
582  const ossimKeywordlist& kwl,
583  const char* prefix)
584 {
585  ossimString copyPrefix = prefix;
586 
587  std::vector<ossimId> inputConnectionIds;
588 
589  ossimString regExpression = ossimString("^(") + copyPrefix + "object[0-9]+.)";
590  std::vector<ossimString> keys =
591  kwl.getSubstringKeyList( regExpression );
592  long numberOfSources = (long)keys.size();
593 
594  int offset = (int)(copyPrefix+"object").size();
595  int idx = 0;
596  std::vector<int> theNumberList(numberOfSources);
597  for(idx = 0; idx < (int)theNumberList.size();++idx)
598  {
599  ossimString numberStr(keys[idx].begin() + offset,
600  keys[idx].end());
601  theNumberList[idx] = numberStr.toInt();
602  }
603  std::sort(theNumberList.begin(), theNumberList.end());
604  for(idx=0;idx < (int)theNumberList.size();++idx)
605  {
606  ossimString newPrefix = copyPrefix;
607  newPrefix += ossimString("object");
608  newPrefix += ossimString::toString(theNumberList[idx]);
609  newPrefix += ossimString(".");
610 
611  if(traceDebug())
612  {
613  ossimNotify(ossimNotifyLevel_DEBUG) << "trying to create source with prefix: " << newPrefix << "\n";
614  }
616  newPrefix.c_str());
617  if(object.valid())
618  {
619  ossimConnectableObject* connectable = PTR_CAST(ossimConnectableObject, object.get());
620  if(connectable)
621  {
622  if(traceDebug())
623  {
624  ossimNotify(ossimNotifyLevel_DEBUG) << "Created source with prefix: " << newPrefix << "\n";
625  }
626  // we did find a source so include it in the count
627  ossimId id = connectable->getId();
628  inputConnectionIds.clear();
629 
630  findInputConnectionIds(inputConnectionIds,
631  kwl,
632  newPrefix);
633 
634  if(inputConnectionIds.size() != 0)
635  {
636  idMapping.insert(std::make_pair(id, inputConnectionIds));
637  }
638  addChild(connectable);
639  }
640  }
641  }
642 
643  return true;
644 }
645 
646 void ossimConnectableContainer::findInputConnectionIds(std::vector<ossimId>& result,
647  const ossimKeywordlist& kwl,
648  const char* prefix)
649 {
650  ossimString newPrefix = prefix;
651 
652  ossim_uint32 counter = 0;
653  ossim_uint32 numberOfMatches = 0;
654 
655  ossimString regExpression = ossimString("^") + newPrefix + "input_connection[0-9]+";
656  ossim_uint32 numberOfKeys = kwl.getNumberOfSubstringKeys( regExpression);
657  std::vector<ossimString> l = kwl.getSubstringKeyList(regExpression);
658  if(numberOfKeys > 0)
659  {
660  newPrefix += "input_connection";
661 
662  while(numberOfMatches < numberOfKeys)
663  {
664  const char* lookup = kwl.find(newPrefix,
665  ossimString::toString(counter));
666  if(lookup)
667  {
668  ++numberOfMatches;
669  long id = ossimString(lookup).toLong();
670  if(id != ossimId::INVALID_ID)
671  {
672  result.push_back(ossimId(id));
673  }
674  }
675  ++counter;
676  }
677  }
678 }
679 
680 bool ossimConnectableContainer::connectAllObjects(const std::map<ossimId, std::vector<ossimId> >& idMapping)
681 {
682  if(idMapping.size())
683  {
684 
686 
687  std::map<ossimId, std::vector<ossimId> >::const_iterator iter = idMapping.begin();
688 
689  while(iter != idMapping.end())
690  {
691  visitor.setId( (*iter).first );
692  accept( visitor );
693  ossimConnectableObject* currentObject = visitor.getObject();
694  // ossimConnectableObject* currentObject = findObject((*iter).first);
695 
696  if(currentObject)
697  {
698  long upperBound = (long)(*iter).second.size();
699  for(long index = 0; index < upperBound; ++index)
700  {
701  visitor.reset();
702  visitor.setId( (*iter).second[index] );
703  accept( visitor );
704  ossimConnectableObject* inputObject = visitor.getObject();
705  if ( inputObject )
706  {
707  currentObject->connectMyInputTo(index, inputObject);
708  }
709  // ossimConnectableObject* inputObject = findObject((*iter).second[index]);
710  // currentObject->connectMyInputTo(index, inputObject);
711  }
712  }
713  else
714  {
716  << "ossimConnectableContainer::connectAllObjects, Could not find "
717  << (*iter).first << " for source: \n";
718  return false;
719  }
720  visitor.reset();
721  ++iter;
722  }
723  }
724  return true;
725 }
726 
728 {
729  return this;
730 }
731 
733 {
734  return this;
735 }
736 
738  ossim_uint32 index)
739 {
740  ossimConnectableObject* result = NULL;
741 
742  if (index > theObjectMap.size())
743  {
744  return result;
745  }
746 
747  connectablObjectMapType::iterator current;
748  current = theObjectMap.begin();
749  ossim_uint32 i = 0;
750  while(current != theObjectMap.end())
751  {
752  if (i == index)
753  {
754  return (*current).second.get();
755  }
756  ++current;
757  ++i;
758  }
759 
760  return result;
761 }
762 
764  const ossimConnectableObject*) const
765 {
766  return false;
767 }
768 
770  const ossimConnectableObject*) const
771 {
772  return false;
773 }
774 
776 {
777  if(!visitor.hasVisited(this))
778  {
779  visitor.visit(this);
780  ossimVisitor::VisitorType currentType = visitor.getVisitorType();
781  // lets make sure inputs and outputs are turned off for we are traversing all children and we should not have
782  // to have that enabled
783  //
786  {
787  connectablObjectMapType::iterator current = theObjectMap.begin();
788  while((current != theObjectMap.end())&&!visitor.stopTraversal())
789  {
790  ossimRefPtr<ossimConnectableObject> currentObject = (current->second);
791  if(currentObject.valid()&&!visitor.hasVisited(currentObject.get())) currentObject->accept(visitor);
792  ++current;
793  }
794  }
795  visitor.setVisitorType(currentType);
796  }
797 
799 
800 }
801 
802 //**************************************************************************************************
803 // Inserts all of this object's children and inputs into the container provided. Since this is
804 // itself a container, this method will consolidate this with the argument container. Therefore
805 // this object will not be represented in the argument container (but its children will be).
806 // Returns TRUE if successful.
807 //**************************************************************************************************
809 {
810  connectablObjectMapType::iterator current;
811  current = theObjectMap.begin();
812  // ossim_uint32 i = 0;
813  // bool fill_ok;
814  while(current != theObjectMap.end())
815  {
816  ossimRefPtr<ossimConnectableObject> currentObject = current->second;
817  if (currentObject.valid())
818  container.addChild(currentObject.get());
819  current++;
820  }
821  return true;
822 }
ossimConnectableContainerChildListener(ossimConnectableContainer *container)
bool connectAllObjects(const std::map< ossimId, std::vector< ossimId > > &idMapping)
virtual void visit(ossimObject *obj)
const ossimObject * getOwner() const
Fetches the current owner, most likely a container but not limited to one.
virtual bool canConnectMyInputTo(ossim_int32 index, const ossimConnectableObject *obj) const
required to be overriden by derived classes
ossimConnectableContainerChildListener * theChildListener
void setId(const ossimId &id)
ossim_uint32 getNumberOfSubstringKeys(const ossimString &regularExpression) const
virtual ossimConnectableObject * findFirstObjectOfType(const RTTItypeid &typeInfo, bool recurse=true)=0
virtual void disconnect(ossimConnectableObject *object=0)
Will disconnect the object passed in.
virtual ossim_uint32 getNumberOfObjects(bool recurse=true) const =0
bool addAllObjects(std::map< ossimId, std::vector< ossimId > > &idMapping, const ossimKeywordlist &kwl, const char *prefix)
Represents serializable keyword/value map.
bool valid() const
Definition: ossimRefPtr.h:75
const char * find(const char *key) const
void setVisitorType(int vType, bool on=true)
virtual void propagateEventToOutputs(ossimEvent &event)
virtual void objectDestructingEvent(ossimObjectDestructingEvent &event)
virtual bool canConnectMyOutputTo(ossim_int32 index, const ossimConnectableObject *obj) const
default implementation is to allow anyone to connect to us.
virtual ossimConnectableObject::ConnectableObjectList findAllObjectsOfType(const RTTItypeid &typeInfo, bool recurse=true)=0
static ossimString toString(bool aValue)
Numeric to string methods.
static const ossim_int64 INVALID_ID
Definition: ossimId.h:83
static ossimObjectFactoryRegistry * instance()
class OSSIMDLLEXPORT ossimConnectableContainerChildListener
ossim_int64 getId() const
Definition: ossimId.h:29
virtual void getChildren(std::vector< ossimConnectableObject *> &children, bool immediateChildrenOnlyFlag)=0
void turnOffVisitorType(int vType)
virtual bool saveState(ossimKeywordlist &kwl, const char *prefix=0) const
std::vector< ossimRefPtr< ossimConnectableObject > > ConnectableObjectList
virtual void changeOwner(ossimObject *owner)
Permits changing the object&#39;s owner.
const ossimObject * getObject() const
This is the originating object that originally produced the event.
Definition: ossimEvent.cpp:64
void findInputConnectionIds(std::vector< ossimId > &result, const ossimKeywordlist &kwl, const char *prefix)
const ossimId & getId() const
Will allow us to get this object&#39;s id.
virtual ossimConnectableObject * getConnectableObject(ossim_uint32 index)
unsigned int ossim_uint32
#define PTR_CAST(T, p)
Definition: ossimRtti.h:321
bool hasVisited(ossimObject *obj) const
virtual bool loadState(const ossimKeywordlist &kwl, const char *prefix=0)
virtual ossim_int32 connectMyInputTo(ossimConnectableObject *inputObject, bool makeOutputConnection=true, bool createEventFlag=true)
Will try to connect this objects input to the passed in object.
ossimConnectableObject * getObject()
virtual void disconnectInputEvent(ossimConnectionEvent &event)
virtual ossimConnectableObject * findObject(const ossimId &id, bool recurse=true)=0
std::vector< ossimString > getSubstringKeyList(const ossimString &regularExpression) const
virtual bool loadState(const ossimKeywordlist &kwl, const char *prefix=0)
virtual void reset()
Resets m_object to 0, calls ossimVisitor::reset().
ossim_uint32 getNumberOfObjects(bool recurse=true) const
virtual void getChildren(std::vector< ossimConnectableObject *> &children, bool immediateChildrenOnlyFlag)
long toLong() const
toLong&#39;s deprecated, please use the toInts...
virtual bool addChild(ossimConnectableObject *attachableObject)
VisitorType getVisitorType() const
virtual ossimObject * createObject(const ossimString &name) const
RTTI_DEF2(ossimConnectableContainer, "ossimConnectableContainer", ossimConnectableObject, ossimConnectableContainerInterface)
const char * c_str() const
Returns a pointer to a null-terminated array of characters representing the string&#39;s contents...
Definition: ossimString.h:396
VisitorType
Enumeration type can be a mask and will traverse a graph of connectables based on the values...
Definition: ossimVisitor.h:27
bool stopTraversal() const
virtual void accept(ossimVisitor &visitor)
We will add a visitor interface for all connectable objects.
virtual void connectInputEvent(ossimConnectionEvent &event)
void setId(const ossimId &id)
All connectable objects will have id&#39;s.
virtual bool fillContainer(ossimConnectableContainer &container)
ossimConnectableContainer(ossimConnectableObject *owner=0)
virtual bool removeChild(ossimConnectableObject *object)
connectablObjectMapType theObjectMap
int toInt() const
OSSIMDLLEXPORT std::ostream & ossimNotify(ossimNotifyLevel level=ossimNotifyLevel_WARN)
virtual bool saveState(ossimKeywordlist &kwl, const char *prefix=0) const
static ossimIdManager * instance()
int ossim_int32
virtual void accept(ossimVisitor &visitor)
We will add a visitor interface for all connectable objects.
virtual bool removeListener(ossimListener *listener)