Blender  V3.3
FN_multi_function_procedure.hh
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 
3 #pragma once
4 
9 #include "FN_multi_function.hh"
10 
11 namespace blender::fn {
12 
13 class MFVariable;
14 class MFInstruction;
15 class MFCallInstruction;
18 class MFDummyInstruction;
19 class MFReturnInstruction;
20 class MFProcedure;
21 
23 enum class MFInstructionType {
24  Call,
25  Branch,
26  Destruct,
27  Dummy,
28  Return,
29 };
30 
36  public:
37  enum Type {
44  };
45 
46  private:
47  Type type_ = None;
48  MFInstruction *instruction_ = nullptr;
49  /* Only used when it is a branch instruction. */
50  bool branch_output_ = false;
51 
52  public:
53  MFInstructionCursor() = default;
58 
60 
61  MFInstruction *next(MFProcedure &procedure) const;
62  void set_next(MFProcedure &procedure, MFInstruction *new_instruction) const;
63 
64  MFInstruction *instruction() const;
65 
66  Type type() const;
67 
69  {
70  return a.type_ == b.type_ && a.instruction_ == b.instruction_ &&
71  a.branch_output_ == b.branch_output_;
72  }
73 
75  {
76  return !(a == b);
77  }
78 };
79 
86  private:
87  MFDataType data_type_;
89  std::string name_;
90  int index_in_graph_;
91 
92  friend MFProcedure;
93  friend MFCallInstruction;
94  friend MFBranchInstruction;
95  friend MFDestructInstruction;
96 
97  public:
98  MFDataType data_type() const;
100 
101  StringRefNull name() const;
102  void set_name(std::string name);
103 
104  int index_in_procedure() const;
105 };
106 
109  protected:
112 
113  friend MFProcedure;
119 
120  public:
121  MFInstructionType type() const;
122 
128 };
129 
135  private:
136  const MultiFunction *fn_ = nullptr;
137  MFInstruction *next_ = nullptr;
139 
140  friend MFProcedure;
141 
142  public:
143  const MultiFunction &fn() const;
144 
145  MFInstruction *next();
146  const MFInstruction *next() const;
147  void set_next(MFInstruction *instruction);
148 
149  void set_param_variable(int param_index, MFVariable *variable);
150  void set_params(Span<MFVariable *> variables);
151 
154 };
155 
161  private:
162  MFVariable *condition_ = nullptr;
163  MFInstruction *branch_true_ = nullptr;
164  MFInstruction *branch_false_ = nullptr;
165 
166  friend MFProcedure;
167 
168  public:
170  const MFVariable *condition() const;
171  void set_condition(MFVariable *variable);
172 
174  const MFInstruction *branch_true() const;
175  void set_branch_true(MFInstruction *instruction);
176 
178  const MFInstruction *branch_false() const;
179  void set_branch_false(MFInstruction *instruction);
180 };
181 
189  private:
190  MFVariable *variable_ = nullptr;
191  MFInstruction *next_ = nullptr;
192 
193  friend MFProcedure;
194 
195  public:
196  MFVariable *variable();
197  const MFVariable *variable() const;
199 
200  MFInstruction *next();
201  const MFInstruction *next() const;
202  void set_next(MFInstruction *instruction);
203 };
204 
209  private:
210  MFInstruction *next_ = nullptr;
211 
212  friend MFProcedure;
213 
214  public:
215  MFInstruction *next();
216  const MFInstruction *next() const;
217  void set_next(MFInstruction *instruction);
218 };
219 
224 };
225 
229 struct MFParameter {
232 };
233 
237 };
238 
248  private:
249  LinearAllocator<> allocator_;
250  Vector<MFCallInstruction *> call_instructions_;
251  Vector<MFBranchInstruction *> branch_instructions_;
252  Vector<MFDestructInstruction *> destruct_instructions_;
253  Vector<MFDummyInstruction *> dummy_instructions_;
254  Vector<MFReturnInstruction *> return_instructions_;
255  Vector<MFVariable *> variables_;
256  Vector<MFParameter> params_;
257  Vector<destruct_ptr<MultiFunction>> owned_functions_;
258  MFInstruction *entry_ = nullptr;
259 
260  friend class MFProcedureDotExport;
261 
262  public:
263  MFProcedure() = default;
264  ~MFProcedure();
265 
266  MFVariable &new_variable(MFDataType data_type, std::string name = "");
272 
273  void add_parameter(MFParamType::InterfaceType interface_type, MFVariable &variable);
275 
276  template<typename T, typename... Args> const MultiFunction &construct_function(Args &&...args);
277 
278  MFInstruction *entry();
279  const MFInstruction *entry() const;
281 
284 
285  std::string to_dot() const;
286 
287  bool validate() const;
288 
289  private:
290  bool validate_all_instruction_pointers_set() const;
291  bool validate_all_params_provided() const;
292  bool validate_same_variables_in_one_call() const;
293  bool validate_parameters() const;
294  bool validate_initialization() const;
295 
296  struct InitState {
297  bool can_be_initialized = false;
298  bool can_be_uninitialized = false;
299  };
300 
301  InitState find_initialization_state_before_instruction(const MFInstruction &target_instruction,
302  const MFVariable &variable) const;
303 };
304 
305 namespace multi_function_procedure_types {
312 } // namespace multi_function_procedure_types
313 
314 /* -------------------------------------------------------------------- */
319  : type_(Call), instruction_(&instruction)
320 {
321 }
322 
324  : type_(Destruct), instruction_(&instruction)
325 {
326 }
327 
329  bool branch_output)
330  : type_(Branch), instruction_(&instruction), branch_output_(branch_output)
331 {
332 }
333 
335  : type_(Dummy), instruction_(&instruction)
336 {
337 }
338 
340 {
341  MFInstructionCursor cursor;
342  cursor.type_ = Type::Entry;
343  return cursor;
344 }
345 
347 {
348  /* This isn't really const correct unfortunately, because to make it correct we'll need a const
349  * version of #MFInstructionCursor. */
350  return instruction_;
351 }
352 
354 {
355  return type_;
356 }
357 
360 /* -------------------------------------------------------------------- */
365 {
366  return data_type_;
367 }
368 
370 {
371  return users_;
372 }
373 
375 {
376  return name_;
377 }
378 
380 {
381  return index_in_graph_;
382 }
383 
386 /* -------------------------------------------------------------------- */
391 {
392  return type_;
393 }
394 
396 {
397  return prev_;
398 }
399 
402 /* -------------------------------------------------------------------- */
407 {
408  return *fn_;
409 }
410 
412 {
413  return next_;
414 }
415 
417 {
418  return next_;
419 }
420 
422 {
423  return params_;
424 }
425 
427 {
428  return params_;
429 }
430 
433 /* -------------------------------------------------------------------- */
438 {
439  return condition_;
440 }
441 
443 {
444  return condition_;
445 }
446 
448 {
449  return branch_true_;
450 }
451 
453 {
454  return branch_true_;
455 }
456 
458 {
459  return branch_false_;
460 }
461 
463 {
464  return branch_false_;
465 }
466 
469 /* -------------------------------------------------------------------- */
474 {
475  return variable_;
476 }
477 
479 {
480  return variable_;
481 }
482 
484 {
485  return next_;
486 }
487 
489 {
490  return next_;
491 }
492 
495 /* -------------------------------------------------------------------- */
500 {
501  return next_;
502 }
503 
505 {
506  return next_;
507 }
508 
511 /* -------------------------------------------------------------------- */
516 {
517  static_assert(sizeof(MFParameter) == sizeof(ConstMFParameter));
518  return params_.as_span().cast<ConstMFParameter>();
519 }
520 
522 {
523  return entry_;
524 }
525 
526 inline const MFInstruction *MFProcedure::entry() const
527 {
528  return entry_;
529 }
530 
532 {
533  return variables_;
534 }
535 
537 {
538  return variables_;
539 }
540 
541 template<typename T, typename... Args>
542 inline const MultiFunction &MFProcedure::construct_function(Args &&...args)
543 {
544  destruct_ptr<T> fn = allocator_.construct<T>(std::forward<Args>(args)...);
545  const MultiFunction &fn_ref = *fn;
546  owned_functions_.append(std::move(fn));
547  return fn_ref;
548 }
549 
552 } // namespace blender::fn
struct Entry Entry
destruct_ptr< T > construct(Args &&...args)
void set_branch_true(MFInstruction *instruction)
void set_condition(MFVariable *variable)
void set_branch_false(MFInstruction *instruction)
void set_next(MFInstruction *instruction)
void set_param_variable(int param_index, MFVariable *variable)
void set_params(Span< MFVariable * > variables)
void set_next(MFInstruction *instruction)
void set_next(MFInstruction *instruction)
friend bool operator==(const MFInstructionCursor &a, const MFInstructionCursor &b)
MFInstruction * next(MFProcedure &procedure) const
void set_next(MFProcedure &procedure, MFInstruction *new_instruction) const
friend bool operator!=(const MFInstructionCursor &a, const MFInstructionCursor &b)
Vector< MFInstructionCursor > prev_
Span< MFInstructionCursor > prev() const
MFBranchInstruction & new_branch_instruction()
void add_parameter(MFParamType::InterfaceType interface_type, MFVariable &variable)
MFDummyInstruction & new_dummy_instruction()
void set_entry(MFInstruction &entry)
MFReturnInstruction & new_return_instruction()
MFCallInstruction & new_call_instruction(const MultiFunction &fn)
MFDestructInstruction & new_destruct_instruction()
MFVariable & new_variable(MFDataType data_type, std::string name="")
Span< ConstMFParameter > params() const
const MultiFunction & construct_function(Args &&...args)
Span< MFInstruction * > users()
void set_name(std::string name)
#define T
static unsigned a[3]
Definition: RandGen.cpp:78
std::unique_ptr< T, DestructValueAtAddress< T > > destruct_ptr
static const pxr::TfToken b("b", pxr::TfToken::Immortal)
MFParamType::InterfaceType type