FishField.hpp

00001 #ifndef __FISH_BONE_FIELD_HPP
00002 #define __FISH_BONE_FIELD_HPP
00003 
00004 #include "FishGrid.hpp"
00005 
00006 #include <ocean/shrimp/VStringList.hpp>
00007 #include <ocean/plankton/VCreator.hpp>
00008 #include <ocean/plankton/VObject.hpp>
00009 #include <bundle/FieldSelector.hpp>
00010 
00011 #include <meta/LIST.hpp>
00012 #include <meta/NativeTypeList.hpp>
00013 
00014 namespace Wizt
00015 {
00016         using Fiber::FieldSelector;
00017 
00022 template <>
00023 class   fishbone_API VOutput<Fiber::Field> : public VOutput<FieldSelector>
00024 {
00025 public:
00029         VOutput(const WeakPtr<VObject>&Source,
00030                 const string&initial_name,
00031                 const RefPtr<VCreationPreferences>&CP = NullPtr() );
00032 
00036         template <class T>
00037         bool provides(const RefPtr<ValuePool>&Context = NullPtr() )
00038         {
00039         FieldSelector F;
00040                 (*this) << Context >> F; 
00041 
00042 //              AcceptType<T> xxx(F.FieldTypes());
00043 
00044                 F.accept<T>();
00045 
00046 //              F.setType( Fiber::FiberType< T >::getFiberType() ); 
00047 //              F.AcceptableFieldTypes.insert( Fiber::FiberType< T >::getFiberType().self() ); 
00048 
00049                 (*this) << Context << F;
00050                 return true;
00051         }
00052 };
00053 
00054 
00055 
00059 template <>
00060 class fishbone_API VValueTrait<FieldSelector>
00061 {
00062 public:
00063 
00064 static  bool setValueFromText(FieldSelector&i, const string&s); 
00065 
00066 static  string Text(const FieldSelector&F);
00067 
00068 };
00069 
00070 
00076 template <>
00077 struct  fishbone_API TypedSlot<Fiber::Field> : TypedSlot<FieldSelector>
00078 {
00085         TypedSlot<Fiber::Field>(VObject*that, const string&slotname, int prior=0); 
00086 
00092         TypedSlot<VTime>        getTimeSlot() const;
00093 
00095         template <class T>
00096         bool acceptType()
00097         {
00098                 if (!*this) return false;
00099 
00101         RefPtr<VValue<FieldSelector> > VVF = ***this;
00102                 if (!VVF) return false; 
00103 
00104         FieldSelector&VF = *VVF;
00105 
00106                 VF.accept<T>();
00107 
00108                 return true;
00109         } 
00110 
00111 
00112         string  getFieldname(const RefPtr<ValuePool>&VP) const
00113         {
00114         FieldSelector FP; 
00115                 (*this) << VP >> FP; 
00116                 return FP();
00117         }
00118 };
00119 
00134 template <>
00135 class   fishbone_API Fish<Fiber::Field> : public virtual Fish<double>
00136 {
00137 protected:
00138         TypedSlot<Fiber::Field>  MyField;
00139 
00140 public:
00141         enum
00142         {
00146                 NumberOfInputFields = 1 
00147         };
00148 
00150         Fish<Fiber::Field>(const string&field, int ExpertLevel=0); 
00151 
00153         template <class T>
00154         bool acceptType()
00155         {
00156                 if (!MyField) return false;
00157 
00159         RefPtr<VValue<FieldSelector> > VVF = **MyField; 
00160                 if (!VVF) return false; 
00161 
00162         FieldSelector&VF = *VVF; 
00163 
00164                 VF.accept<T>();
00165 
00166                 return true;
00167         } 
00168 
00170         void setFieldExpertLevel(int EL)
00171         {
00172                 myself->setExpertLevel( MyField, EL);
00173         }
00174 
00176         ~Fish(); 
00177 
00178 
00180         void registerFieldAsOutput()
00181         {
00182                 assert(myself);
00183                 myself->registerOutput( MyField );
00184         }
00185 
00189         string  Fieldname(const RefPtr<ValuePool>&VP) const;
00190 
00194         string  getFieldname(const RefPtr<ValuePool>&VP) const
00195         {
00196                 return Fieldname(VP);
00197         }
00198 
00200         RefPtr<Fiber::Field>  getField(const RefPtr<ValuePool>&VP) const;
00201 
00202         FieldSelector  getFieldSelector(const RefPtr<ValuePool>&VP) const; 
00203 
00205         override double getTime(const RefPtr<ValuePool>&VP, const RefPtr<Fiber::Bundle>&SpaceTime) const; 
00206 
00224         TypedSlot<VTime> getTimeSlot() const
00225         {
00226                 return MyField.getTimeSlot();
00227         }
00228 
00238         RefPtr<Fiber::Field>  getField(const RefPtr<Fiber::Representation>&LevelRep,
00239                                        const RefPtr<ValuePool>&VP) const; 
00240 
00241 
00242         override Fiber::Info<Fiber::Skeleton>
00243                         getRefinementLevel(int Level,
00244                                            const RefPtr<ValuePool>&VP,
00245                                            int IndexDepth = 0,
00246                                            const Fiber::BundlePtr&SpaceTime = Fiber::BundlePtr(NullPtr() ) ); 
00247 
00248 
00249         Fiber::Bundle::GridInfo_t
00250                 findMostRecentGrid(FieldSelector&GS, const RefPtr<ValuePool>&VP, const Fiber::BundlePtr&SpaceTime = Fiber::BundlePtr(NullPtr() )) const;
00251 
00260         Fiber::Bundle::GridInfo_t
00261                 findMostRecentGrid(const RefPtr<ValuePool>&VP, const Fiber::BundlePtr&SpaceTime = Fiber::BundlePtr( NullPtr() ) ) const
00262         {
00263         FieldSelector   GS;
00264                 return findMostRecentGrid(GS, VP, SpaceTime);
00265         } 
00266 
00267         using Fish<double>::IterateLevels;
00268 
00288         bool    IterateLevels(LevelIterator&LI, const RefPtr<ValuePool>&Context,
00289                               const Fiber::BundlePtr&SpaceTime = Fiber::BundlePtr( NullPtr() ) );
00290 
00291 
00292 };
00293 
00294 using META::LIST;
00295 
00318 template <class FieldVObject, class TypeList = LIST<META::NIL>, 
00319           int NumberOfInputFields = FieldVObject::NumberOfInputFields>
00320 struct  FieldInputCreator : VCreator<FieldVObject, AcceptList<Fiber::Field> >  
00321 {
00326         FieldInputCreator(const string&name, int quality)
00327         : VCreator<FieldVObject, AcceptList<Fiber::Field> > (name, quality)
00328         {
00329 //              if (this->Arguments().length()<1)
00330 //                      this->Arguments() = TypeString();
00331         }
00332 
00339         FieldInputCreator(const VCreatorProperties&CreatorProperties, int quality)
00340         : VCreator<FieldVObject, AcceptList<Fiber::Field> > (CreatorProperties, quality)
00341         {
00342                 if (this->Arguments().length()<1)
00343                         this->Arguments() = TypeString();
00344         }
00345 
00362         template <unsigned ID>
00363         FieldInputCreator(const VCreatorProperty<ID>&CreatorProperties, int quality)
00364         : VCreator<FieldVObject, AcceptList<Fiber::Field> > (CreatorProperties, quality)
00365         {
00366                 if (this->Arguments().length()<1)
00367                         this->Arguments() = TypeString();
00368         }
00369 
00370 
00374         struct  TypeInspector
00375         {
00376                 const FieldSelector&FS;
00377                 bool    Yess;
00378 
00379                 TypeInspector(const FieldSelector&fs)
00380                 : FS(fs)
00381                 , Yess(false)
00382                 {}
00383 
00384                 template <typename T>
00385                 struct exec
00386                 {
00387                         // return true if the traversal of the list 
00388                         // should be stopped
00389                 static inline bool Break(TypeInspector&TI)
00390                         {
00391 #ifdef  VERBOSE
00392                                 printf("    TypeInspector<%s>: ", typeid(T).name() ); 
00393                                 TI.FS.FieldTypes().speak(); puts("");
00394 #endif
00395                                 if (TI.FS.requires( typeid(T) ) )
00396                                 {
00397 #ifdef  VERBOSE
00398                                         printf("  ...... FIELD requires %s (%d fields available)\n", typeid(T).name(), TI.FS.NumberOfAvailableFields() );
00399 #endif
00400                                         TI.Yess = true;
00401                                         return true;
00402                                 }
00403 #ifdef  VERBOSE
00404                                 printf("Field requirement %s is NOT available\n", typeid(T).name() );
00405 #endif
00406                                 return false; // continue traversal
00407                         }
00408                 };
00409         };
00410 
00416         override RefPtr<VAcceptInfo> accept(const RefPtr<VObject>&vobj) const
00417         {
00418 #ifdef  VERBOSE
00419                 printf("override RefPtr<VAcceptInfo> %s::accept(const RefPtr<VObject>&%s) const\n", 
00420                        this->Name().c_str(), vobj->Name().c_str()
00421                         );
00422 #endif
00423                 if (!vobj)
00424                 {
00425 #ifdef  VERBOSE
00426                         puts("FieldInputCreator(): NO INPUT FOUND!\n");
00427 #endif
00428                         return NullPtr();
00429                 }
00430 
00431         RefPtr<VParameter> FieldParam = vobj->getImplementation( typeid(Fiber::FieldSelector) );
00432                 if (!FieldParam)
00433                 {
00434 #ifdef  VERBOSE
00435                         printf("FieldInputCreator(): NO INPUT FIELD FOUND at %s\n",vobj->Name().c_str() );
00436 #endif
00437                         return NullPtr();
00438                 }
00439 #ifdef  VERBOSE
00440                 printf("             [%s]  GET FIELDSELECTOR\n", this->Name().c_str() );
00441 #endif
00442         FieldSelector FS;
00443                 if (!FieldParam->getValue( FS, NullPtr(), "" ) )
00444                 {
00445 #ifdef  VERBOSE
00446                         printf("FieldInputCreator(): COULD NOT RETRIEVE FIELD TYPE at %s\n",vobj->Name().c_str() );
00447 #endif
00448                         return NullPtr();
00449                 }
00450                 if (FS.NumberOfAvailableFields()>0
00451                     &&
00452                     FS.NumberOfAvailableFields()<NumberOfInputFields)
00453                 {
00454 #ifdef  VERBOSE
00455                         printf("FieldInputCreator(): Input object provides a number of available fields, "
00456                                "but FS.NumberOfAvailableFields() (%d) < NumberOfInputFields (%d)\n",
00457                                FS.NumberOfAvailableFields(), NumberOfInputFields);
00458 #endif
00459                         return NullPtr();
00460                 }
00461 
00462 #ifdef  VERBOSE
00463                 printf("FieldInputCreator(): INSPECT FIELD AS EXPORTED BY %s (%u types)\n",vobj->Name().c_str(), FS.FieldTypes().size() ); 
00464                 FS.FieldTypes().speak();puts("");
00465 #endif
00466         TypeInspector TI(FS);
00467                 META::FOREACH<TypeInspector, TypeList>::exec(TI);
00468 
00469                 //      if (!GridObject::HasGrids(vobj) )
00470                 //      return NullPtr();
00471         RefPtr<VAcceptInfo>
00472                 VAI = VCreator<FieldVObject, AcceptList<Fiber::Field> >::accept(vobj); 
00473 
00474                 if (!VAI)
00475                         return NullPtr();
00476 
00477                 if (!TI.Yess)
00478                 {
00479 #ifdef  VERBOSE
00480                         puts("NOPE, don't want this field type");
00481 #endif
00482                         return NullPtr();
00483                 }
00484 #ifdef  VERBOSE
00485                 puts("YESSS, accepted this field type");
00486 #endif
00487 //              printf(" ACCEPTED AS: %s\n", Typename( VAI->what ).c_str() );
00488                 return VAI;
00489         }
00490 
00491         
00492 
00493 
00494         struct  MakeString
00495         {
00496                 string  theTypeString;
00497 
00498                 template <typename T>
00499                 struct exec
00500                 {
00501                         // return true if the traversal of the list 
00502                         // should be stopped
00503                 static  inline bool Break(MakeString&MS)
00504                         {
00505                                 if (MS.theTypeString.length()<1)
00506                                         MS.theTypeString += "|"; 
00507 
00508                                 MS.theTypeString += Typename( typeid(T) ); 
00509                                 return false;
00510                         }
00511                 };
00512         }; 
00513 
00514 static  string  TypeString()
00515         {
00516         MakeString MS;
00517                 META::FOREACH<MakeString, TypeList>::exec(MS); 
00518                 return MS.theTypeString;
00519         }
00520 
00521 
00522 };
00523 
00524 
00537 template <class FieldVObject>
00538 struct  TypedFieldInputCreator : FieldInputCreator<FieldVObject, typename FieldVObject::InputTypes>
00539 {
00543         TypedFieldInputCreator(const string&name, int quality)
00544         : FieldInputCreator<FieldVObject, typename FieldVObject::InputTypes>(name, quality)
00545         {}
00546 
00550         TypedFieldInputCreator(const VCreatorProperties&CreatorProperties, int quality)
00551         : FieldInputCreator<FieldVObject, typename FieldVObject::InputTypes>(CreatorProperties, quality)
00552         {}
00553 
00560         template <unsigned ID>
00561         TypedFieldInputCreator(const VCreatorProperty<ID>&CreatorProperties, int quality)
00562         : FieldInputCreator<FieldVObject, typename FieldVObject::InputTypes>(CreatorProperties, quality)
00563         {}
00564 };
00565 
00566 } // namespace Wizt
00567 
00568 #endif /* __FISH_BONE_FIELD_HPP */
00569