Lumiera  0.pre.03
»edit your freedom«
activity-term.hpp
Go to the documentation of this file.
1 /*
2  ACTIVITY-TERM.hpp - definition language framework for scheduler activities
3 
4  Copyright (C) Lumiera.org
5  2023, Hermann Vosseler <Ichthyostega@web.de>
6 
7  This program is free software; you can redistribute it and/or
8  modify it under the terms of the GNU General Public License as
9  published by the Free Software Foundation; either version 2 of
10  the License, or (at your option) any later version.
11 
12  This program is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  GNU General Public License for more details.
16 
17  You should have received a copy of the GNU General Public License
18  along with this program; if not, write to the Free Software
19  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 
21 */
22 
23 
72 #ifndef SRC_VAULT_GEAR_ACTIVITY_TERM_H_
73 #define SRC_VAULT_GEAR_ACTIVITY_TERM_H_
74 
75 
76 #include "vault/gear/activity.hpp"
78 #include "vault/gear/job.h"
79 #include "lib/time/timevalue.hpp"
80 
81 #include <string>
82 #include <utility>
83 
84 
85 namespace vault{
86 namespace gear {
87 
88  using lib::time::Time;
90  using std::string;
91  using std::move;
92 
93  using BlockFlowAlloc = BlockFlow<blockFlow::RenderConfig>;
94 
95 
96  namespace activity {
97 
102  class Term
103  {
104 
105  using AllocHandle = BlockFlowAlloc::AllocatorHandle;
106 
107  AllocHandle alloc_;
108 
109  Activity* invoke_{nullptr};
110  Activity* post_{nullptr};
111 
112  Activity* gate_{nullptr};
113  Activity* callback_{nullptr};
114 
115 
116  public:
120  };
121 
122  explicit
123  Term (AllocHandle&& allocHandle, Template kind, Time start, Time dead, Job job)
124  : alloc_{move (allocHandle)}
125  , invoke_{setupInvocation (job)}
126  , post_{setupPost (start,dead, invoke_)}
127  {
128  configureTemplate (kind);
129  }
130 
131  // standard copy acceptable
132 
133  operator std::string() const
134  {
135  return "Term-"
136  + (post_? string{*post_} : util::BOTTOM_INDICATOR)
137  + "⧐"
138  + (invoke_? string{*invoke_} : util::BOTTOM_INDICATOR);
139  }
140 
141 
146  Activity&
148  {
149  REQUIRE (post_, "Activity Term not yet fully configured");
150  return *post_;
151  }
152 
157  Activity&
159  {
160  REQUIRE (callback_, "Activity Term properly configured for async IO");
161  return *callback_;
162  }
163 
173  Term&
174  expectNotification (Activity& notificationSrc, bool unlimitedTime =false)
175  {
176  REQUIRE (notificationSrc.is (Activity::NOTIFY));
177  setupGate();
178  gate_->incDependencies();
179  Time triggerTimeStart{unlimitedTime? Time::ANYTIME : post_->data_.timeWindow.life};
180  notificationSrc.setNotificationTarget (gate_, triggerTimeStart);
181  return *this;
182  }
183 
190  Term&
191  appendNotificationTo (Term& targetTerm, bool unlimitedTime =false)
192  {
193  Activity& success = alloc_.create (Activity::NOTIFY);
194  insert (findTail (callback_? callback_ : invoke_), &success);
195  targetTerm.expectNotification (success, unlimitedTime);
196  return *this;
197  }
198 
218  Term&
220  {
221  Activity& trigger = alloc_.create (Activity::NOTIFY);
222  expectNotification (trigger);
223  insert (post_, &trigger);
224  return *this;
225  }
226 
227  private:
228  void
229  configureTemplate (Template kind)
230  {
231  switch (kind) {
232  case CALC_JOB:
233  setupGate();
234  insertWorkBracket();
235  break;
236  case LOAD_JOB:
237  insertWorkBracket();
238  severAsyncChain();
239  break;
240  case META_JOB:
241  /* use the minimal default wiring */
242  break;
243  default:
244  NOTREACHED ("unknown wiring scheme for Render Jobs.");
245  break;
246  }
247  }
248 
249 
250  Activity*
251  setupInvocation (Job& job)
252  {
253  Activity& feed1 = alloc_.create (job.parameter.invoKey.code.w1
254  ,job.parameter.invoKey.code.w2);
255  Activity& feed2 = alloc_.create (Activity::FEED);
256  feed1.next = &feed2;
257 
258  JobClosure* functor = static_cast<JobClosure*> (job.jobClosure);
259  REQUIRE (functor);
260  Activity& invo = alloc_.create (*functor
261  , Time{TimeValue{job.parameter.nominalTime}}
262  , feed1);
263  return & invo;
264  }
265 
266  Activity*
267  setupPost (Time start, Time dead, Activity* followUp)
268  {
269  return & alloc_.create (start,dead,followUp);
270  }
271 
272  void
273  setupGate()
274  {
275  if (gate_) return;
276  gate_ = & alloc_.create (0, Time{post_->data_.timeWindow.dead});
277  ENSURE (gate_);
278  ENSURE (gate_->is (Activity::GATE));
279  insert (post_, gate_);
280  }
281 
282  void
283  insertWorkBracket()
284  {
285  Activity& start = alloc_.create (Activity::WORKSTART);
286  Activity& stop = alloc_.create (Activity::WORKSTOP);
288 
289  insert (gate_? gate_: post_, &start);
290  insert (findTail (start.next), &stop);
291  }
292 
293  void
294  severAsyncChain()
295  {
296  if (callback_) return;
297  Activity& cut = *invoke_->next->next;
298  REQUIRE (cut.is (Activity::FEED));
299  callback_ = cut.next;
300  cut.next = nullptr;
301  ENSURE (callback_);
302  }
303 
304 
305  static void
306  insert (Activity* anchor, Activity* target)
307  {
308  REQUIRE (anchor);
309  REQUIRE (target);
310  target->next = anchor->next;
311  anchor->next = target;
312  }
313 
314  static Activity*
315  findTail (Activity* chain)
316  {
317  REQUIRE (chain);
318  while (chain->next)
319  chain = chain->next;
320  return chain;
321  }
322  };
323 
324  }//(End)namespace activity
325 }}// namespace vault::gear
326 #endif /*SRC_VAULT_GEAR_ACTIVITY_TERM_H_*/
static const Time ANYTIME
border condition marker value. ANYTIME <= any time value
Definition: timevalue.hpp:322
signal start of some processing and transition grooming mode ⟼ *work mode
Definition: activity.hpp:242
Record to describe an Activity, to happen within the Scheduler&#39;s control flow.
Definition: activity.hpp:235
Memory management scheme for activities and parameter data passed through the Scheduler within the Lu...
Term & requireDirectActivation()
Insert a self-inhibition to enforce activation is possible only after the scheduled start time...
correspondingly signal end of some processing
Definition: activity.hpp:243
supply additional payload data for a preceding Activity
Definition: activity.hpp:247
scheme for a synchronous media calculation job
Lumiera&#39;s internal time value datatype.
Definition: timevalue.hpp:308
scheme for an asynchronous data retrieval job
Term & expectNotification(Activity &notificationSrc, bool unlimitedTime=false)
Builder operation: block this Term waiting for prerequisite notification.
A Term of the »Activity Language«, describing the steps necessary to perform the calculation of a sin...
ElementBoxWidget::Config::Qualifier kind(Kind kind)
qualify the basic use case for the new ElementBoxWidget
probe window + count-down; activate next Activity, else re-schedule
Definition: activity.hpp:245
Activity * next
Activities are organised into chains to represent relations based on verbs.
Definition: activity.hpp:258
Term & appendNotificationTo(Term &targetTerm, bool unlimitedTime=false)
Builder operation: append a Notification link to the end of this Term&#39;s chain.
Definition of a render job.
push a message to another Activity
Definition: activity.hpp:244
scheme for planning and organisational job
Interface of the closure for frame rendering jobs.
Definition: job.h:244
Individual frame rendering task, forwarding to a closure.
Definition: job.h:277
a family of time value like entities and their relationships.
basic constant internal time value.
Definition: timevalue.hpp:142
Vault-Layer implementation namespace root.
Descriptor for a piece of operational logic performed by the scheduler.