HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
mapExpression.h
Go to the documentation of this file.
1 //
2 // Copyright 2016 Pixar
3 //
4 // Licensed under the Apache License, Version 2.0 (the "Apache License")
5 // with the following modification; you may not use this file except in
6 // compliance with the Apache License and the following modification to it:
7 // Section 6. Trademarks. is deleted and replaced with:
8 //
9 // 6. Trademarks. This License does not grant permission to use the trade
10 // names, trademarks, service marks, or product names of the Licensor
11 // and its affiliates, except as required to comply with Section 4(c) of
12 // the License and to reproduce the content of the NOTICE file.
13 //
14 // You may obtain a copy of the Apache License at
15 //
16 // http://www.apache.org/licenses/LICENSE-2.0
17 //
18 // Unless required by applicable law or agreed to in writing, software
19 // distributed under the Apache License with the above modification is
20 // distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
21 // KIND, either express or implied. See the Apache License for the specific
22 // language governing permissions and limitations under the Apache License.
23 //
24 #ifndef PXR_USD_PCP_MAP_EXPRESSION_H
25 #define PXR_USD_PCP_MAP_EXPRESSION_H
26 
27 #include "pxr/pxr.h"
28 #include "pxr/usd/pcp/api.h"
30 
31 #include <hboost/intrusive_ptr.hpp>
32 
33 #include <tbb/atomic.h>
34 #include <tbb/spin_mutex.h>
35 
36 #include <atomic>
37 #include <memory>
38 
40 
41 /// \class PcpMapExpression
42 ///
43 /// An expression that yields a PcpMapFunction value.
44 ///
45 /// Expressions comprise constant values, variables, and operators
46 /// applied to sub-expressions. Expressions cache their computed values
47 /// internally. Assigning a new value to a variable automatically
48 /// invalidates the cached values of dependent expressions. Common
49 /// (sub-)expressions are automatically detected and shared.
50 ///
51 /// PcpMapExpression exists solely to support efficient incremental
52 /// handling of relocates edits. It represents a tree of the namespace
53 /// mapping operations and their inputs, so we can narrowly redo the
54 /// computation when one of the inputs changes.
55 ///
57 {
58 public:
59  /// The value type of PcpMapExpression is a PcpMapFunction.
61 
62  /// Evaluate this expression, yielding a PcpMapFunction value.
63  /// The computed result is cached.
64  /// The return value is a reference to the internal cached value.
65  /// The cache is automatically invalidated as needed.
66  PCP_API
67  const Value & Evaluate() const;
68 
69  /// Default-construct a NULL expression.
70  PCP_API
72 
73  /// Swap this expression with the other.
74  PCP_API
75  void Swap(PcpMapExpression &other);
76 
77  /// Return true if this is a null expression.
78  PCP_API
79  bool IsNull() const;
80 
81  /// \name Creating expressions
82  /// @{
83 
84  /// Return an expression representing PcpMapFunction::Identity().
85  PCP_API
86  static PcpMapExpression Identity();
87 
88  /// Create a new constant.
89  PCP_API
90  static PcpMapExpression Constant( const Value & constValue );
91 
92  /// A Variable is a mutable memory cell that holds a value.
93  /// Changing a variable's value invalidates any expressions using
94  /// that variable.
95  class Variable {
96  Variable(Variable const &) = delete;
97  Variable &operator=(Variable const &) = delete;
98  public:
99  Variable() = default;
100  virtual ~Variable();
101  /// Return the current value.
102  virtual const Value & GetValue() const = 0;
103  /// Mutate the variable to have the new value.
104  /// This will also invalidate dependant expressions.
105  virtual void SetValue(Value && value) = 0;
106  /// Return an expression representing the value of this variable.
107  /// This lets you use the variable as a sub-term in other expressions.
108  virtual PcpMapExpression GetExpression() const = 0;
109  };
110 
111  /// Variables are held by reference.
112  typedef std::unique_ptr<Variable> VariableUniquePtr;
113 
114  /// Create a new variable.
115  /// The client is expected to retain the reference for as long as
116  /// it wishes to continue being able to set the value of the variable.
117  /// After the reference is dropped, expressions using the variable
118  /// will continue to be valid, but there will be no way to further
119  /// change the value of the variable.
120  PCP_API
121  static VariableUniquePtr NewVariable(Value && initialValue);
122 
123  /// Create a new PcpMapExpression representing the application of
124  /// f's value, followed by the application of this expression's value.
125  PCP_API
127 
128  /// Create a new PcpMapExpression representing the inverse of f.
129  PCP_API
130  PcpMapExpression Inverse() const;
131 
132  /// Return a new expression representing this expression with an added
133  /// (if necessary) mapping from </> to </>.
134  PCP_API
136 
137  /// Return true if the map function is the constant identity function.
138  bool IsConstantIdentity() const {
139  return _node && _node->key.op == _OpConstant &&
140  _node->key.valueForConstant.IsIdentity();
141  }
142 
143  /// @}
144 
145  /// \name Convenience API
146  /// The following API just forwards through to the underlying evaluated
147  /// mapfunction value.
148  /// @{
149 
150  /// Return true if the evaluated map function is the identity function.
151  /// For identity, MapSourceToTarget() always returns the path unchanged.
152  bool IsIdentity() const {
153  return Evaluate().IsIdentity();
154  }
155 
156  /// Map a path in the source namespace to the target.
157  /// If the path is not in the domain, returns an empty path.
159  return Evaluate().MapSourceToTarget(path);
160  }
161 
162  /// Map a path in the target namespace to the source.
163  /// If the path is not in the co-domain, returns an empty path.
165  return Evaluate().MapTargetToSource(path);
166  }
167 
168  /// The time offset of the mapping.
169  const SdfLayerOffset &GetTimeOffset() const {
170  return Evaluate().GetTimeOffset();
171  }
172 
173  /// Returns a string representation of this mapping for debugging
174  /// purposes.
176  return Evaluate().GetString();
177  }
178 
179  /// @}
180 
181 private:
182  // Allow Pcp_Statistics access to internal data for diagnostics.
183  friend class Pcp_Statistics;
184  friend struct Pcp_VariableImpl;
185 
186  class _Node;
187  typedef hboost::intrusive_ptr<_Node> _NodeRefPtr;
188 
189  explicit PcpMapExpression(const _NodeRefPtr & node) : _node(node) {}
190 
191 private: // data
192  enum _Op {
193  _OpConstant,
194  _OpVariable,
195  _OpInverse,
196  _OpCompose,
197  _OpAddRootIdentity
198  };
199 
200  class _Node : public hboost::noncopyable {
201  public:
202  // The Key holds all the state needed to uniquely identify
203  // this (sub-)expression.
204  struct Key {
205  const _Op op;
206  const _NodeRefPtr arg1, arg2;
208 
209  Key( _Op op_,
210  const _NodeRefPtr & arg1_,
211  const _NodeRefPtr & arg2_,
212  const Value & valueForConstant_ )
213  : op(op_)
214  , arg1(arg1_)
215  , arg2(arg2_)
216  , valueForConstant(valueForConstant_)
217  {}
218  inline size_t GetHash() const;
219  bool operator==(const Key &key) const;
220  };
221 
222  // The Key of a node is const, and established when it is created.
223  const Key key;
224 
225  // Whether or not the expression tree up to and including this node
226  // will always include an identity mapping.
227  const bool expressionTreeAlwaysHasIdentity;
228 
229  // Factory method to create new nodes.
230  static _NodeRefPtr
231  New( _Op op,
232  const _NodeRefPtr & arg1 = _NodeRefPtr(),
233  const _NodeRefPtr & arg2 = _NodeRefPtr(),
234  const Value & valueForConstant = Value() );
235  ~_Node();
236 
237  // Evaluate (and internally cache) the value of this node.
238  const Value & EvaluateAndCache() const;
239 
240  // For _OpVariable nodes, sets the variable's value.
241  void SetValueForVariable(Value &&newValue);
242 
243  // For _OpVariable nodes, returns the variable's value.
244  const Value & GetValueForVariable() const {
245  return _valueForVariable;
246  }
247 
248  private:
249  explicit _Node( const Key &key_ );
250  void _Invalidate();
251  Value _EvaluateUncached() const;
252 
253  // Helper to determine if the expression tree indicated by key
254  // will always contains the root identity.
255  static bool _ExpressionTreeAlwaysHasIdentity(const Key& key);
256 
257  // Ref-counting ops manage _refCount.
258  // Need to friend them here to have access to _refCount.
259  friend PCP_API void intrusive_ptr_add_ref(_Node*);
260  friend PCP_API void intrusive_ptr_release(_Node*);
261 
262  // Registry of node instances, identified by Key.
263  // Note: variable nodes are not tracked by the registry.
264  struct _NodeMap;
265  static TfStaticData<_NodeMap> _nodeRegistry;
266 
267  mutable tbb::atomic<int> _refCount;
268  mutable Value _cachedValue;
269  mutable std::set<_Node*> _dependentExpressions;
270  Value _valueForVariable;
271  mutable tbb::spin_mutex _mutex;
272  mutable std::atomic<bool> _hasCachedValue;
273  };
274 
275  // Need to friend them here to have visibility to private class _Node.
276  friend PCP_API void intrusive_ptr_add_ref(_Node*);
277  friend PCP_API void intrusive_ptr_release(_Node*);
278 
279  _NodeRefPtr _node;
280 };
281 
283 
284 #endif // PXR_USD_PCP_MAP_EXPRESSION_H
Key(_Op op_, const _NodeRefPtr &arg1_, const _NodeRefPtr &arg2_, const Value &valueForConstant_)
PcpMapFunction Value
The value type of PcpMapExpression is a PcpMapFunction.
Definition: mapExpression.h:60
friend struct Pcp_VariableImpl
static PCP_API VariableUniquePtr NewVariable(Value &&initialValue)
PCP_API void Swap(PcpMapExpression &other)
Swap this expression with the other.
bool IsConstantIdentity() const
Return true if the map function is the constant identity function.
PCP_API PcpMapExpression()
Default-construct a NULL expression.
PCP_API bool IsNull() const
Return true if this is a null expression.
PCP_API bool IsIdentity() const
static PCP_API PcpMapExpression Identity()
Return an expression representing PcpMapFunction::Identity().
PCP_API PcpMapExpression Compose(const PcpMapExpression &f) const
GLsizei const GLchar *const * path
Definition: glcorearb.h:3340
PCP_API SdfPath MapSourceToTarget(const SdfPath &path) const
GLuint GLuint GLuint GLuint GLuint GLuint arg2
Definition: glew.h:8296
PCP_API PcpMapExpression AddRootIdentity() const
virtual const Value & GetValue() const =0
Return the current value.
friend PCP_API void intrusive_ptr_add_ref(_Node *)
const SdfLayerOffset & GetTimeOffset() const
The time offset of the mapping.
Definition: mapFunction.h:170
virtual PcpMapExpression GetExpression() const =0
SdfPath MapTargetToSource(const SdfPath &path) const
std::string GetString() const
const SdfLayerOffset & GetTimeOffset() const
The time offset of the mapping.
GLsizei const GLchar *const * string
Definition: glcorearb.h:813
SdfPath MapSourceToTarget(const SdfPath &path) const
virtual void SetValue(Value &&value)=0
std::unique_ptr< Variable > VariableUniquePtr
Variables are held by reference.
Definition: path.h:288
PCP_API const Value & Evaluate() const
bool operator==(const Key &key) const
bool IsIdentity() const
PCP_API PcpMapExpression Inverse() const
Create a new PcpMapExpression representing the inverse of f.
PXR_NAMESPACE_CLOSE_SCOPE PXR_NAMESPACE_OPEN_SCOPE
Definition: path.h:1375
GLuint GLuint GLuint arg1
Definition: glew.h:8295
#define PXR_NAMESPACE_CLOSE_SCOPE
Definition: pxr.h:91
GLsizei const GLfloat * value
Definition: glcorearb.h:823
GLfloat f
Definition: glcorearb.h:1925
friend PCP_API void intrusive_ptr_release(_Node *)
PCP_API std::string GetString() const
PCP_API SdfPath MapTargetToSource(const SdfPath &path) const
static PCP_API PcpMapExpression Constant(const Value &constValue)
Create a new constant.
friend class Pcp_Statistics
#define PCP_API
Definition: api.h:40