HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
OP_OperatorTable.h
Go to the documentation of this file.
1 /*
2  * PROPRIETARY INFORMATION. This software is proprietary to
3  * Side Effects Software Inc., and is not to be reproduced,
4  * transmitted, or disclosed in any way without written permission.
5  *
6  * NAME: OP_OperatorTable.h (C++)
7  *
8  * COMMENTS: This class is simply a symbol table of OP_Operator's.
9  *
10  */
11 
12 #ifndef __OP_OperatorTable_h__
13 #define __OP_OperatorTable_h__
14 
15 #include "OP_API.h"
16 #include "OP_OTLDefinition.h"
17 #include "OP_Operator.h"
19 #include <UT/UT_NonCopyable.h>
20 #include <UT/UT_String.h>
21 #include <UT/UT_StringMap.h>
22 #include <UT/UT_SymbolTable.h>
23 #include <UT/UT_ValArray.h>
24 #include <UT/UT_Color.h>
25 #include <iosfwd>
26 
27 class OP_Node;
28 class OP_Network;
29 class OP_OperatorTable;
30 class OP_ScriptOperator;
31 class OP_ScriptIndexFile;
33 
36 typedef OP_ScriptOperator *(*OP_ScriptCreatorFunc)
37  (const OP_OTLDefinition &definition);
38 typedef bool (*OP_ScriptCanReuseFunc)
39  (const OP_ScriptOperator *script_operator,
40  const OP_OTLDefinition &new_definition);
41 
43 {
44 public:
45  OP_OperatorTable(const char *table_name, const char *script_directory);
47 
48  static int getAllOperatorTables(OP_OperatorTableList &list);
49 
50  /// Creates a new node of a given type inside a parent and names it
51  /// as a give name.
52  /// @param exact_type If true, the operator name parameter 'type',
53  /// is used verbatim to lookup the operator. Otherwise,
54  /// a preferred operator name that matches 'type'
55  /// specification is found first and then is used to lookup
56  /// the operator. For example, "hda" may match "hda::2.0",
57  /// which is the preferred operator definition.
58  OP_Node *createNode(OP_Network *parent, const char *type,
59  const char *name = 0,
60  int *aliasedScriptedOp = 0,
61  bool exact_type = false);
62 
63  OP_Operator *getOperator(const char *name) const;
64  bool addOperator(OP_Operator *op,
65  std::ostream *err = nullptr);
66  void removeOperator(OP_Operator *op);
67 
69  { return myPrimarySubnet; }
70 
71  void setScriptCreator(OP_ScriptCreatorFunc creator_func,
72  OP_ScriptCanReuseFunc reuse_func);
73  void addScriptIndexFile(const char *indexpath,
74  const char *indexfile,
75  const char *classid,
76  const char *extrainfo,
77  int defaultMinInputs,
78  int defaultMaxInputs,
79  bool issubnet,
80  bool ispython);
81  bool loadScriptOperator(const char *opname, UT_IStream &is,
82  OP_OTLLibrary *addToLib);
83  bool addOperatorIfNew(const OP_OTLDefinition &definition);
84  bool canReuseOperator(
85  const OP_OTLDefinition &new_definition,
86  const OP_Operator *op = 0) const;
87 
88  void requestReload();
89 
90  // Runs the DSO installation function on our currently loaded dso's inthe
91  // dso search path.
92  void runDSOInstall();
93 
94  // Loads the given dso file and runs the installation function
95  bool loadDSO(const char *dso_file);
96 
97  // Runs this op table function on a spcific library.
98  bool runDSO(const char* lib_path);
99 
100  int entries() const
101  { return myOpCount; }
102 
103  void getOperatorList(UT_StringArray &list,
104  bool english=true) const;
105  int getOperators(OP_OperatorList &list,
106  OP_Network *net = 0,
107  bool filterhidden = false) const;
108 
109  // This returns the optype id for the given table.
110  OP_OpTypeId getOpTypeID() const;
111 
112  // This returns a unique integer for each OP_OperatorTable created
113  int getUniqueOpTypeID() const
114  { return myUniqueOpTypeID; }
115  // Before sorting, you should getOperators(list);
116  void sortOperators(OP_OperatorList &list,
119 
120  const UT_String &getName() const
121  { return myName; }
122  const UT_String &getScriptPath() const
123  { return myScriptDirectory; }
124 
125  unsigned getOperatorStatus(OP_Operator *op) const;
126  unsigned getStatus() const;
127  void setDefaultType(const char *type);
128  const char *getDefaultType() const;
129 
130  // Add an operator alias (from the OPcustomize file).
131  bool setOpRename(const char *optype, const char *newname,
132  std::ostream *err = nullptr);
133  // Display all the oprename commands.
134  void outputOpRenames(std::ostream &os) const;
135 
136  // Add an operator alias (from the OPcustomize file).
137  bool setOpAlias(const char *optype,
138  const char *alias,
139  std::ostream *err = nullptr);
140 
141  // Sets what the inital default name of the op will be.
142  // null first name will disable, reverting to the usual rules.
143  bool setOpFirstName(const char *type,
144  const char *firstname,
145  std::ostream *err = nullptr);
146  // Display all the opalias commands.
147  void outputOpAliases(std::ostream &os) const;
148  // Display all the firstname commands.
149  void outputOpFirstNames(std::ostream &os) const;
150  // Get all the aliases for a particular operator type.
151  void getOpAliases(const char *opname,
152  UT_StringArray &opaliases) const;
153  // Get the operator type represented by the supplied alias (if any).
154  const char *getOpFromAlias(const char *alias) const;
155 
156  /// Sets the boost for the tab menu for this _label_.
157  /// Maybe allow globbing at some point?
158  void setTabBoost(const char *label, int boost);
159 
160  /// Returns how much this label should be boosted, will be
161  /// the largest of matched labels.
162  int getTabBoost(const char *label) const;
163 
164  /// Directly provide the tab boost table
165  UT_SharedPtr<UT_StringMap<int>> tabBoostTable() const { return myTabBoost; }
166 
167  /// Output all the tab boosts.
168  void outputTabBoosts(std::ostream &os) const;
169 
170  /// Sets the macro for the tab menu for this shortcut.
171  /// This is a fixed label that will be given highest precedent to
172  /// match the shortcut.
173  void setTabMacro(const char *shortcut, const UT_StringHolder &label);
174 
175  /// Return the label to consider highest priority for this shortcut
176  /// Empty string if none.
177  UT_StringHolder getTabMacro(const char *shortcut) const;
178 
179  /// Directly provide the tab boost table
181 
182  /// Output all the tab macros.
183  void outputTabMacros(std::ostream &os) const;
184 
185  // Add an operator override (from the OPcustomize file).
186  bool setOpOverride(const char *optype,
187  const char *override,
188  bool keep_parms, bool keep_contents,
189  std::ostream *err = nullptr);
190  // Add an operator override (from the OPcustomize file).
191  bool clearOpOverride(const char *optype,
192  std::ostream *err = nullptr);
193  // Display all the opoverride commands.
194  void outputOpOverrides(std::ostream &os) const;
195  // Get all the overridees for a particular operator type.
196  void getOpOverrides(const char *opname,
197  UT_StringArray &opoverridees) const;
198 
199  // Add an operator to the excluded op list (from the OPcustomize file).
200  bool addOpExcluded(const char *opname,
201  std::ostream *err = nullptr);
202  // Is operator excluded?
203  bool isOpExcluded(const char *opname) const;
204  // Display all the opexclude commands.
205  void outputOpExcluded(std::ostream &os) const;
206  // Add an operator to the hidden op list (from the OPcustomize file).
207  bool addOpHidden(const char *opname,
208  std::ostream *err = nullptr);
209  // Delete an operator from the hidden op list (from the OPcustomize file).
210  void delOpHidden(const char *opname);
211  // Is operator hidden?
212  bool isOpHidden(const char *opname) const;
213  // Get all hidden ops.
214  void getOpHidden(UT_StringArray &opnames) const;
215 
216  // Is operator experimental?
217  bool isOpExperimental(const UT_StringRef &opname) const;
218  // Add operator to experimental list
219  bool addOpExperimental(const char *opname,
220  std::ostream *err = nullptr);
221 
222  // Mark the operator as deprecated.
223  bool setOpDeprecated(const char *opname,
224  const char *version,
225  const char *replacement = 0,
226  std::ostream *err = nullptr);
227  // Is the operator deprecated?
228  bool isOpDeprecated(const char *opname) const;
229 
230  // Retrieve the deprecation version and possible replacement operator.
231  bool getDeprecationInfo(const char *opname,
233  UT_StringHolder &replacement) const;
234  // Display all the opdeprecate commands.
235  void outputOpDeprecated(std::ostream &os) const;
236 
237  // Sets the default color for an operator type.
238  bool setOpDefaultColor(const UT_StringHolder &optype,
239  const UT_Color &clr,
240  std::ostream *err = nullptr);
241  // Gets the default color for the supplied operator type.
242  UT_Color getOpDefaultColor(const UT_StringRef &optype) const;
243  // Determine if we have a optype specific default color
244  bool hasSpecificOpDefaultColor(
245  const UT_StringRef &optype) const;
246  // Clear all the opdefaultcolor commands.
247  void clearOpDefaultColors();
248  // Display all the opdefaultcolor commands.
249  void outputOpDefaultColors(std::ostream &os) const;
250 
251  // Sets the default shape for an operator type.
252  bool setOpDefaultShape(const UT_StringHolder &optype,
253  const UT_StringHolder &shape,
254  std::ostream *err = nullptr);
255  // Gets the default shape for the supplied operator type.
256  const UT_StringHolder &getOpDefaultShape(const UT_StringRef &optype) const;
257  // Determine if we have a optype specific default shape
258  bool hasSpecificOpDefaultShape(
259  const UT_StringRef &optype) const;
260  // Clear all the opdefaultshape commands.
261  void clearOpDefaultShapes();
262  // Display all the opdefaultshape commands.
263  void outputOpDefaultShapes(std::ostream &os) const;
264 
265  // Get or set the wire style for networks with this child node type.
266  const UT_StringHolder &getDefaultWireStyle() const;
267  void setDefaultWireStyle(const UT_StringHolder &wirestyle);
268 
269  // When no name is specified for a node, we typically use the type as the
270  // prefix for the name. However, we may want to provide a method for
271  // creating alternate default names for operators.
272  void getDefaultNodeName(const char *type, UT_String &name);
273 
274  // If there is an index file that contains scripted subnets for this op
275  // table, this function returns a pointer to that file name.
276  const char *getScriptedSubnetIndex() const;
277 
278  // Notify those who are interested that our table contents have changed.
279  // Don't do this in addOperator - only after bulk operations like
280  // loadScriptOperators or OP_Netowkr::loadScriptedOpDefs.
281  void notifyUpdateTableSinksOfUpdate();
282 
283  static inline int getLoadDSOFlag()
284  { return theLoadDSOFlag; }
285  static inline void setLoadDSOFlag(int i)
286  { theLoadDSOFlag = i; }
287  static unsigned getPermissionMask(const OP_Operator *op);
288  static void clearPermissionMask(const OP_Operator *op);
289 
290  /// Called once all basic operator types are loaded to call the python
291  /// code which will initialize node color and shape themes.
292  static void initializeOpThemes();
293 
294  /// Builds (or rebuilds) the operator type namespace hierarchy.
295  /// The optype precedence is given by the environment variable
296  /// HOUDINI_OPTYPE_NAMESPACE_HIERARCHY, which is processed by this method.
297  static void buildOpTypeNamespaceHierarchy();
298 
299  /// Obtains the value of the environment variable used to construct
300  /// the hierarchy.
301  static const char *getOpTypeNamespaceHierarchyPref();
302 
303  /// Obtains a list of available operator names that have the same base
304  /// (core) name as the given operator.
305  /// If scope network name is not NULL, the list includes only operators
306  /// whose nodes can be created in that network (otherwise all
307  /// operators are included).
308  /// The list is sorted according to the descending precedence order.
309  void getCandidateOperatorNamesInPrecedenceOrder(
310  UT_StringArray &precedence_order,
311  const char *op_name,
312  const UT_StringArray *scope_network_stack);
313 
314  /// Obtains the preferred operator name that matches the given op_name.
315  /// Any name component included in the op_name must match the returned op
316  /// type name, and any component not present in op_name is assumed to match
317  /// the returned op type. For example 'hda' will match any scope, namespace,
318  /// or version, while 'userA::hda' will match any scope and version, but the
319  /// namespace must be 'userA'. For global namespace use '::hda' and for
320  /// versionless opname use 'hda::'.
321  /// If the scope_network_stack is also given (ie, non-null) then the
322  /// returned opname must match one of the scopes listed in that array too.
323  /// Returns the name of the highest precedence operator that matches
324  /// the given op_name.
325  const char *getPreferredOperatorName(const char *opname,
326  const UT_StringArray *scope_network_stack);
327 
328  /// Returns true if the provided node name is "close enough" to the
329  /// operator type name, english name, or first name to imply what the
330  /// operator type is.
331  bool nodeNameImpliesType(OP_Operator *op,
332  const char *node_name) const;
333 
334  /// Convenience functions for the second callback in setScriptCreator().
335  static bool alwaysReuseScriptOperatorCallback(
336  const OP_ScriptOperator *script_operator,
337  const OP_OTLDefinition &new_definition);
338  static bool neverReuseScriptOperatorCallback(
339  const OP_ScriptOperator *script_operator,
340  const OP_OTLDefinition &new_definition);
341 
342 private:
343  // Functions for adding or removing a table sink.
344  void addUpdateTableSink(OP_UpdateTableSink *sink);
345  void removeUpdateTableSink(OP_UpdateTableSink *sink);
346  // Called when the operator is deleted.
347  void notifyUpdateTableSinksOfDelete();
348 
349  // Functions for adding new operator types using an OP_OTLDefinition.
350  OP_ScriptOperator *addNewOperator(const OP_OTLDefinition &definition,
351  std::ostream *err = nullptr);
352  int loadScriptIndexFile(OP_ScriptIndexFile &sif,
353  bool checkdup);
354  /// Returns the table's operator namespace hierarchy (ie, the hierarchy
355  /// of operator definitions for the optype associated with this table).
356  OP_OpNamespaceHierarchy &getOpNamespaceHierarchy()
357  { return myOpNamespaceHierarchy; }
358 
359  /// Returns the operator named 'opname' for instantiating a node
360  /// inside the parent. If 'opname' is an ambiguous and unqualified opname
361  /// (ie core name witouth namespace), the preferred operator matching
362  /// that opname is returned. However when loading a network or if
363  /// the exact_name flag is true, then an operator with the exact 'opname'
364  /// is returned (or NULL).
365  OP_Operator *getPreferredOperator(OP_Network *parent,
366  const char *opname, bool exact_opname);
367 
368  UT_String myName;
369  UT_String myScriptDirectory;
370  UT_String myDefaultType;
371  UT_String myScriptedSubnetIndex;
372  UT_Color myDefaultColor;
373  UT_StringHolder myDefaultShape;
374  UT_StringHolder myDefaultWireStyle;
375  OP_Operator *myPrimarySubnet;
376  int myOpCount;
377  int myUniqueOpTypeID;
378  static int theLoadDSOFlag;
379 
380  OP_ScriptCreatorFunc myScriptCreatorFunc;
381  OP_ScriptCanReuseFunc myScriptCanReuseFunc;
382  UT_ValArray<OP_ScriptIndexFile *> myScriptIndexFiles;
383  UT_ValArray<OP_UpdateTableSink *> myUpdateTableSinks;
384 
385  // Data structure to store information on operators, without affecting
386  // the operator definition itself. This also allows us to store overrides
387  // for operators that have not been loaded yet.
388  class OpInfo
389  {
390  public:
391  OpInfo();
392  bool isEmpty() const;
393 
394  OP_Operator *myOperator;
395  OP_Operator *myOriginalOperator;
396  UT_StringHolder myCreationName;
397  UT_StringHolder myOriginalEnglishName;
398 
399  // Deprecation support
400  UT_StringHolder myDeprecatedVersion;
401  UT_StringHolder myDeprecatedReplacement;
402 
403  // Flags
404  bool myIsHidden:1;
405  bool myIsExcluded:1;
406  bool myIsExperimental:1;
407  bool myIsOverridden:1;
408  };
409 
410  UT_SymbolMap<OpInfo> myOperators;
411  UT_SymbolMap<UT_StringHolder> myOpAliases;
412  UT_SymbolMap<UT_StringHolder> myOpOverrides;
413  UT_StringMap<UT_Color> myOpDefaultColors;
414  UT_StringMap<UT_StringHolder> myOpDefaultShapes;
415 
416  UT_SharedPtr<UT_StringMap<int>> myTabBoost;
418 
419  OP_OpNamespaceHierarchy myOpNamespaceHierarchy;
420  static UT_String theOpTypeNamespaceHierarchyPref;
421  static bool theOpThemesInitialized;
422 
423  friend class OP_UpdateTableSink;
424 };
425 
427 {
428 public:
431  { removeAllTableSinks(); }
432 
433  virtual void tableUpdated(OP_OperatorTable *table) = 0;
435  { removeUpdateTableSink(table); }
436 
437 protected:
439  {
440  if( !table ) return;
441  table->addUpdateTableSink(this);
442  myOpTables.append(table, 1);
443  }
445  {
446  if( !table ) return;
447  table->removeUpdateTableSink(this);
448  myOpTables.findAndRemove(table);
449  }
451  {
452  for( int i = myOpTables.entries(); i --> 0; )
453  removeUpdateTableSink(myOpTables(i));
454  }
455 
456 private:
457  OP_OperatorTableList myOpTables;
458 };
459 
460 #endif
bool(* OP_ScriptCanReuseFunc)(const OP_ScriptOperator *script_operator, const OP_OTLDefinition &new_definition)
virtual ~OP_UpdateTableSink()
GLuint GLsizei const GLchar * label
Definition: glcorearb.h:2545
UT_SharedPtr< UT_StringMap< int > > tabBoostTable() const
Directly provide the tab boost table.
OutGridT const XformOp bool bool
UT_SharedPtr< UT_StringMap< UT_StringHolder > > tabMacroTable() const
Directly provide the tab boost table.
OP_Operator * getPrimarySubnetOperator()
static void setLoadDSOFlag(int i)
GLint GLint GLsizei GLint GLenum GLenum type
Definition: glcorearb.h:108
static int getLoadDSOFlag()
std::shared_ptr< T > UT_SharedPtr
Wrapper around std::shared_ptr.
Definition: UT_SharedPtr.h:36
int getUniqueOpTypeID() const
OP_OpTypeId
Definition: OP_OpTypeId.h:18
GLuint const GLchar * name
Definition: glcorearb.h:786
GLenum GLenum GLsizei void * table
Definition: glad.h:5129
UT_SymbolMap< OP_OperatorTable * > OP_OperatorTableMap
UT_ValArray< OP_OperatorTable * > OP_OperatorTableList
GT_API const UT_StringHolder version
virtual void tableDeleted(OP_OperatorTable *table)
OP_ScriptOperator *(* OP_ScriptCreatorFunc)(const OP_OTLDefinition &definition)
const UT_String & getName() const
void removeUpdateTableSink(OP_OperatorTable *table)
const UT_String & getScriptPath() const
#define OP_API
Definition: OP_API.h:10
int entries() const
void addUpdateTableSink(OP_OperatorTable *table)