00001 #ifndef _TypedOutControl_ 00002 #define _TypedOutControl_ 00003 00004 #include <string> 00005 #include <list> 00006 #include <typeinfo> 00007 #include <CLAM/Assert.hxx> 00008 #include <CLAM/BaseTypedOutControl.hxx> 00009 #include <CLAM/TypedInControl.hxx> 00010 00011 namespace CLAM { 00012 class Processing; 00013 00018 template<class TypedControlData> 00019 class TypedOutControl : public BaseTypedOutControl 00020 { 00021 // This is required to solve the parsing problem with iterators. 00022 typedef TypedInControl<TypedControlData> ProperTypedInControl; 00023 typedef std::list< ProperTypedInControl * > ProperTypedInControlList; 00024 00025 protected: 00026 // mLinks will store the pointers to the connected TypedInPorts 00027 std::list< BaseTypedInControl * > mLinks; 00028 00029 public: 00030 TypedOutControl(const std::string &name = "unnamed typed in control", Processing * proc = 0); 00031 ~TypedOutControl(); 00032 00033 void AddLink(TypedInControl<TypedControlData>& in); 00037 void AddLink(BaseTypedInControl& in); 00038 void RemoveLink(TypedInControl<TypedControlData>& in); 00039 void RemoveLink(BaseTypedInControl& in); 00040 void SendControl(const TypedControlData& val); 00041 bool IsConnected(); 00042 bool IsConnectedTo(TypedInControl<TypedControlData> & ); 00043 bool IsConnectedTo(BaseTypedInControl& in); 00044 bool IsLinkable(const BaseTypedInControl& in); 00045 std::list<BaseTypedInControl*>::iterator BeginInControlsConnected(); 00046 std::list<BaseTypedInControl*>::iterator EndInControlsConnected(); 00047 00048 //bool DoTypedLink(BaseTypedInControl& in); 00049 00050 }; 00051 00052 template<class TypedControlData> 00053 TypedOutControl<TypedControlData>::TypedOutControl(const std::string &name, Processing * proc) 00054 : BaseTypedOutControl(name,proc) 00055 { 00056 } 00057 00058 template<class TypedControlData> 00059 TypedOutControl<TypedControlData>::~TypedOutControl() 00060 { 00061 while (!mLinks.empty()) 00062 RemoveLink(*mLinks.front()); 00063 } 00064 00065 00066 template<class TypedControlData> 00067 void TypedOutControl<TypedControlData>::AddLink(TypedInControl<TypedControlData>& in) 00068 { 00069 mLinks.push_back(&in); 00070 in.OutControlInterface_AddLink(*this); 00071 } 00072 00076 template<class TypedControlData> 00077 void TypedOutControl<TypedControlData>::AddLink(BaseTypedInControl& in) 00078 { 00079 try 00080 { 00081 AddLink(dynamic_cast< ProperTypedInControl& >(in)); 00082 } 00083 catch(...) 00084 { 00085 CLAM_ASSERT( false, "TypedOutControl<TypedControlData>::AddLink(BaseTypedInControl&) could not cast BaseTypedInControl to TypedInControl<TypedControlData>" ); 00086 } 00087 } 00088 00089 template<class TypedControlData> 00090 void TypedOutControl<TypedControlData>::RemoveLink(TypedInControl<TypedControlData>& in) 00091 { 00092 mLinks.remove( &in ); 00093 in.OutControlInterface_RemoveLink(*this); 00094 } 00095 template<class TypedControlData> 00096 void TypedOutControl<TypedControlData>::RemoveLink(BaseTypedInControl& in) 00097 { 00098 try 00099 { 00100 RemoveLink(dynamic_cast< ProperTypedInControl& >(in)); 00101 } 00102 catch(...) 00103 { 00104 CLAM_ASSERT( false, "TypedOutControl<TypedControlData>::RemoveLink(BaseTypedInControl&) could not cast BaseTypedInControl to TypedInControl<TypedControlData>" ); 00105 } 00106 } 00107 template<class TypedControlData> 00108 void TypedOutControl<TypedControlData>::SendControl(const TypedControlData& val) 00109 { 00110 typename std::list< BaseTypedInControl * >::iterator it; 00111 00112 for (it=mLinks.begin(); it!=mLinks.end(); it++) 00113 { 00114 ((dynamic_cast<TypedInControl<TypedControlData>*>(*it)))->DoControl(val); 00115 } 00116 } 00117 00118 template<class TypedControlData> 00119 bool TypedOutControl<TypedControlData>::IsConnected() 00120 { 00121 return ! mLinks.empty(); 00122 } 00123 00124 template<class TypedControlData> 00125 bool TypedOutControl<TypedControlData>::IsConnectedTo( TypedInControl<TypedControlData> & in) 00126 { 00127 typename std::list< BaseTypedInControl * >::iterator it; 00128 for (it=mLinks.begin(); it!=mLinks.end(); it++) 00129 if ((*it) == &in) 00130 return true; 00131 00132 return false; 00133 } 00134 00135 template<class TypedControlData> 00136 bool TypedOutControl<TypedControlData>::IsLinkable(const BaseTypedInControl& in) 00137 { 00138 return typeid(TypedControlData) == in.ControlType(); 00139 00140 } 00141 00142 template<class TypedControlData> 00143 bool TypedOutControl<TypedControlData>::IsConnectedTo(BaseTypedInControl& in) 00144 { 00145 bool result = false; 00146 try 00147 { 00148 result = IsConnectedTo(dynamic_cast< ProperTypedInControl& >(in)); 00149 } 00150 catch(...) 00151 { 00152 CLAM_ASSERT( false, "TypedOutControl<TypedControlData>::IsConnectedTo(BaseTypedInControl& in) could not cast BaseTypedInControl to TypedInControl<TypedControlData>" ); 00153 } 00154 00155 return result; 00156 00157 } 00158 00159 template<class TypedControlData> 00160 std::list<BaseTypedInControl*>::iterator TypedOutControl<TypedControlData>::BeginInControlsConnected() 00161 { 00162 return mLinks.begin(); 00163 } 00164 00165 template<class TypedControlData> 00166 std::list<BaseTypedInControl*>::iterator TypedOutControl<TypedControlData>::EndInControlsConnected() 00167 { 00168 return mLinks.end(); 00169 } 00170 00171 00172 } // END NAMESPACE CLAM 00173 #endif // _TypedOutControl_