HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
VOP_TypeDefinitionFile.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: VOP_TypeDefinitionFile.h ( VOP Library, C++)
7  *
8  * COMMENTS:
9  */
10 
11 #ifndef __VOP_TypeDefinitionFile__
12 #define __VOP_TypeDefinitionFile__
13 
14 #include "VOP_API.h"
15 #include "VOP_Language.h" // for VOP_LanguageHandle
17 #include <OP/OP_OperatorTable.h> // for base classes
18 #include <UT/UT_ValArray.h>
19 #include <UT/UT_StringMap.h>
20 #include <UT/UT_Functor.h>
21 
22 class UT_StringArray;
23 class VOP_LanguageCustom;
24 
25 // ============================================================================
26 /// Function that creates an instance of a type definition subclass,
27 /// and a dictionary that maps a definition metatype names to such functions.
30 
31 // ============================================================================
32 /// Represents a source of vop type definitions saved in files or inside HDAs.
34 {
35 public:
36  /// Constructor.
37  /// Note, still need to invoke load() before the object can provide info
38  ///about the types defined in that file.
39  VOP_TypeDefinitionFile( const char *file_path );
40 
41  /// Gets the definition source file path.
42  void getSourcePath( UT_String &path ) const override;
43  const UT_String & getFilePath() const;
44 
45  /// Loads the necessary data from the file before this class provide
46  /// information about type definitions from that file.
47  bool load( const VOP_TypeDefinitionFactoryMap &factory_map,
48  UT_String &errors );
49 
50  /// Saves the current data into the file.
51  bool save( UT_String &errors ) const;
52 
53 
54  /// Obtains the list of language definition names provided by this source.
55  void getLanguageDefinitionNames(UT_StringArray &lang_names)const;
56 
57  /// Returns a language definition provided by this source.
59  getLanguageDefinition( const char *language_name ) override;
60 
61 
62  /// Obtains the list of type definition names provided by this source.
63  void getTypeDefinitionNames( UT_StringArray &type_names ) const;
64 
65  /// Returns a type definition object found in the file at load time.
67  getTypeDefinition( const char *type_name ) override;
68 
69  /// Add a new definition to this source.
70  void addDefinition( VOP_TypeDefinitionHandle type_handle );
71 
72  /// Update an old or add a new definition to this source.
73  void updateOrAddDefinition( const char *type_name,
74  VOP_TypeDefinitionHandle type_handle );
75 
76  /// Delete the definition from the source.
77  bool removeDefinition( const char *type_name );
78 
79  /// @{ Tests some characteristics of the disk file this source represents.
80  bool exists() const;
81  bool canRead() const;
82  bool canWrite() const;
83  /// @}
84 
85  /// @{ Allows editing of types it provides in the default editor.
86  void setAllowsEditingOfTypes( bool flag );
87  bool allowsEditingOfTypes() const;
88  /// @}
89 
90 private:
91  bool loadJSON( const VOP_TypeDefinitionFactoryMap &factory_map,
94  UT_String &errors );
95  bool loadJSONTypeDefs( const UT_JSONValue *json_typedefs,
96  const VOP_TypeDefinitionFactoryMap &factory_map,
98  UT_String &errors );
99  bool loadJSONLangDefs( const UT_JSONValue *json_langdefs,
101  UT_String &errors );
102 
103  bool saveJSON() const;
104 
105  /// Find a handle pointer within the definition handle list.
106  VOP_TypeDefinitionHandle * findTypeHandle( const char *type_name );
107 
108 private:
109  /// The file path.
110  UT_String myFilePath;
111 
112  /// Allows editor to modify the types and their source.
113  bool myAllowEditingOfTypes;
114 
115  /// The list of VOP language definitions this source provides.
116  UT_Array<VOP_LanguageHandle> myLanguageDefinitions;
117 
118  /// The list of VOP data type definitions this source provides.
119  UT_Array<VOP_TypeDefinitionHandle> myTypeDefinitions;
120 };
121 
122 
123 // ============================================================================
124 /// A class for handling files and HDAs as sources of vop type definitions.
126  public OP_UpdateTemplatesSink
127 {
128 public:
130  ~VOP_TypeDefinitionFileLoader() override;
131 
132  /// Gets the file path where the vop types are saved by default.
133  const char * getDefaultSourceFile() const;
134 
135  /// Looks for the definition files in the search path and loads them.
136  void loadDefinitionFilesInSearchPath();
137 
138  /// Loads the definitions from the specified file.
139  bool loadFile( const char *file_path, UT_String &errors );
140 
141  /// Sets a new type definition for a given type name.
142  /// @param old_type_name The original name of the type to redefine.
143  /// This should be NULL, if it's a brand new type.
144  /// If the new definition has a new type name, this
145  /// parameter contains the original (old) type name
146  /// that is being renamed.
147  /// @param type_handle The handle to the type definition object.
148  /// Manager will use it as the new definition for the type.
149  /// The definition must have a valid non-empty type name string.
150  /// @param source_path The file where to save the type definition.
151  /// If the old definition resided in another file, it is moved
152  /// to this new file.
153  /// If NULL, a default file will be used.
154  /// @param errors An outgoing string parameter that will contain
155  /// error messages if manger encounters any problems.
156  void createOrUpdateType( const char *old_type_name,
157  VOP_TypeDefinitionHandle type_handle,
158  const char *source_path,
159  UT_String &errors );
160 
161  /// Deletes the definition from the source.
162  bool deleteType( const char *type_name );
163 
164  /// @{ Registers a functor that creates a data type definition object
165  /// associated with the given meta type name, when such meta type
166  /// is encountered when reading and parsing a JSON file.
167  /// After that the created object is given a chance to load itself from
168  /// the definition JSON value.
169  void registerFactory( const UT_StringHolder &metatype_name,
170  const VOP_TypeDefinitionFactory &factory);
171  void unregisterFactory(const UT_StringHolder &metatype_name);
172  /// @}
173 
174  /// Adds default factories to the map (eg, for "struct" metatype)
175  void registerDefaultFactories();
176 
177  /// Registers interests in tables and ops to monitor HDAs for their
178  /// section that may define vop structs.
179  void registerOperatorInterests();
180 
181  /// @{ Starts and ends a block of code in which the op table updates
182  /// should not be handled. All the pending actions are performed only
183  /// at the time the last endDeferHandlingUpdates() is called.
184  void beginDeferUpdates();
185  void endDeferUpdates();
186  /// @}
187 
188 protected:
189  /// @{ Virtual overrides from the base class. Respectively: monitoring
190  /// for any new HDAs that appear in a table, keeping an eye on existing HDAs
191  /// for anu updates, and making sure we handle deleted HDA operator types.
192  void tableUpdated(OP_OperatorTable *table) override;
193  void templatesUpdated( OP_Operator *op ) override;
194  void operatorDeleted( OP_Operator *op ) override;
195  /// @}
196 
197 private:
198  /// Helper method that handles an update or removal of operator.
199  void updateDefinitionsAndSourcesFromOp( const char *op_name,
200  VOP_TypeDefinitionFile *old_src,
201  VOP_TypeDefinitionFile *new_src );
202 
203 
204  /// Scans the search path and loads all the definition files found there.
205  void loadDefinitionFiles( const char *file_ext );
206 
207  /// Create info objects for the definitions provided by the loaded source.
208  void registerLoadedDefinitions(
210  bool takes_precedence );
211 
212  /// @{
213  /// Helper methods to find and create a vop type definition srouce
214  /// corresponding to a disk file.
215  /// When takes_precedence is true, any newly loaded type definitions
216  /// that conflict with existing types will take precedence; otherwise,
217  /// the existing definitions will remain the ones that define the type.
218  bool hasSource( VOP_TypeDefinitionFile *src ) const;
219  VOP_TypeDefinitionFile * findSource( const char *path );
220  VOP_TypeDefinitionFile * createAndLoadSource(
221  const char *path,
222  bool takes_precedence,
223  UT_String *errors = NULL );
224  /// @}
225 
226 private:
227  /// The manager in which we register types defined in files.
228  VOP_LanguageManager & myOwnerMgr;
229 
230  /// The default source file path.
231  UT_String myDefaultFileSource;
232 
233  /// The known sources of type definitions.
235 
236  /// Dictionary that maps an op to a definitions source managed by loader.
238 
239  /// The map from a definition metatype name (eg "struct") to a function
240  /// callback that creates an instance of VOP_TypeDefinition subclass
241  /// implementing that type.
242  VOP_TypeDefinitionFactoryMap myTypeDefinitionFactoryMap;
243 
244  /// List of deferred op tables with pending update.
245  UT_Set<OP_OperatorTable*> myDeferredUpdateTables;
246 
247  /// Nesting level of deferred update handling.
248  int myDeferUpdateCounter;
249 };
250 
251 
252 // ============================================================================
253 /// A class for to postpone reloading of VOP type definitions.
254 /// Sometimes (eg, on startup) there is a slew of HDA load events, each may
255 /// try to reload and update definitions, but reloading can be safely
256 /// performed only once, on the last update, after all HDAs are available.
257 /// An instance of this class postpones updates until it goes out of scope.
258 /// When the last instance goes out of scope, all pending updates are performed.
260 {
261 public:
264 };
265 
266 #endif
267 
virtual void templatesUpdated(OP_Operator *op)=0
UT_Functor< VOP_TypeDefinition * > VOP_TypeDefinitionFactory
GLsizei const GLchar *const * path
Definition: glcorearb.h:3341
virtual VOP_TypeDefinitionHandle getTypeDefinition(const char *type_name)
Returns a type definition provided by this source.
virtual void getSourcePath(UT_String &path) const
A class for managing the languages and custom data types in VOPs.
UT_StringMap< VOP_TypeDefinitionFactory > VOP_TypeDefinitionFactoryMap
#define VOP_API
Definition: VOP_API.h:10
constexpr std::enable_if< I< type_count_base< T >::value, int >::type tuple_type_size(){return subtype_count< typename std::tuple_element< I, T >::type >::value+tuple_type_size< T, I+1 >);}template< typename T > struct type_count< T, typename std::enable_if< is_tuple_like< T >::value >::type >{static constexpr int value{tuple_type_size< T, 0 >)};};template< typename T > struct subtype_count{static constexpr int value{is_mutable_container< T >::value?expected_max_vector_size:type_count< T >::value};};template< typename T, typename Enable=void > struct type_count_min{static const int value{0};};template< typename T >struct type_count_min< T, typename std::enable_if<!is_mutable_container< T >::value &&!is_tuple_like< T >::value &&!is_wrapper< T >::value &&!is_complex< T >::value &&!std::is_void< T >::value >::type >{static constexpr int value{type_count< T >::value};};template< typename T > struct type_count_min< T, typename std::enable_if< is_complex< T >::value >::type >{static constexpr int value{1};};template< typename T >struct type_count_min< T, typename std::enable_if< is_wrapper< T >::value &&!is_complex< T >::value &&!is_tuple_like< T >::value >::type >{static constexpr int value{subtype_count_min< typename T::value_type >::value};};template< typename T, std::size_t I >constexpr typename std::enable_if< I==type_count_base< T >::value, int >::type tuple_type_size_min(){return 0;}template< typename T, std::size_t I > constexpr typename std::enable_if< I< type_count_base< T >::value, int >::type tuple_type_size_min(){return subtype_count_min< typename std::tuple_element< I, T >::type >::value+tuple_type_size_min< T, I+1 >);}template< typename T > struct type_count_min< T, typename std::enable_if< is_tuple_like< T >::value >::type >{static constexpr int value{tuple_type_size_min< T, 0 >)};};template< typename T > struct subtype_count_min{static constexpr int value{is_mutable_container< T >::value?((type_count< T >::value< expected_max_vector_size)?type_count< T >::value:0):type_count_min< T >::value};};template< typename T, typename Enable=void > struct expected_count{static const int value{0};};template< typename T >struct expected_count< T, typename std::enable_if<!is_mutable_container< T >::value &&!is_wrapper< T >::value &&!std::is_void< T >::value >::type >{static constexpr int value{1};};template< typename T > struct expected_count< T, typename std::enable_if< is_mutable_container< T >::value >::type >{static constexpr int value{expected_max_vector_size};};template< typename T >struct expected_count< T, typename std::enable_if<!is_mutable_container< T >::value &&is_wrapper< T >::value >::type >{static constexpr int value{expected_count< typename T::value_type >::value};};enum class object_category:int{char_value=1, integral_value=2, unsigned_integral=4, enumeration=6, boolean_value=8, floating_point=10, number_constructible=12, double_constructible=14, integer_constructible=16, string_assignable=23, string_constructible=24, other=45, wrapper_value=50, complex_number=60, tuple_value=70, container_value=80,};template< typename T, typename Enable=void > struct classify_object{static constexpr object_category value{object_category::other};};template< typename T >struct classify_object< T, typename std::enable_if< std::is_integral< T >::value &&!std::is_same< T, char >::value &&std::is_signed< T >::value &&!is_bool< T >::value &&!std::is_enum< T >::value >::type >{static constexpr object_category value{object_category::integral_value};};template< typename T >struct classify_object< T, typename std::enable_if< std::is_integral< T >::value &&std::is_unsigned< T >::value &&!std::is_same< T, char >::value &&!is_bool< T >::value >::type >{static constexpr object_category value{object_category::unsigned_integral};};template< typename T >struct classify_object< T, typename std::enable_if< std::is_same< T, char >::value &&!std::is_enum< T >::value >::type >{static constexpr object_category value{object_category::char_value};};template< typename T > struct classify_object< T, typename std::enable_if< is_bool< T >::value >::type >{static constexpr object_category value{object_category::boolean_value};};template< typename T > struct classify_object< T, typename std::enable_if< std::is_floating_point< T >::value >::type >{static constexpr object_category value{object_category::floating_point};};template< typename T >struct classify_object< T, typename std::enable_if<!std::is_floating_point< T >::value &&!std::is_integral< T >::value &&std::is_assignable< T &, std::string >::value >::type >{static constexpr object_category value{object_category::string_assignable};};template< typename T >struct classify_object< T, typename std::enable_if<!std::is_floating_point< T >::value &&!std::is_integral< T >::value &&!std::is_assignable< T &, std::string >::value &&(type_count< T >::value==1)&&std::is_constructible< T, std::string >::value >::type >{static constexpr object_category value{object_category::string_constructible};};template< typename T > struct classify_object< T, typename std::enable_if< std::is_enum< T >::value >::type >{static constexpr object_category value{object_category::enumeration};};template< typename T > struct classify_object< T, typename std::enable_if< is_complex< T >::value >::type >{static constexpr object_category value{object_category::complex_number};};template< typename T > struct uncommon_type{using type=typename std::conditional<!std::is_floating_point< T >::value &&!std::is_integral< T >::value &&!std::is_assignable< T &, std::string >::value &&!std::is_constructible< T, std::string >::value &&!is_complex< T >::value &&!is_mutable_container< T >::value &&!std::is_enum< T >::value, std::true_type, std::false_type >::type;static constexpr bool value=type::value;};template< typename T >struct classify_object< T, typename std::enable_if<(!is_mutable_container< T >::value &&is_wrapper< T >::value &&!is_tuple_like< T >::value &&uncommon_type< T >::value)>::type >{static constexpr object_category value{object_category::wrapper_value};};template< typename T >struct classify_object< T, typename std::enable_if< uncommon_type< T >::value &&type_count< T >::value==1 &&!is_wrapper< T >::value &&is_direct_constructible< T, double >::value &&is_direct_constructible< T, int >::value >::type >{static constexpr object_category value{object_category::number_constructible};};template< typename T >struct classify_object< T, typename std::enable_if< uncommon_type< T >::value &&type_count< T >::value==1 &&!is_wrapper< T >::value &&!is_direct_constructible< T, double >::value &&is_direct_constructible< T, int >::value >::type >{static constexpr object_category value{object_category::integer_constructible};};template< typename T >struct classify_object< T, typename std::enable_if< uncommon_type< T >::value &&type_count< T >::value==1 &&!is_wrapper< T >::value &&is_direct_constructible< T, double >::value &&!is_direct_constructible< T, int >::value >::type >{static constexpr object_category value{object_category::double_constructible};};template< typename T >struct classify_object< T, typename std::enable_if< is_tuple_like< T >::value &&((type_count< T >::value >=2 &&!is_wrapper< T >::value)||(uncommon_type< T >::value &&!is_direct_constructible< T, double >::value &&!is_direct_constructible< T, int >::value)||(uncommon_type< T >::value &&type_count< T >::value >=2))>::type >{static constexpr object_category value{object_category::tuple_value};};template< typename T > struct classify_object< T, typename std::enable_if< is_mutable_container< T >::value >::type >{static constexpr object_category value{object_category::container_value};};template< typename T, enable_if_t< classify_object< T >::value==object_category::char_value, detail::enabler >=detail::dummy >constexpr const char *type_name(){return"CHAR";}template< typename T, enable_if_t< classify_object< T >::value==object_category::integral_value||classify_object< T >::value==object_category::integer_constructible, detail::enabler >=detail::dummy >constexpr const char *type_name(){return"INT";}template< typename T, enable_if_t< classify_object< T >::value==object_category::unsigned_integral, detail::enabler >=detail::dummy >constexpr const char *type_name(){return"UINT";}template< typename T, enable_if_t< classify_object< T >::value==object_category::floating_point||classify_object< T >::value==object_category::number_constructible||classify_object< T >::value==object_category::double_constructible, detail::enabler >=detail::dummy >constexpr const char *type_name(){return"FLOAT";}template< typename T, enable_if_t< classify_object< T >::value==object_category::enumeration, detail::enabler >=detail::dummy >constexpr const char *type_name(){return"ENUM";}template< typename T, enable_if_t< classify_object< T >::value==object_category::boolean_value, detail::enabler >=detail::dummy >constexpr const char *type_name(){return"BOOLEAN";}template< typename T, enable_if_t< classify_object< T >::value==object_category::complex_number, detail::enabler >=detail::dummy >constexpr const char *type_name(){return"COMPLEX";}template< typename T, enable_if_t< classify_object< T >::value >=object_category::string_assignable &&classify_object< T >::value<=object_category::other, detail::enabler >=detail::dummy >constexpr const char *type_name(){return"TEXT";}template< typename T, enable_if_t< classify_object< T >::value==object_category::tuple_value &&type_count_base< T >::value >=2, detail::enabler >=detail::dummy >std::string type_name();template< typename T, enable_if_t< classify_object< T >::value==object_category::container_value||classify_object< T >::value==object_category::wrapper_value, detail::enabler >=detail::dummy >std::string type_name();template< typename T, enable_if_t< classify_object< T >::value==object_category::tuple_value &&type_count_base< T >::value==1, detail::enabler >=detail::dummy >inline std::string type_name(){return type_name< typename std::decay< typename std::tuple_element< 0, T >::type >::type >);}template< typename T, std::size_t I >inline typename std::enable_if< I==type_count_base< T >::value, std::string >::type tuple_name(){return std::string{};}template< typename T, std::size_t I >inline typename std::enable_if<(I< type_count_base< T >::value), std::string >::type tuple_name(){auto str=std::string{type_name< typename std::decay< typename std::tuple_element< I, T >::type >::type >)}+ ','+tuple_name< T, I+1 >);if(str.back()== ',') str.pop_back();return str;}template< typename T, enable_if_t< classify_object< T >::value==object_category::tuple_value &&type_count_base< T >::value >=2, detail::enabler > > std::string type_name()
Recursively generate the tuple type name.
Definition: CLI11.h:1729
GLsizei GLsizei GLchar * source
Definition: glcorearb.h:803
virtual void tableUpdated(OP_OperatorTable *table)=0
OIIO_UTIL_API bool exists(string_view path) noexcept
GLenum GLenum GLsizei void * table
Definition: glad.h:5129
UT_SharedPtr< const VOP_Language > VOP_LanguageHandle
Definition: VOP_Language.h:205
A class for handling files and HDAs as sources of vop type definitions.
virtual VOP_LanguageHandle getLanguageDefinition(const char *language_name)
Returns a language definition provided by this source.
Class to store JSON objects as C++ objects.
Definition: UT_JSONValue.h:99
virtual void operatorDeleted(OP_Operator *op)
Definition: OP_Operator.h:954
Represents a source of vop type definitions saved in files or inside HDAs.
UT_SharedPtr< const VOP_TypeDefinition > VOP_TypeDefinitionHandle
Define a handle for the type definition objects.
GLenum src
Definition: glcorearb.h:1793