HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
UNI_Manager.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: UNI_Manager.h ( UNI Library, C++)
7  *
8  * COMMENTS:
9  *
10  */
11 
12 #ifndef __UNI_Manager_h__
13 #define __UNI_Manager_h__
14 
15 #include "UNI_API.h"
16 #include "UNI_Category.h"
17 #include <UT/UT_Function.h>
18 #include <UT/UT_NonCopyable.h>
19 #include <UT/UT_Notifier.h>
20 #include <UT/UT_IteratorRange.h>
21 #include <UT/UT_StringMap.h>
22 #include <UT/UT_StringArray.h>
23 #include <UT/UT_UniquePtr.h>
24 #include <iterator>
25 
26 #define UNI_ROOT_CATEGORY "UniNet"
27 
28 // ============================================================================
29 /// The manager of UNI graphs. It is a point of entry into the UNI framework.
30 ///
31 /// It provides information about known categories (ie, goups of node types that
32 /// work together in a domain-specific specialization context of a UNI graph).
33 /// It also provides the list of existing UNI graphs in the session.
34 ///
36 {
37 public:
38  /// Cata structure used for internal mapping of categories.
40 
41  /// @{ Constructor and destructor.
42  // Note, there is a global manger accessible thru UNImanager() function,
43  // but we allow local managers too, since there is no absolute need for
44  // singelton here. This allows using it for small scoped tasks,
45  // independent of global UNI manager framework.
46  UNI_Manager();
47  ~UNI_Manager();
48  /// @}
49 
50  /// Returns the reference to the global UNI manager, which is accessible
51  /// in a single Houdini session.
52  static UNI_Manager &get();
53 
54  /// Returns the names of the categorires the manager knows about.
55  /// @parm include_non_loaded If true the returned result includes
56  // categories that have been discovered/registered but not loaded yet.
57  UT_StringArray categoryNames( bool include_not_loaded = true ) const;
58 
59  /// A factory function that creates and returns a new category.
61 
62  /// Registers a new category factory function that returns a newly created
63  /// category by the given name.
64  void addCategoryFactory( const UT_StringRef &category_name,
65  const CategoryFactory &factory );
66 
67  /// Returns true if the manager has a factory function for the category by
68  /// the given name.
69  bool hasCategoryFactory( const UT_StringRef &category_name );
70 
71  /// @{ Returns a node category by the given name, or null if not found.
72  const UNI_Category *
73  findCategory( const UT_StringRef &category_name ) const
74  {
75  return SYSconst_cast(this)->findCategory( category_name );
76  }
77 
78  UNI_Category *
79  findCategory( const UT_StringRef &category_name )
80  {
81  auto it = myCategories.find( category_name );
82  return it != myCategories.end()
83  ? it->second.get()
84  : loadCategory( category_name );
85  }
86  /// @}
87 
88 
89  /// Iterator for traversing loaded categories.
91  {
92  public:
93  using iterator_category = std::forward_iterator_tag;
95  using difference_type = std::ptrdiff_t;
98 
100  : myIterator( underlying_it ) {}
101  bool operator ==( const CategoryIterator &other ) const
102  { return myIterator == other.myIterator; }
103  bool operator !=( const CategoryIterator &other) const
104  { return myIterator != other.myIterator; }
106  { ++myIterator; return *this; }
108  { return myIterator->get(); }
109 
110  private:
111  CategoryMap::mapped_iterator myIterator;
112  };
113 
114  /// Returns a range for iterating loaded categories.
117  {
118  auto cat_range = myCategories.mapped_range();
119  return CategoryRange( CategoryIterator(cat_range.begin()),
120  CategoryIterator(cat_range.end()));
121  }
122 
123  /// Class containing info about magager's change event.
124  class Event
125  {
126  public:
127  /// Enumeration of event types.
128  enum class Type
129  {
130  CategoryAdded, // Category added
131  CategoryRemoved // Category removed
132  };
133 
134  /// Constructor.
136  : myManager(mgr)
137  , myType(type)
138  , myName(name)
139  {}
140 
141  /// The manager issuing the event
143  { return myManager; }
144  /// Event type;
145  Type type() const
146  { return myType; }
147 
148  /// Name of added/removed category.
149  const UT_StringHolder & name() const
150  { return myName; }
151 
152  private:
153  UNI_Manager & myManager; // Manager issuing the event
154  Type myType; // The Type of the event
155  const UT_StringHolder myName; // Name of affected category
156  };
157 
158  /// Returns an object used for notifying interested parties about
159  /// changes to the known categories (adding a new or removing old one).
161  {
162  return myEventNotifier;
163  }
164 
165  /// Adds a node type to our special "root node types" category. This is
166  /// a category for all the "root" nodes of UNI_Graphs.
167  void addRootType( const UT_StringHolder &type_name,
168  const UT_StringArray &child_category_names );
169 
170 private:
171  /// Loads and returns a category by the given name.
172  /// Returns null if no factory is found for the given name.
173  UNI_Category * loadCategory( const UT_StringRef &category_name );
174 
175 private:
176  /// The node categories known to the manager.
177  /// Each category is identified by a name, on which we key the dictionary.
178  CategoryMap myCategories;
179 
180  /// Object that sends notifications about manager changes.
181  UT_NotifierImpl<const Event &> myEventNotifier;
182 
183  /// Category factory functions associated with category names.
184  UT_StringMap<CategoryFactory> myCategoryFactories;
185 };
186 
187 // ============================================================================
188 /// Returns the reference to the global UNI manager.
189 static inline UNI_Manager &
190 UNImanager()
191 {
192  return UNI_Manager::get();
193 }
194 
195 #endif
196 
partial_iterator_base< iterator, mapped_type, deref_pair_second< iterator, mapped_type >> mapped_iterator
Definition: UT_Map.h:257
UNI_Manager & manager() const
The manager issuing the event.
Definition: UNI_Manager.h:142
Event(UNI_Manager &mgr, Type type, const UT_StringRef name)
Constructor.
Definition: UNI_Manager.h:135
UNI_Category * operator*() const
Definition: UNI_Manager.h:107
CategoryRange loadedCategoryRange()
Definition: UNI_Manager.h:116
const UNI_Category * findCategory(const UT_StringRef &category_name) const
Returns a node category by the given name, or null if not found.
Definition: UNI_Manager.h:73
SYS_FORCE_INLINE T * SYSconst_cast(const T *foo)
Definition: SYS_Types.h:136
#define UNI_API
Definition: UNI_API.h:11
UT_Function< UNI_CategoryHandle()> CategoryFactory
A factory function that creates and returns a new category.
Definition: UNI_Manager.h:60
const UT_StringHolder & name() const
Name of added/removed category.
Definition: UNI_Manager.h:149
bool operator==(const BaseDimensions< T > &a, const BaseDimensions< Y > &b)
Definition: Dimensions.h:137
GLint GLint GLsizei GLint GLenum GLenum type
Definition: glcorearb.h:108
Iterator for traversing loaded categories.
Definition: UNI_Manager.h:90
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
CategoryIterator & operator++()
Definition: UNI_Manager.h:105
std::ptrdiff_t difference_type
Definition: UNI_Manager.h:95
Class containing info about magager's change event.
Definition: UNI_Manager.h:124
std::forward_iterator_tag iterator_category
Definition: UNI_Manager.h:93
GLuint const GLchar * name
Definition: glcorearb.h:786
std::function< T > UT_Function
Definition: UT_Function.h:37
static UNI_Manager & get()
Type
Enumeration of event types.
Definition: UNI_Manager.h:128
UNI_Category * findCategory(const UT_StringRef &category_name)
Returns a node category by the given name, or null if not found.
Definition: UNI_Manager.h:79
Type type() const
Event type;.
Definition: UNI_Manager.h:145
bool operator!=(const BaseDimensions< T > &a, const BaseDimensions< Y > &b)
Definition: Dimensions.h:165
UT_NotifierImpl< const Event & > & getEventNotifier()
Definition: UNI_Manager.h:160
CategoryIterator(CategoryMap::mapped_iterator underlying_it)
Definition: UNI_Manager.h:99