Usd Notice Framework  0.7.0
broker.h
Go to the documentation of this file.
1 #ifndef USD_NOTICE_FRAMEWORK_BROKER_H
2 #define USD_NOTICE_FRAMEWORK_BROKER_H
3 
5 
6 #include "unf/api.h"
7 #include "unf/capturePredicate.h"
8 #include "unf/notice.h"
9 
10 #include <pxr/base/plug/plugin.h>
11 #include <pxr/base/plug/registry.h>
12 #include <pxr/base/tf/refBase.h>
13 #include <pxr/base/tf/refPtr.h>
14 #include <pxr/base/tf/weakBase.h>
15 #include <pxr/base/tf/weakPtr.h>
16 #include <pxr/pxr.h>
17 #include <pxr/usd/usd/common.h>
18 #include <pxr/usd/usd/stage.h>
19 
20 #include <functional>
21 #include <memory>
22 #include <string>
23 #include <typeinfo>
24 #include <unordered_map>
25 #include <vector>
26 
27 namespace unf {
28 
29 class Broker;
30 class Dispatcher;
31 
34 
37 
40 
47  public:
53  UNF_API static BrokerPtr Create(const PXR_NS::UsdStageWeakPtr& stage);
54 
55  UNF_API virtual ~Broker() = default;
56 
58  UNF_API Broker(const Broker&) = delete;
59 
61  UNF_API Broker& operator=(const Broker&) = delete;
62 
64  UNF_API const PXR_NS::UsdStageWeakPtr GetStage() const { return _stage; }
65 
69  UNF_API bool IsInTransaction();
70 
89  UNF_API void BeginTransaction(
91 
112 
126  UNF_API void EndTransaction();
127 
133  template <class UnfNotice, class... Args>
134  void Send(Args&&... args);
135 
141  UNF_API void Send(const UnfNotice::StageNoticeRefPtr&);
142 
144  UNF_API DispatcherPtr& GetDispatcher(std::string identifier);
145 
150  template <class T>
151  void AddDispatcher();
152 
158  UNF_API void Reset();
159 
161  UNF_API static void ResetAll();
162 
163  private:
165 
167  static void _CleanCache();
168 
170  void _DiscoverDispatchers();
171 
173  UNF_API void _Add(const DispatcherPtr&);
174 
177  template <class T>
178  DispatcherPtr _AddDispatcher();
179 
181  template <class OutputPtr, class OutputFactory>
182  void _LoadFromPlugins(const PXR_NS::TfType& type);
183 
184  struct UsdStageWeakPtrHasher {
185  std::size_t operator()(const PXR_NS::UsdStageWeakPtr& ptr) const
186  {
187  return hash_value(ptr);
188  }
189  };
190 
192  static std::unordered_map<
193  PXR_NS::UsdStageWeakPtr, BrokerPtr, UsdStageWeakPtrHasher>
194  Registry;
195 
196  class _NoticeMerger {
197  public:
198  _NoticeMerger(CapturePredicate predicate = CapturePredicate::Default());
199 
200  void Add(const UnfNotice::StageNoticeRefPtr&);
201  void Join(_NoticeMerger&);
202  void Merge();
203  void PostProcess();
204  void Send(const PXR_NS::UsdStageWeakPtr&);
205 
206  private:
207  using _NoticePtrList = std::vector<UnfNotice::StageNoticeRefPtr>;
208  using _NoticePtrMap = std::unordered_map<std::string, _NoticePtrList>;
209 
210  _NoticePtrMap _noticeMap;
211  CapturePredicate _predicate;
212  };
213 
216 
218  std::vector<_NoticeMerger> _mergers;
219 
221  std::unordered_map<std::string, DispatcherPtr> _dispatcherMap;
222 };
223 
224 template <class UnfNotice, class... Args>
225 void Broker::Send(Args&&... args)
226 {
228  UnfNotice::Create(std::forward<Args>(args)...);
229 
230  Send(_notice);
231 }
232 
233 template <class T>
234 DispatcherPtr Broker::_AddDispatcher()
235 {
236  static_assert(
237  std::is_base_of<Dispatcher, T>::value,
238  "Expecting a type derived from unf::Dispatcher.");
239 
240  auto self = PXR_NS::TfCreateWeakPtr(this);
241  DispatcherPtr dispatcher = PXR_NS::TfCreateRefPtr(new T(self));
242  _Add(dispatcher);
243  return dispatcher;
244 }
245 
246 template <class T>
248 {
249  const auto& dispatcher = _AddDispatcher<T>();
250  dispatcher->Register();
251 }
252 
253 template <class OutputPtr, class OutputFactory>
254 void Broker::_LoadFromPlugins(const PXR_NS::TfType& type)
255 {
256  PXR_NAMESPACE_USING_DIRECTIVE
257 
258  const PXR_NS::PlugPluginPtr plugin =
259  PXR_NS::PlugRegistry::GetInstance().GetPluginForType(type);
260 
261  if (!plugin) {
262  return;
263  }
264 
265  if (!plugin->Load()) {
266  TF_CODING_ERROR(
267  "Failed to load plugin %s for %s",
268  plugin->GetName().c_str(),
269  type.GetTypeName().c_str());
270  return;
271  }
272 
273  OutputPtr output;
274  OutputFactory* factory = type.GetFactory<OutputFactory>();
275 
276  if (factory) {
277  output = factory->New(TfCreateWeakPtr(this));
278  }
279 
280  if (!output) {
281  TF_CODING_ERROR(
282  "Failed to manufacture %s from plugin %s",
283  type.GetTypeName().c_str(),
284  plugin->GetName().c_str());
285  return;
286  }
287 
288  _Add(output);
289 }
290 
291 } // namespace unf
292 
293 #endif // USD_NOTICE_FRAMEWORK_BROKER_H
Intermediate object between the Usd Stage and any clients that needs asynchronous handling and upstre...
Definition: broker.h:46
static UNF_API void ResetAll()
Un-register all brokers.
UNF_API void EndTransaction()
Stop a notice transaction.
UNF_API const PXR_NS::UsdStageWeakPtr GetStage() const
Return Usd Stage associated with the broker.
Definition: broker.h:64
void AddDispatcher()
Create and register a new dispatcher.
Definition: broker.h:247
static UNF_API BrokerPtr Create(const PXR_NS::UsdStageWeakPtr &stage)
Create a broker from a Usd Stage.
UNF_API Broker(const Broker &)=delete
Remove default copy constructor.
UNF_API void Reset()
Un-register broker.
UNF_API Broker & operator=(const Broker &)=delete
Remove default assignment operator.
UNF_API void BeginTransaction(CapturePredicate predicate=CapturePredicate::Default())
Start a notice transaction.
UNF_API bool IsInTransaction()
Indicate whether a notice transaction has been started.
UNF_API void BeginTransaction(const CapturePredicateFunc &)
Start a notice transaction with a capture predicate function.
void Send(Args &&... args)
Create and send a UnfNotice::StageNotice notice via the broker.
Definition: broker.h:225
UNF_API DispatcherPtr & GetDispatcher(std::string identifier)
Return dispatcher reference associated with identifier.
UNF_API void Send(const UnfNotice::StageNoticeRefPtr &)
Send a UnfNotice::StageNotice notice via the broker.
Predicate functor which indicates whether a notice can be captured during a transaction.
Definition: capturePredicate.h:29
static UNF_API CapturePredicate Default()
Create a predicate which return true for each notice type.
PXR_NS::TfRefPtr< StageNotice > StageNoticeRefPtr
Convenient alias for StageNotice reference pointer.
Definition: notice.h:124
PXR_NS::TfRefPtr< Broker > BrokerPtr
Convenient alias for Broker reference pointer.
Definition: broker.h:33
std::function< bool(const UnfNotice::StageNotice &)> CapturePredicateFunc
Convenient alias for function defining whether notice can be captured.
Definition: capturePredicate.h:16