SMTK  @SMTK_VERSION@
Simulation Modeling Tool Kit
Operation.h
1 //=========================================================================
2 // Copyright (c) Kitware, Inc.
3 // All rights reserved.
4 // See LICENSE.txt for details.
5 //
6 // This software is distributed WITHOUT ANY WARRANTY; without even
7 // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
8 // PURPOSE. See the above copyright notice for more information.
9 //=========================================================================
10 #ifndef smtk_operation_Operation_h
11 #define smtk_operation_Operation_h
12 
13 #include "smtk/resource/Lock.h"
14 
15 #include "smtk/PublicPointerDefs.h"
16 #include "smtk/SharedFromThis.h"
17 #include "smtk/common/Deprecation.h"
18 
19 #include <functional>
20 #include <map>
21 #include <string>
22 #include <typeindex>
23 #include <utility>
24 
25 namespace smtk
26 {
27 namespace attribute
28 {
29 class Attribute;
30 class Resource;
31 } // namespace attribute
32 namespace io
33 {
34 class Logger;
35 }
36 namespace operation
37 {
38 class Helper;
39 
40 class ImportPythonOperation;
41 class Manager;
42 class Operation;
43 
44 using Handler = std::function<void(Operation&, const std::shared_ptr<smtk::attribute::Attribute>&)>;
45 
47 using ResourceAccessMap = std::map<
48  std::weak_ptr<smtk::resource::Resource>,
49  smtk::resource::LockType,
50  std::owner_less<std::weak_ptr<smtk::resource::Resource>>>;
51 
62 class SMTKCORE_EXPORT Operation : smtkEnableSharedPtr(Operation)
63 {
64  friend class Helper;
65 
66 public:
68 
69  // A hash value uniquely representing the operation.
70  typedef std::size_t Index;
71 
72  // An attribute describing the operation's input.
73  typedef std::shared_ptr<smtk::attribute::Attribute> Parameters;
74 
75  // An attribute containing the operation's result.
76  typedef std::shared_ptr<smtk::attribute::Attribute> Result;
77 
78  // An attribute resource containing the operation's execution definition
79  // result definition.
80  typedef std::shared_ptr<smtk::attribute::Resource> Specification;
81 
82  typedef std::shared_ptr<smtk::attribute::Definition> Definition;
83 
84  // These values are taken on by the "outcome" item of every Operation Result.
85  enum class Outcome
86  {
87  UNABLE_TO_OPERATE,
88  CANCELED,
89  FAILED,
90  SUCCEEDED,
91  UNKNOWN = -1
92  };
93 
94  friend Manager;
95  friend ImportPythonOperation;
96 
97  virtual ~Operation();
98 
99  // Index is a compile-time intrinsic of the derived operation; as such, it
100  // cannot be set. It is virtual so that derived operations can assign their
101  // own index (as is necessary for python operations that would otherwise all
102  // resolve to the same index).
103  virtual Index index() const { return std::type_index(typeid(*this)).hash_code(); }
104 
127  virtual bool configure(
129  const smtk::attribute::ItemPtr& changedItem = smtk::attribute::ItemPtr());
130 
134  virtual bool ableToOperate();
135 
138  Result operate();
139 
154  Outcome safeOperate();
155  Outcome safeOperate(Handler handler);
156 
165  virtual bool releaseResult(Result& result);
166 
170  virtual smtk::io::Logger& log() const;
171 
176  Specification specification();
177 
181  Parameters parameters();
182  Parameters parameters() const;
183 
186  Result createResult(Outcome);
187 
189  ManagerPtr manager() const { return m_manager.lock(); }
190 
192  bool restoreTrace(const std::string& trace);
193 
195  void setManagers(const std::shared_ptr<smtk::common::Managers>& m) { m_managers = m; }
196  std::shared_ptr<smtk::common::Managers> managers() const { return m_managers; }
197 
199  virtual bool threadSafe() const { return true; }
200 
202  smtk::resource::ManagerPtr resourceManager();
203 
206  {
209  SkipLocks
210  };
211 
217  {
219  SkipObservers
220  };
221 
225  {
227  SkipValidation
228  };
229 
230 protected:
231  Operation();
232 
237  virtual ResourceAccessMap identifyLocksRequired();
238 
240  const ResourceAccessMap& lockedResources() const { return this->m_lockedResources; }
241 
243  virtual Result operateInternal() = 0;
244 
245  // Apply post-processing to the result object. This method should not modify
246  // the modeling kernel but may change string/float/int properties stored on
247  // entities.
248  virtual void postProcessResult(Result&) {}
249 
250  // Mark resources as dirty or clean according to their use in the operation.
251  // By default, all resources used as inputs with Write LockTypes and all
252  // resources referenced in the result are marked dirty.
253  virtual void markModifiedResources(Result&);
254 
255  // Remove resources from the resource manager.
256  virtual bool unmanageResources(Result&);
257 
258  // Append an output summary string to the output result. Derived classes can
259  // reimplement this method to send custom summary strings to the logger.
260  virtual void generateSummary(Result&);
261 
262  // Construct the operation's base specification. This is done by reading
263  // an attribute .sbt file.
264  Specification createBaseSpecification() const;
265 
266  int m_debugLevel{ 0 };
267  std::weak_ptr<Manager> m_manager;
268  std::shared_ptr<smtk::common::Managers> m_managers;
269 
275  struct BaseKey
276  {
277  BaseKey() = default;
278  BaseKey(
279  const Operation* parent,
280  ObserverOption observerOption,
281  LockOption lockOption,
282  ParametersOption paramsOption)
283  : m_parent(parent)
284  , m_lockOption(lockOption)
285  , m_observerOption(observerOption)
286  , m_paramsOption(paramsOption)
287  {
288  }
289 
290  const Operation* m_parent{ nullptr };
291  LockOption m_lockOption{ LockOption::SkipLocks };
292  ObserverOption m_observerOption{ ObserverOption::SkipObservers };
293  ParametersOption m_paramsOption{ ParametersOption::SkipValidation };
294  };
295 
296  struct SMTK_DEPRECATED_IN_24_11(
297  "Use this->childKey(ObserverOption::SkipObservers, LockOption::SkipLocks, "
298  "ParametersOption::SkipValidation) instead.") Key : BaseKey
299  {
300  Key() = default;
301  };
302 
309  BaseKey childKey(
310  ObserverOption observerOption = ObserverOption::SkipObservers,
311  LockOption lockOption = LockOption::LockAll,
312  ParametersOption paramsOption = ParametersOption::Validate) const;
313 
314 public:
316  Result operate(const BaseKey& key);
317 
318 private:
319  // Construct the operation's specification. This is typically done by reading
320  // an attribute .sbt file, but can be done by first constructing a base
321  // specification and then augmenting the specification to include the derived
322  // operation's input and output attributes.
323  virtual Specification createSpecification() = 0;
324 
325  void unlockResources(const ResourceAccessMap& resources);
326 
327  Specification m_specification;
328  Parameters m_parameters;
329  Definition m_resultDefinition;
330  std::vector<std::weak_ptr<smtk::attribute::Attribute>> m_results;
331  ResourceAccessMap m_lockedResources;
332 };
333 
339 SMTKCORE_EXPORT Operation::Outcome outcome(const Operation::Result& result);
340 SMTKCORE_EXPORT bool setOutcome(const Operation::Result& result, Operation::Outcome outcome);
341 
342 } // namespace operation
343 } // namespace smtk
344 
345 #endif // smtk_operation_Operation_h
smtk
The main namespace for the Simulation Modeling Tool Kit (SMTK).
Definition: doc.h:33
PublicPointerDefs.h
smtk::operation::Manager
An operation Manager is responsible for creating new operations and filtering operations based on inp...
Definition: Manager.h:42
smtk::operation::Operation::Outcome
Outcome
Definition: Operation.h:85
smtk::operation::Operation::lockedResources
const ResourceAccessMap & lockedResources() const
Returns the set of resources that are currently locked by this operation.
Definition: Operation.h:240
smtk::operation::ImportPythonOperation
A class for adding python operations to the current session.
Definition: ImportPythonOperation.h:27
smtk::operation::Operation::ObserverOption
ObserverOption
When running a nested operation, specify whether observers should be invoked.
Definition: Operation.h:216
smtk::operation::outcome
Operation::Outcome outcome(const Operation::Result &result)
Return the outcome of an operation given its result object.
Definition: Operation.cxx:752
smtk::operation::Operation::Validate
@ Validate
Ensure the nested operation's parameters are valid.
Definition: Operation.h:226
smtk::io::Logger
Log messages for later presentation to a user or a file.
Definition: Logger.h:94
smtkEnableSharedPtr
#define smtkEnableSharedPtr(...)
An abbreviation for enabling shared pointers.
Definition: SharedFromThis.h:234
smtk::operation::ManagerPtr
smtk::shared_ptr< smtk::operation::Manager > ManagerPtr
Definition: PublicPointerDefs.h:355
smtk::operation::ResourceAccessMap
std::map< std::weak_ptr< smtk::resource::Resource >, smtk::resource::LockType, std::owner_less< std::weak_ptr< smtk::resource::Resource > >> ResourceAccessMap
Hold a set of resources to be locked for an operation along with the type of lock to acquire.
Definition: Operation.h:50
smtk::operation::Operation::ParentLocksOnly
@ ParentLocksOnly
Use only the locks already held by this (the parent's) operation.
Definition: Operation.h:208
smtk::operation::Operation::BaseKey
A key used to run operations nested from within this operation.
Definition: Operation.h:275
smtk::operation::Operation::LockOption
LockOption
When running a nested operation, specify how resource locks should be handled.
Definition: Operation.h:205
smtk::operation::Operation
Operation is a base class for all SMTK operations.
Definition: Operation.h:62
smtk::attribute::AttributePtr
smtk::shared_ptr< smtk::attribute::Attribute > AttributePtr
Definition: PublicPointerDefs.h:463
smtk::operation::Helper
A helper for dealing with serialization/deserialization done within an operation.
Definition: Helper.h:25
smtk::plugin::Manager
smtk::common::Singleton< detail::Manager > Manager
The Manager is a singleton interface for registering available plugins to manager instances.
Definition: Manager.h:92
smtk::operation::Operation::InvokeObservers
@ InvokeObservers
Do not invoke observers for the internal/nested operation.
Definition: Operation.h:218
smtk::operation::Operation::setManagers
void setManagers(const std::shared_ptr< smtk::common::Managers > &m)
Operations may be passed application state in the form of a Managers type-container.
Definition: Operation.h:195
smtk::operation::Operation::manager
ManagerPtr manager() const
Operations that are managed have a non-null pointer to their manager.
Definition: Operation.h:189
smtk::operation::Operation::LockAll
@ LockAll
Lock all resources mentioned in the nested operation's parameters.
Definition: Operation.h:207
smtk::operation::Operation::ParametersOption
ParametersOption
When running a nested operation, specify whether to call the operation's ableToOperate() method or sk...
Definition: Operation.h:224
smtk::attribute::ItemPtr
smtk::shared_ptr< smtk::attribute::Item > ItemPtr
Definition: PublicPointerDefs.h:474
SharedFromThis.h
Macros for dealing with shared-pointer classes.
smtkTypeMacroBase
#define smtkTypeMacroBase(...)
Add typedefs to a class for identifcation.
Definition: SharedFromThis.h:151
smtk::resource::ManagerPtr
smtk::shared_ptr< smtk::resource::Manager > ManagerPtr
Definition: PublicPointerDefs.h:288
smtk::operation::Operation::threadSafe
virtual bool threadSafe() const
Is this type of operation safe to launch in a thread?
Definition: Operation.h:199