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
00043
00044 F.accept<T>();
00045
00046
00047
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
00330
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
00388
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;
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
00470
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
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
00502
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 }
00567
00568 #endif
00569