1 // Copyright 2009-2020 Intel Corporation
2 // SPDX-License-Identifier: Apache-2.0
3 
4 #pragma once
5 
6 #include "rkcommon/utility/Any.h"
7 #include "rkcommon/utility/Optional.h"
8 #include "rkcommon/utility/ParameterizedObject.h"
9 // ospray
10 #include "./OSPCommon.h"
11 // stl
12 #include <set>
13 #include <vector>
14 
15 namespace ospray {
16 
17 struct Data;
18 template <typename T, int DIM>
19 struct DataT;
20 
21 struct OSPRAY_SDK_INTERFACE ManagedObject : public memory::RefCount,
22                                             public utility::ParameterizedObject
23 {
24   using OSP_PTR = ManagedObject *;
25 
26   ManagedObject() = default;
27 
28   virtual ~ManagedObject() override;
29 
30   virtual void commit();
31 
32   virtual std::string toString() const;
33 
34   void *getIE() const;
35 
36   template <typename T>
37   T getParam(const char *name, T valIfNotFound = T());
38 
39   template <typename T>
40   inline utility::Optional<T> getOptParam(const char *name);
41 
42   ManagedObject *getParamObject(
43       const char *name, ManagedObject *valIfNotFound = nullptr);
44 
45   template <typename T, int DIM = 1>
46   const Ref<const DataT<T, DIM>> getParamDataT(
47       const char *name, bool required = false, bool promoteScalar = false);
48 
49   void checkUnused();
50 
51   virtual box3f getBounds() const;
52 
53   // Data members //
54 
55   void *ispcEquivalent{nullptr};
56   OSPDataType managedObjectType{OSP_OBJECT};
57 
58  private:
59   template <typename T>
60   inline bool checkObjType(T, OSPDataType);
61 };
62 
63 OSPTYPEFOR_SPECIALIZATION(ManagedObject *, OSP_OBJECT);
64 
65 // Inlined ManagedObject definitions ////////////////////////////////////////
66 
67 inline void *ManagedObject::getIE() const
68 {
69   return ispcEquivalent;
70 }
71 
72 template <typename T>
73 inline T ManagedObject::getParam(const char *name, T valIfNotFound)
74 {
75   return ParameterizedObject::getParam<T>(name, valIfNotFound);
76 }
77 
78 template <typename T>
79 inline bool ManagedObject::checkObjType(T, OSPDataType)
80 {
81   return true;
82 };
83 
84 template <>
85 inline bool ManagedObject::checkObjType(ManagedObject *o, OSPDataType t)
86 {
87   return o->managedObjectType == t;
88 };
89 
90 template <typename T>
91 inline utility::Optional<T> ManagedObject::getOptParam(const char *name)
92 {
93   utility::Optional<T> retval;
94   Param *param = findParam(name);
95   // objects are always set as ManagedObject*, retrieve as such
96   using S =
97       typename std::conditional<std::is_convertible<T, ManagedObject *>::value,
98           ManagedObject *,
99           T>::type;
100   if (param && param->data.is<S>()) {
101     auto val = param->data.get<S>();
102     if (checkObjType(val, OSPTypeFor<T>::value)) {
103       retval = (T)val;
104       param->query = true;
105     }
106   }
107   return retval;
108 }
109 
110 template <>
111 inline Data *ManagedObject::getParam<Data *>(
112     const char *name, Data *valIfNotFound)
113 {
114   auto *obj = ParameterizedObject::getParam<ManagedObject *>(
115       name, (ManagedObject *)valIfNotFound);
116   if (obj && obj->managedObjectType == OSP_DATA)
117     return (Data *)obj;
118   else {
119     // reset query status if object is not a Data*
120     if (obj)
121       findParam(name)->query = false;
122     return valIfNotFound;
123   }
124 }
125 
126 } // namespace ospray
127 
128 // Specializations for ISPCDevice /////////////////////////////////////////////
129 
130 namespace rkcommon {
131 namespace utility {
132 
133 template <>
134 inline void ParameterizedObject::Param::set(
135     const ospray::ManagedObject::OSP_PTR &object)
136 {
137   using OSP_PTR = ospray::ManagedObject::OSP_PTR;
138 
139   if (object)
140     object->refInc();
141 
142   if (data.is<OSP_PTR>()) {
143     auto *existingObj = data.get<OSP_PTR>();
144     if (existingObj != nullptr)
145       existingObj->refDec();
146   }
147 
148   data = object;
149 }
150 
151 } // namespace utility
152 } // namespace rkcommon
153