FiberVISH 0.2
Fish - The Fiber Bundle API for the Vish Visualization Shell
FieldFunctor.hpp
1#ifndef __FISH_BONE_FIELDFUNCTOR_HPP
2#define __FISH_BONE_FIELDFUNCTOR_HPP
3
4#include <bone/FieldOperatorObject.hpp>
5#include <bone/FieldInputCreator.hpp>
6#include <field/FunctionalCreator.hpp>
7
8namespace Wizt
9{
10using namespace Fiber;
11using namespace Eagle;
12
92template <class Operation, class GridInspectorType = typename Operation::GridInspector>
94{
95protected:
96
99
100public:
101 using input_type = typename Operation::input_type;
102 using output_type = typename Operation::output_type;
103
106
109
112
116 FieldFunctor(const string&name, const string&fieldname, int p, const RefPtr<VCreationPreferences>&VP)
117 : FieldOperatorObject(name, fieldname, p, VP)
119 , Result( self(), "result" )
120 {
122 }
123
124 FieldFunctor(const string&name, int p, const RefPtr<VCreationPreferences>&VP)
125 : FieldOperatorObject(name, "inputfield", p, VP)
127 , Result( self(), "result" )
128 {
130 }
131
136 struct Op : Field::Iterator, Operation
137 {
138 RefPtr<Field> ResultField;
139 bool Modified = false;
140 bool doCreateArrayIfRequired = true;
141 const FieldFunctor&theFieldFunctor;
142 VRequest &theContext;
143
145 : Modified(false)
146 , theFieldFunctor(F)
147 , theContext(Context)
148 {}
149
151 bool apply(const RefPtr<FragmentID>&frag, const RefPtr<CreativeArrayBase>&CAB) override
152 {
153#ifdef VERBOSE_FIELDFUNCTOR
154 if (frag)
155 Verbose(VERBOSE_FIELDFUNCTOR) << "FieldFunctor::apply(FragmentID=" << frag->Name() << ")";
156 else
157 Verbose(VERBOSE_FIELDFUNCTOR) << "FieldFunctor::apply() - unfragmented.";
158#endif
159 if (ResultField)
160 {
161 if (RefPtr<CreativeArrayBase> ResultCreator = ResultField->getCreator( frag ) )
162 {
163 if (CAB->isNewerThan(*ResultCreator) )
164 {
165#ifdef VERBOSE_FIELDFUNCTOR
166 Verbose(VERBOSE_FIELDFUNCTOR) << "FieldFunctor: INPUT field is NEWER, recompute.";
167#endif
168 }
169 else
170 {
171#ifdef VERBOSE_FIELDFUNCTOR
172 Verbose(VERBOSE_FIELDFUNCTOR) << "FieldFunctor: INPUT field is OLDER, nothing done.";
173#endif
174 return true;
175 // may have other newer inputs
176 }
177 }
178 }
179
180#if 1
183 if (!ResultField)
184 {
185 if (frag)
186 ResultField = new Field(frag->getFragmentIDCollection() );
187 else
188 ResultField = new Field();
189 }
190
191 ResultField->setLambda( frag, [ theOperator = *this, wfrag, wCAB]() -> RefPtr<MemBase>
192 {
194 if (!CAB) return nullptr;
195 RefPtr<MemBase> Data = CAB->create();
196 if (!Data) return nullptr;
197
199 if (!T)
200 {
201 T = Data->makeMemArray( nullptr );
202 if (!T)
203 {
204 return nullptr;
205 }
206 }
207 const Iterator<input_type>&Src = *T;
208
209#ifdef VERBOSE_FIELDFUNCTOR
210 Verbose(VERBOSE_FIELDFUNCTOR) << "FieldFunctor: Computing new data...";
211#endif
214
215 const Iterator<output_type>&Dst = *Result ->creativeIterator() ;
216
217 index_t end = Src.count();
218 for(index_t i = 0; i<end; i++)
219 {
220 Dst[i] = theOperator.compute( Src[i] );
221 }
222
223#ifdef VERBOSE_FIELDFUNCTOR
224 Verbose(VERBOSE_FIELDFUNCTOR) << "FieldFunctor: Computed new data on ..." << Result->myChunk();
225#endif
226 if (wfrag)
227 Result ->CacheInfoString = "Computed field on fragment " + wfrag->Name();
228 else
229 Result ->CacheInfoString = "Computed field.";
230
231 return Result;
232 }
233 ); // end Lambda
234
235 ResultField->touch();
236 Modified = true;
237 return true;
238#else
239 //
240 // TODO: Move this into an OnDemandCreator
241 //
242 const RefPtr<MemBase>&Data = CAB->create();
243 if (!Data)
244 {
245 puts("FieldFunctor: DATA CREATION FAILED!"); fflush(stdout);
246 return false;
247 }
248
250 if (!T)
251 {
252 T = Data->makeMemArray( nullptr );
253 if (!T)
254 {
255
257 theFieldFunctor.MyField << theContext >> FieldSelection;
258 puts("FieldFunctor: OUCCCH - Some data here, but no fitting data!"); fflush(stdout);
259 VActionNotifier::Warning("FieldFunctor \"" + theFieldFunctor.Name() + "\" :\n\n"
260 "Need data of type '" + Typename(typeid(input_type)) +
261 "', but input data are of type '" +
262 Typename(Data->getType() ) +
263 //"' (elements of type '" + Typename(Data->getFiberType().getType() ) + "'"
264 ").\n\n"
265 "Maybe a wrong input field was connected here. "
266 "The currently connected input field is \""
267 + FieldSelection() + "\" - check whether this is correct."
268 );
269 return false;
270 }
271 }
272
273 const Iterator<input_type>&Src = *T;
274
275#ifdef VERBOSE_FIELDFUNCTOR
276 Verbose(VERBOSE_FIELDFUNCTOR) << "FieldFunctor: Computing new data...";
277#endif
278
281
282 const Iterator<output_type>&Dst = *Result ->creativeIterator() ;
283
284 index_t end = Src.count();
285 for(index_t i = 0; i<end; i++)
286 {
287 Dst[i] = this->compute( Src[i] );
288 }
289
290 Result ->CacheInfoString = "Computed field.";
291 if (!ResultField)
292 {
293 if (frag)
294 ResultField = new Field(frag->getFragmentIDCollection() );
295 else
296 ResultField = new Field();
297 }
298
299 ResultField->setDiscardableData( Result , Cache::MemCache(), frag);
300#pragma message "Review this code to use Lambda creators!"
301 ResultField->touch();
302 Modified = true;
303 return true;
304#endif
305 }
306 };
307
308
309static string createChildname(const string&parent_name)
310 {
311 return Operation::createChildname( parent_name );
312 }
313
320 virtual bool modifyOperator(VRequest&Context, Operation&Op) const
321 {
322 return true;
323 }
324
338 {
339 return true;
340 }
341
343 Fiber::Representation&Target // , Fiber::Representation&FieldIDSource
344 ) override
345 {
347
348#ifdef VERBOSE_FIELDFUNCTOR
349 Verbose(VERBOSE_FIELDFUNCTOR) << "FieldFunctor: FieldOperation...";
350#endif
351
352 Op MyOp(*this, Context);
353 MyOp.doCreateArrayIfRequired = doCreateArrayIfRequired;
354
356 {
357 return false;
358 }
359
360 string ResultFieldname = BaseName( createChildname( Fieldname(Context) ) );
361
362#ifdef VERBOSE_FIELDFUNCTOR
363 Verbose(VERBOSE_FIELDFUNCTOR) << "FieldFunctor: will create field [" + ResultFieldname + "]";
364#endif
365
368
370 MyOp.ResultField = Target( ResultID );
371
372// Source.iterate( MyOp );
373
374 Source.iterate( [&MyOp](const RefPtr<FragmentID>&frag, const RefPtr<CreativeArrayBase>&CAB)
375 {
376 return MyOp.apply(frag, CAB);
377 } );
378
379 if (!postOperation(Context, MyOp) )
380 {
381 return false;
382 }
383
384 if (MyOp.ResultField)
385 {
386 Assert( ResultID );
387
388 Target[ ResultID ] = MyOp.ResultField;
389
390 Assert( Target.getField( ResultID ) );
391
392 FieldSelector InputField;
393 MyField << Context >> InputField;
394
395#ifdef VERBOSE_FIELDFUNCTOR
396 Verbose(VERBOSE_FIELDFUNCTOR) << "FieldFunctor: created field [" + ResultFieldname + "] at T=" << InputField.getTime()
397 << ", target representation "<< Target.self() << " has " << Target.getNumberOfFields() << " fields";
398#endif
399
400// if (MyOp.Modified) puts("ResultField.modified"); else puts("NOT ResultField.modified");
401
402 FieldSelector OutField( InputField );
403 OutField.selectField( ResultFieldname );
404 OutField.accept<output_type>();
405
408
409 if (MyOp.Modified || OutField != PreviousOutField)
410 {
411#ifdef VERBOSE_FIELDFUNCTOR
412 Verbose(VERBOSE_FIELDFUNCTOR) << "FieldFunctor: field [" + ResultFieldname + "] is NEW";
413#endif
414// puts("SET NEW Field");
415 Result << Context << OutField;
416 return setStatusInfo(Context, "Created field ["+ResultFieldname+"]");
417 }
418 else
419 return setStatusInfo(Context, "Used old field ["+ResultFieldname+"]");
420// puts("OLD Field is fine");
421 }
422 else
423 return setStatusError(Context, "Invalid input type of input field");
424
425// return setStatusInfo(Context, "Created field ["+ResultFieldname+"]");
426// return true;
427 }
428};
429
430
431} // namespace
432
433#endif
constexpr auto end(_Container &__cont) -> decltype(__cont.end())
An iterator with an optional DataCreator, which is just a class to intercept creation of data along a...
Definition CreativeIterator.hpp:34
An abstract selection of fields, that is given by names of fields and possible types for each field.
Definition FieldSelection.hpp:23
An internal class that stores a couple of textual names.
Definition FieldSelector.hpp:18
double getTime() const
The time when this field was found most recently.
Definition FieldSelector.hpp:276
A Field is a collection of CreativeArrayBase reference pointers which are accessed via FragmentID obj...
Definition Field.hpp:245
Base class for iterators over the fragments of a field.
Definition FragmentID.hpp:249
index_t count() const
Return the number of steps which can be traversed through this ElementIterator.
Definition HyperslabParameters.hpp:147
A Representation is a set of Field objects, each of them accessed via some FieldID identifier.
Definition Representation.hpp:101
An intermediate class that allows to operate on the pure type information of some memory array.
Definition TypedArray.hpp:58
static RefPtr< Cache, CacheBase > & MemCache()
const std::string & Name() const
std::string BaseName(const char Separator) const
Perform operations on fields.
Definition FieldFunctor.hpp:94
virtual bool postOperation(VRequest &Context, Op &Result) const
An optional function to inspect the result of the operation, possibly modify or add something once it...
Definition FieldFunctor.hpp:337
VOutput< Fiber::Field > Result
The output: a Fiber::Field .
Definition FieldFunctor.hpp:111
FieldFunctor(const string &name, const string &fieldname, int p, const RefPtr< VCreationPreferences > &VP)
Constructor.
Definition FieldFunctor.hpp:116
bool FieldOperation(VRequest &Context, Fiber::Field &Source, Fiber::Representation &Target) override
The operation to be performed on the given field, to be overloaded in a subclass.
Definition FieldFunctor.hpp:342
bool doCreateArrayIfRequired
Flag. Is true by default.
Definition FieldFunctor.hpp:98
virtual bool modifyOperator(VRequest &Context, Operation &Op) const
An optional function to modify the current operator according the context, which may specify addition...
Definition FieldFunctor.hpp:320
Base class for objects that operate on Field objects and create new fields.
Definition FieldOperatorObject.hpp:44
MEMCORE_API std::string Typename(const std::type_info &t)
Given a fragmented field of curvilinear coordinates, (3D array of coordinates), build a uniform Grid ...
Definition FAQ.dox:2
note: cannot derive from FloatingSkeletonRenderer as long as independent base class TriangleRenderer ...
Operator instance: The template argument as Operation paired with an Iteration over a Field's fragmen...
Definition FieldFunctor.hpp:137
bool apply(const RefPtr< FragmentID > &frag, const RefPtr< CreativeArrayBase > &CAB) override
Iteration callback function for each fragment of a Field.
Definition FieldFunctor.hpp:151
string Fieldname(const RefPtr< ValuePool > &VP) const
Get the name of the selected field.
Definition FishField.cpp:250
bool setStatusInfo(const RefPtr< ValuePool > &Context, const string &what) const
bool setStatusError(const RefPtr< ValuePool > &Context, const string &what, bool AnnouncePublic=false) const