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