-
Notifications
You must be signed in to change notification settings - Fork 10
/
Copy pathUsdBaseObject.h
197 lines (164 loc) · 5.95 KB
/
UsdBaseObject.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
// Copyright 2020 The Khronos Group
// SPDX-License-Identifier: Apache-2.0
#pragma once
#include "helium/utility/IntrusivePtr.h"
#include "UsdCommonMacros.h"
#include "UsdParameterizedObject.h"
class UsdDevice;
// Base parameterized class without being derived as such - nontemplated to allow for polymorphic use
class UsdBaseObject : public helium::RefCounted
{
public:
// If device != 0, the object is added to the commit list
UsdBaseObject(ANARIDataType t, UsdDevice* device = nullptr);
virtual void filterSetParam(
const char *name,
ANARIDataType type,
const void *mem,
UsdDevice* device) = 0;
virtual void filterResetParam(
const char *name) = 0;
virtual void resetAllParams() = 0;
virtual void* getParameter(const char* name, ANARIDataType& returnType) = 0;
virtual int getProperty(const char *name,
ANARIDataType type,
void *mem,
uint64_t size,
UsdDevice* device) = 0;
virtual void commit(UsdDevice* device) = 0;
virtual void remove(UsdDevice* device) = 0; // Remove any committed data and refs
ANARIDataType getType() const { return type; }
void addObserver(UsdBaseObject* observer);
void removeObserver(UsdBaseObject* observer);
void notify(UsdBaseObject* caller, UsdDevice* device);
virtual void observe(UsdBaseObject* caller, UsdDevice* device) {}
protected:
virtual bool deferCommit(UsdDevice* device) = 0; // Returns whether data commit has to be deferred
virtual bool doCommitData(UsdDevice* device) = 0; // Data commit, execution can be immediate, returns whether doCommitRefs has to be performed
virtual void doCommitRefs(UsdDevice* device) = 0; // For updates with dependencies on referenced object's data, is always executed deferred
ANARIDataType type;
friend class UsdDevice;
std::vector<UsdBaseObject*> observers;
};
void UsdBridgeAddToCommitList(UsdDevice* device, UsdBaseObject* object, bool commitData); // Helper function to suppress compiler warnings
// Templated base implementation of parameterized object
template<typename T, typename D>
class UsdParameterizedBaseObject : public UsdBaseObject, public UsdParameterizedObject<T, D>
{
public:
typedef UsdParameterizedObject<T, D> ParamClass;
UsdParameterizedBaseObject(ANARIDataType t, UsdDevice* device = nullptr)
: UsdBaseObject(t, device)
{}
void filterSetParam(
const char *name,
ANARIDataType type,
const void *mem,
UsdDevice* device) override
{
ParamClass::setParam(name, type, mem, device);
}
void filterResetParam(
const char *name) override
{
ParamClass::resetParam(name);
}
void resetAllParams() override
{
ParamClass::resetParams();
}
void* getParameter(const char* name, ANARIDataType& returnType) override
{
return ParamClass::getParam(name, returnType);
}
int getProperty(const char *name,
ANARIDataType type,
void *mem,
uint64_t size,
UsdDevice* device) override
{
return 0;
}
void commit(UsdDevice* device) override
{
ParamClass::transferWriteToReadParams();
UsdBaseObject::commit(device);
}
// Convenience functions for commonly used name property
virtual const char* getName() const { return ""; }
protected:
void onParamRefChanged(UsdBaseObject* paramObject, bool incRef, bool onWriteParams) override
{
// Only observe arrays that have actually been committed, so !onWriteParams
if(!onWriteParams && anari::isArray(paramObject->getType()))
{
if(incRef)
paramObject->addObserver(this);
else
paramObject->removeObserver(this);
}
}
void observe(UsdBaseObject* caller, UsdDevice* device) override
{
if(anari::isArray(caller->getType()))
{
UsdBridgeAddToCommitList(device, this, true); // No write to read params; just write to USD
ParamClass::paramChanged = true;
}
}
// Convenience functions for commonly used name property
bool setNameParam(const char *name,
ANARIDataType type,
const void *mem,
UsdDevice* device)
{
const char* objectName = static_cast<const char*>(mem);
if (type == ANARI_STRING)
{
if (strEquals(name, "name"))
{
if (!objectName || strEquals(objectName, ""))
{
reportStatusThroughDevice(UsdLogInfo(device, this, ANARI_OBJECT, nullptr), ANARI_SEVERITY_WARNING, ANARI_STATUS_NO_ERROR,
"%s: ANARI object %s cannot be an empty string, using auto-generated name instead.", getName(), "name");
}
else
{
ParamClass::setParam(name, type, mem, device);
ParamClass::setParam("usd::name", type, mem, device);
this->formatUsdName(this->getWriteParams().usdName);
}
return true;
}
else if (strEquals(name, "usd::name"))
{
reportStatusThroughDevice(UsdLogInfo(device, this, ANARI_OBJECT, nullptr), ANARI_SEVERITY_WARNING, ANARI_STATUS_NO_ERROR,
"%s parameter '%s' cannot be set, only read with getProperty().", getName(), "usd::name");
return true;
}
}
return false;
}
int getNameProperty(const char *name,
ANARIDataType type,
void *mem,
uint64_t size,
UsdDevice* device)
{
if (type == ANARI_STRING && strEquals(name, "usd::name"))
{
snprintf((char*)mem, size, "%s", UsdSharedString::c_str(this->getReadParams().usdName));
return 1;
}
else if (type == ANARI_UINT64 && strEquals(name, "usd::name.size"))
{
if (Assert64bitStringLengthProperty(size, UsdLogInfo(device, this, ANARI_ARRAY, this->getName()), "usd::name.size"))
{
uint64_t nameLen = this->getReadParams().usdName ? strlen(this->getReadParams().usdName->c_str())+1 : 0;
memcpy(mem, &nameLen, size);
}
return 1;
}
return 0;
}
};