1 //******************************************************************* 2 // Copyright (C) 2000 ImageLinks Inc. 3 // 4 // License: See top level LICENSE.txt file. 5 // 6 // Author: Garrett Potts 7 // 8 // Description: 9 // 10 // Contains class declaration for ossimConnectableObject the base class for 11 // all connectable objects. 12 // 13 //************************************************************************* 14 // $Id$ 15 16 #ifndef ossimConnectableObject_HEADER 17 #define ossimConnectableObject_HEADER 1 18 19 #include <ossim/base/ossimConstants.h> 20 #include <ossim/base/ossimObject.h> 21 #include <ossim/base/ossimId.h> 22 #include <ossim/base/ossimListenerManager.h> 23 #include <ossim/base/ossimPropertyInterface.h> 24 #include <ossim/base/ossimRefPtr.h> 25 #include <vector> 26 27 class ossimVisitor; 28 class ossimConnectableContainer; 29 30 class OSSIMDLLEXPORT ossimConnectableObject : public ossimObject, 31 public ossimListenerManager, 32 public ossimPropertyInterface 33 { 34 public: 35 typedef std::vector<ossimRefPtr<ossimConnectableObject> > ConnectableObjectList; 36 enum ossimConnectableObjectDirectionType 37 { 38 CONNECTABLE_DIRECTION_NONE = 0, 39 CONNECTABLE_DIRECTION_INPUT = 1, 40 CONNECTABLE_DIRECTION_OUTPUT = 2 41 }; 42 /** 43 * Base constructor of this object. 44 */ 45 ossimConnectableObject(ossimObject* owner=0); 46 ossimConnectableObject(ossimObject* owner, 47 ossim_int32 inputListSize, 48 ossim_int32 outputListSize, 49 bool inputListIsFixedFlag=true, 50 bool outputListIsFixedFlag=true); 51 52 virtual ~ossimConnectableObject(); 53 /** 54 * All connectable objects will have id's. This allows us to 55 * set the id of this object. 56 */ 57 void setId(const ossimId& id); 58 59 /** 60 * Will allow us to get this object's id. 61 */ 62 const ossimId& getId()const; 63 64 /** 65 * Fetches the current owner, most likely a container but not limited to one. 66 */ 67 const ossimObject* getOwner() const; 68 69 /** 70 * Permits changing the object's owner. 71 */ 72 virtual void changeOwner(ossimObject* owner); 73 74 virtual void setDescription(const ossimString& description); 75 virtual ossimString getDescription()const; 76 77 /** 78 * will check the direction specified to see if all slots are full. 79 * If any slot is null then false is returned. 80 * If a filter requires options testing they 81 * need to override this method. The argument can be ored together. If you 82 * want both checked then pass 83 * CONNECTABLE_DIRECTION_INPUT | CONNECTABLE_DIRECTION_OUTPUT 84 */ 85 virtual bool isConnected( 86 ossimConnectableObjectDirectionType direction = CONNECTABLE_DIRECTION_INPUT)const; 87 88 89 /*! 90 * These methods are now deprecated. You can achieve the same thing by 91 * using the new visitor design pattern. If this does not achieve exactly 92 * what you want then you can derive new rules by overriding the virtual 93 * visit method in ossimVisitor 94 * 95 * <pre> 96 * ossimIdVisitor visitor(id, false, ossimVisitor::VISIT_CHILDREN | 97 * ossimVisitor::VISIT_INPUTS); 98 * connectableObject->accept(visitor); 99 * ossimRefPtr<ossimConnectableObject> object = visitor.getObject(); 100 * </pre> 101 */ 102 OSSIM_DEPRECATE_METHOD(virtual ossimConnectableObject* findConnectableObject( 103 const ossimId& id)); 104 105 /*! 106 * These methods are now deprecated. You can achieve the same thing by 107 * using the new visitor design pattern. If this does not achieve exactly 108 * what you want then you can derive new rules by overriding the virtual 109 * visit method in ossimVisitor 110 * 111 * <pre> 112 * ossimTypeIdVisitor visitor(typeId, true, ossimVisitor::VISIT_CHILDREN | 113 * ossimVisitor::VISIT_INPUTS); 114 * connectableObject->accept(visitor); 115 * ossimRefPtr<ossimConnectableObject> object = visitor.getObject(); 116 * </pre> 117 */ 118 OSSIM_DEPRECATE_METHOD(virtual ossimConnectableObject* findObjectOfType( 119 RTTItypeid typeId, 120 ossimConnectableObjectDirectionType directionType, 121 bool recurse = true)); 122 123 /*! 124 * These methods are now deprecated. You can achieve the same thing by 125 * using the new visitor design pattern. If this does not 126 * achieve exactly what you want then you can derive new rules by overriding 127 * the virtual visit method in ossimVisitor 128 * 129 * <pre> 130 * ossimTypeNameVisitor visitor(typeName, true, 131 * ossimVisitor::VISIT_CHILDREN | ossimVisitor::VISIT_INPUTS); 132 * connectableObject->accept(visitor); 133 * ossimRefPtr<ossimConnectableObject> object = visitor.getObject(); 134 * </pre> 135 */ 136 OSSIM_DEPRECATE_METHOD(virtual ossimConnectableObject* findObjectOfType( 137 const ossimString& obj, 138 ossimConnectableObjectDirectionType directionType, 139 bool recurse = true)); 140 141 /*! 142 * These methods are now deprecated. You can achieve the same thing by 143 * using the new visitor design pattern. If this does not 144 * achieve exactly what you want then you can derive new rules by overriding 145 * the virtual visit method in ossimVisitor 146 * 147 * <pre> 148 * ossimTypeNameVisitor visitor(typeName, true, 149 * ossimVisitor::VISIT_CHILDREN | ossimVisitor::VISIT_INPUTS); 150 * connectableObject->accept(visitor); 151 * ossimRefPtr<ossimConnectableObject> object = visitor.getObject(); 152 * </pre> 153 */ 154 OSSIM_DEPRECATE_METHOD(virtual ossimConnectableObject* findInputObjectOfType( 155 const ossimString& className)); 156 157 /** 158 * Return a valid index of the input list if the passed in object 159 * is found else return -1. 160 */ 161 virtual ossim_int32 findInputIndex(const ossimConnectableObject* object); 162 163 /** 164 * Return a valid index of the input list if the passed id 165 * is found else return -1. 166 */ 167 virtual ossim_int32 findInputIndex(const ossimId& id); 168 169 /** 170 * Return a valid index of the output list if the passed in object 171 * is found else return -1. 172 */ 173 virtual ossim_int32 findOutputIndex(const ossimConnectableObject* object); 174 175 /** 176 * Return a valid index of the output list if the passed in object 177 * is found else return -1. 178 */ 179 virtual ossim_int32 findOutputIndex(const ossimId& id); 180 181 /** 182 * Should return the first available index to connect to. The 183 * connectMyInputTo that just takes another ossimConnectableObject as input 184 * and not an index will call this method. By default this method will find 185 * the first open slot (not null) or append o the list if it's dynamic. If 186 * the list is dynamic it calls conConnectMyInputTo(index, object) on an 187 * index = to listSize. 188 */ 189 virtual ossim_int32 getMyInputIndexToConnectTo( 190 ossimConnectableObject* object)const; 191 192 193 /** 194 * Should return the first available index to connect to. The 195 * connectMyOutputTo that just takes another ossimConnectableObject as input\ 196 * and not an index will call this method. By default this method will find 197 * the first open slot (not null) or append to the list if it's dynamic. If 198 * the list is dynamic it calls canConnectMyOutputTo(index, object) on an 199 * index = to listSize. 200 */ 201 virtual ossim_int32 getMyOutputIndexToConnectTo( 202 ossimConnectableObject* object)const; 203 204 /** 205 * required to be overriden by derived classes 206 */ 207 virtual bool canConnectMyInputTo( 208 ossim_int32 myInputIndex, const ossimConnectableObject* object)const=0; 209 210 /** 211 * default implementation is to allow anyone to connect to us. 212 */ 213 virtual bool canConnectMyOutputTo(ossim_int32 myOutputIndex, 214 const ossimConnectableObject* object)const; 215 216 /** 217 * Will disconnect the object passed in. 218 */ 219 virtual void disconnect(ossimConnectableObject* object=0); 220 221 /** 222 * Will disconnect the object passed in. 223 */ 224 virtual void disconnect(const ossimId& id); 225 226 /** 227 * Will disconnect the object at the given input index and generate 228 * a connection event. 229 */ 230 virtual ossimRefPtr<ossimConnectableObject> disconnectMyInput( 231 ossim_int32 inputIndex, 232 bool disconnectOutputFlag=true, 233 bool createEventFlag = true); 234 235 /** 236 * Finds the index of the passed in input and calls 237 * disconnectMyInput(inputIndex, disconnectOutputFlag, createEventFlag); 238 */ 239 virtual void disconnectMyInput(ossimConnectableObject* input, 240 bool disconnectOutputFlag=true, 241 bool createEventFlag = true); 242 /** 243 * 244 */ 245 virtual void disconnectMyInputs( 246 ConnectableObjectList& inputList, 247 bool disconnectOutputFlag=true, 248 bool createEventFlag=true); 249 250 /** 251 * Will disconnect the object at the given output index and generate 252 * a connection event. If there is no object at that index then no 253 * event is generated and NULL is returned. The disconnectOutputFlag 254 * says do you want this method to disconnect the output pointer to 255 * this object. 256 */ 257 virtual ossimRefPtr<ossimConnectableObject> disconnectMyOutput( 258 ossim_int32 outputIndex, 259 bool disconnectInputFlag=true, 260 bool createEventFlag = true); 261 262 /** 263 * Will disconnect the output object. It will get the index of 264 * the object and call disconnectMyOutput(index, disconnectOutputFlag). 265 */ 266 virtual void disconnectMyOutput(ossimConnectableObject* output, 267 bool disconnectInputFlag=true, 268 bool createEventFlag=true); 269 270 virtual void disconnectMyOutputs( 271 ConnectableObjectList& outputList, 272 bool disconnectOutputFlag=true, 273 bool createEventFlag=true); 274 275 /** 276 * Will disconnect all of the input objects. 277 */ 278 virtual void disconnectAllInputs(); 279 280 /** 281 * Will disconnect all of the output objects. 282 */ 283 virtual void disconnectAllOutputs(); 284 285 /** 286 * Will try to connect this objects input to the passed in object. 287 * It will return a valid index >= 0 if successful. Will use the 288 * getMyInputIndexToConnectTo method to implement the connection 289 */ 290 virtual ossim_int32 connectMyInputTo(ossimConnectableObject* inputObject, 291 bool makeOutputConnection=true, 292 bool createEventFlag=true); 293 294 /** 295 * Will connect the specified input to the passed in object 296 */ 297 virtual ossim_int32 connectMyInputTo(ossim_int32 inputIndex, 298 ossimConnectableObject* inputObject, 299 bool makeOutputConnection=true, 300 bool createEventFlag=true); 301 302 virtual bool connectMyInputTo( 303 ConnectableObjectList& inputList, 304 bool makeOutputConnection=true, 305 bool createEventFlag = true); 306 307 /** 308 * Will try to connect this objects output to the passed in object. 309 * It will return a valid index >= 0 if successful. It will in turn call 310 * the passed in objects connect input command if makeInputConnection 311 * is set to true. 312 * 313 * Will use the getMyOutputIndexToConnectTo to implement this method 314 */ 315 virtual ossim_int32 connectMyOutputTo(ossimConnectableObject* outputObject, 316 bool makeInputConnection=true, 317 bool createEventFlag=true); 318 319 virtual bool connectMyOutputTo( 320 ConnectableObjectList& outputList, 321 bool makeInputConnection=true, 322 bool createEventFlag=true); 323 324 /** 325 * Will disconnect itself from all inputs and reset to the passed in 326 * input list. It will return true if all objects were successfully 327 * added. 328 */ 329 virtual bool connectInputList( 330 ConnectableObjectList& inputList); 331 332 /** 333 * Will disconnect itself from all outputs and reset to the passed in 334 * output list. It will return true if all objects were successfully 335 * added. 336 */ 337 virtual bool connectOutputList( 338 ConnectableObjectList& outputList); 339 340 /** 341 * Returns the number of input objects. 342 */ 343 virtual ossim_uint32 getNumberOfInputs()const; 344 345 /** 346 * Return the number of output objects 347 */ 348 virtual ossim_uint32 getNumberOfOutputs()const; 349 350 /** 351 * returns the object at the specified index. 352 * if the index is not valid then NULL is 353 * returned 354 */ 355 ossimConnectableObject* getInput(ossim_uint32 index=0); 356 357 /** 358 * returns the object at the specified index. 359 * if the index is not valid then NULL is 360 * returned 361 */ 362 const ossimConnectableObject* getInput(ossim_uint32 index=0)const; 363 364 /** 365 * returns the object at the specified index. 366 * if the index is not valid then NULL is 367 * returned 368 */ 369 ossimConnectableObject* getOutput(ossim_uint32 index=0); 370 371 /** 372 * returns the object at the specified index. 373 * if the index is not valid then NULL is 374 * returned 375 */ 376 const ossimConnectableObject* getOutput(ossim_uint32 index=0)const; 377 378 /** 379 * Will set the number of inputs. This will expand the list if the number 380 * of inputs is larger than the current number of inputs. Will shrink 381 * the list if the current number of inputs is larger than the passed in 382 * inputs. 383 */ 384 virtual void setNumberOfInputs(ossim_int32 numberOfInputs); 385 386 virtual bool getInputListIsFixedFlag()const; 387 388 virtual bool getOutputListIsFixedFlag()const; 389 390 /** 391 * Will set the number of outputs. This will expand the list if the 392 * number of outputs is larger than the current number of outputs. 393 * Will shrink the list if the current number of outputs is larger than 394 * the passed in outputs. 395 */ 396 virtual void setNumberOfOutputs(ossim_int32 numberOfInputs); 397 398 const ConnectableObjectList& getInputList()const; 399 400 const ConnectableObjectList& getOutputList()const; 401 402 ConnectableObjectList& getInputList(); 403 404 ConnectableObjectList& getOutputList(); 405 406 /*! 407 * These methods are now deprecated. You can achieve the same thing by 408 * using the new visitor design pattern. If this does not achieve exactly 409 * what you want then you can derive new rules by overriding the virtual 410 * visit method in ossimVisitor 411 * 412 * <pre> 413 * ossimTypeNameVisitor visitor("<put type name here>", 414 * false, ossimVisitor::VISIT_CHILDREN); 415 * connectableObject->accept(visitor); 416 * ossimCollectionVisitor::List& collection = visitor.getObjects(); 417 * </pre> 418 */ 419 OSSIM_DEPRECATE_METHOD(virtual void findAllObjectsOfType( 420 ConnectableObjectList& result, 421 const RTTItypeid& typeInfo, bool recurse=true) ); 422 423 /*! 424 * These methods are now deprecated. You can achieve the same thing by 425 * using the new visitor design pattern. If this does not achieve exactly 426 * what you want then you can derive new rules by overriding the virtual 427 * visit method in ossimVisitor 428 * 429 * <pre> 430 * ossimTypeNameVisitor visitor("<put type name here>", false, 431 * ossimVisitor::VISIT_CHILDREN); 432 * connectableObject->accept(visitor); 433 * ossimCollectionVisitor::List& collection = visitor.getObjects(); 434 * </pre> 435 */ 436 OSSIM_DEPRECATE_METHOD(virtual void findAllObjectsOfType( 437 ConnectableObjectList& result, 438 const ossimString& className, 439 bool recurse=true)); 440 441 #if 0 /* Deprecated code. Left here until thoroughly debugged. (drb) */ 442 /*! 443 * These methods are now deprecated. You can achieve the same thing by 444 * using the new visitor design pattern. If this does not 445 * achieve exactly what you want then you can derive new rules by overriding 446 * the virtual visit method in ossimVisitor 447 * 448 * <pre> 449 * ossimTypeIdVisitor visitor(<put type id here>, false, 450 * ossimVisitor::VISIT_CHILDREN | ossimVisitor::VISIT_INPUTS); 451 * connectableObject->accept(visitor); 452 * ossimCollectionVisitor::List& collection = visitor.getObjects(); 453 * </pre> 454 */ 455 OSSIM_DEPRECATE_METHOD(virtual void findAllInputsOfType( 456 ConnectableObjectList& result, 457 const RTTItypeid& typeInfo, 458 bool propagateToInputs=true, 459 bool recurseChildren=false)); 460 461 /*! 462 * These methods are now deprecated. You can achieve the same thing by 463 * using the new visitor design pattern. If this does not 464 * achieve exactly what you want then you can derive new rules by overriding 465 * the virtual visit method in ossimVisitor 466 * 467 * <pre> 468 * ossimTypeNameVisitor visitor("<put type name here>", 469 * false, ossimVisitor::VISIT_CHILDREN | ossimVisitor::VISIT_INPUTS); 470 * connectableObject->accept(visitor); 471 * ossimCollectionVisitor::List& collection = visitor.getObjects(); 472 * </pre> 473 */ 474 475 OSSIM_DEPRECATE_METHOD(virtual void findAllInputsOfType( 476 ConnectableObjectList& result, 477 const ossimString& className, 478 bool propagateToInputs=true, 479 bool recurseChildren=false)); 480 #endif /* deprecated code. (drb) */ 481 482 virtual void propagateEventToOutputs(ossimEvent& event); 483 virtual void propagateEventToInputs(ossimEvent& event); 484 485 /* ------------------- PROPERTY INTERFACE -------------------- */ 486 virtual void setProperty(ossimRefPtr<ossimProperty> property); 487 virtual void setProperty(const ossimString& name, const ossimString& value); 488 virtual ossimRefPtr<ossimProperty> getProperty(const ossimString& name)const; 489 virtual void getPropertyNames(std::vector<ossimString>& propertyNames)const; 490 /* ------------------ PROPERTY INTERFACE END ------------------- */ 491 492 493 virtual bool loadState(const ossimKeywordlist& kwl, 494 const char* prefix = 0); 495 496 virtual bool saveState(ossimKeywordlist& kwl, 497 const char* prefix = 0)const; 498 499 /** 500 * Save the state of all inputs to a keyword list. This will do a 501 * recursive call through all inputs and save their state to a 502 * keyword list. 503 * 504 * @param kwl Keyword list to save state to. 505 * 506 * @param saveThisStateFlag If the true the state of this object will be 507 * saved as well as all inputs. Default = true. 508 * 509 * @param objectIndex Index to be used for prefix. So if 510 * objectIndex = 1, the first object will have a prefix of: "object1." 511 * Default = 1. 512 * 513 * @param prefix Prefix to tack onto keyword. If prefix = "myChain." and 514 * objectIndex = 1, then the first keyword would be 515 * "myChain.object1.some_keyword". 516 * 517 * @return Returns the next object index. This is the last index used 518 * plus one. Used internally to keep track of index to use for prefix. 519 */ 520 virtual ossim_uint32 saveStateOfAllInputs(ossimKeywordlist& kwl, 521 bool saveThisStateFlag=true, 522 ossim_uint32 objectIndex=1, 523 const char* prefix=0) const; 524 525 /** 526 * Inserts this object and all of its children and inputs into the container 527 * provided. 528 * @return Returns TRUE if successful. 529 */ 530 virtual bool fillContainer(ossimConnectableContainer& container); 531 532 /** 533 * Moves the input connection matching id up one in the connection list. 534 * @param id The id to move. 535 * @return true if action was performed, false if not. 536 */ 537 bool moveInputUp(const ossimId& id); 538 539 /** 540 * Moves the input connection matching id down one in the connection list. 541 * @param id The id to move. 542 * @return true if action was performed, false if not. 543 */ 544 bool moveInputDown(const ossimId& id); 545 546 /** 547 * Moves the input connection matching id to the top of the connection list. 548 * @param id The id to move. 549 * @return true if action was performed, false if not. 550 */ 551 bool moveInputToTop(const ossimId& id); 552 553 /** 554 * Moves the input connection matching id to the bottom of the connection 555 * list. 556 * @param id The id to move. 557 * @return true if action was performed, false if not. 558 */ 559 bool moveInputToBottom(const ossimId& id); 560 561 /** 562 * We will add a visitor interface for all connectable objects. 563 */ 564 virtual void accept(ossimVisitor& visitor); 565 566 protected: 567 568 ossimConnectableObject* findObjectOfType( 569 ConnectableObjectList* connectableList, 570 ossimVisitor& visitor ); 571 572 ossimId theId; 573 ossimString theDescription; 574 ossimObject* theOwner; 575 576 /** 577 * Indicates whether the theInputObjectList is fixed 578 */ 579 bool theInputListIsFixedFlag; 580 581 /** 582 * Indicates whether the theOutputObjectList is fixed 583 */ 584 bool theOutputListIsFixedFlag; 585 586 /** 587 * Holds a list of input objects. 588 */ 589 ConnectableObjectList theInputObjectList; 590 591 /** 592 * Holds a list of output objects. 593 */ 594 ConnectableObjectList theOutputObjectList; 595 596 private: 597 TYPE_DATA 598 }; 599 600 #endif /* #ifndef ossimConnectableObject_HEADER */ 601