1 //
2 // Copyright 2019 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 
25 #include "pxr/pxr.h"
26 #include "pxr/usd/pcp/dynamicFileFormatInterface.h"
27 #include "pxr/usd/pcp/dynamicFileFormatDependencyData.h"
28 #include "pxr/usd/sdf/fileFormat.h"
29 #include "pxr/base/vt/value.h"
30 
31 PXR_NAMESPACE_OPEN_SCOPE
32 
PcpDynamicFileFormatDependencyData(const PcpDynamicFileFormatDependencyData & other)33 PcpDynamicFileFormatDependencyData::PcpDynamicFileFormatDependencyData(
34     const PcpDynamicFileFormatDependencyData &other)
35 {
36     // Have to copy the contents of the unique pointer if it's non-null.
37     if (other._data) {
38         _data.reset(new _Data(*other._data));
39     }
40 }
41 
42 void
AddDependencyContext(const PcpDynamicFileFormatInterface * dynamicFileFormat,VtValue && dependencyContextData,TfToken::Set && composedFieldNames)43 PcpDynamicFileFormatDependencyData::AddDependencyContext(
44     const PcpDynamicFileFormatInterface *dynamicFileFormat,
45     VtValue &&dependencyContextData,
46     TfToken::Set &&composedFieldNames)
47 {
48     // Create the data now if it was empty before this call..
49     if (!_data) {
50         _data.reset(new _Data());
51     }
52 
53     // Add file format and context data to the list and update the list of
54     // relevant fields.
55     _data->dependencyContexts.emplace_back(
56         dynamicFileFormat, std::move(dependencyContextData));
57     _data->_AddRelevantFieldNames(std::move(composedFieldNames));
58 }
59 
60 void
AppendDependencyData(PcpDynamicFileFormatDependencyData && dependencyData)61 PcpDynamicFileFormatDependencyData::AppendDependencyData(
62     PcpDynamicFileFormatDependencyData &&dependencyData)
63 {
64     if (!dependencyData._data) {
65         return;
66     }
67     // If we have our own data we need to append, otherwise we can just take
68     // the other dependency data wholesale.
69     if (_data) {
70         // Take each context from the other data and add it to ours.
71         for (_Data::_ContextData &contextData :
72                 dependencyData._data->dependencyContexts) {
73             _data->dependencyContexts.emplace_back(std::move(contextData));
74         }
75         // Add the other data's relevants fields to ours as well.
76         _data->_AddRelevantFieldNames(
77             std::move(dependencyData._data->relevantFieldNames));
78     } else {
79         Swap(dependencyData);
80     }
81 }
82 
83 bool
CanFieldChangeAffectFileFormatArguments(const TfToken & fieldName,const VtValue & oldValue,const VtValue & newValue) const84 PcpDynamicFileFormatDependencyData::CanFieldChangeAffectFileFormatArguments(
85     const TfToken &fieldName,
86     const VtValue& oldValue,
87     const VtValue& newValue) const
88 {
89     if (!_data) {
90         return false;
91     }
92 
93     // Early out if this particular field wasn't composed for this dependency.
94     if (_data->relevantFieldNames.count(fieldName) == 0) {
95         return false;
96     }
97 
98     // Check each dependency context.
99     for (const _Data::_ContextData &contextData : _data->dependencyContexts) {
100         // We better not have logged a dependency for a file format that doesn't
101         // support dynamic arguments.
102         if (!TF_VERIFY(contextData.first)) {
103             continue;
104         }
105 
106         // Return true if any context's file format can be affect by this
107         // field change.
108         if (contextData.first->CanFieldChangeAffectFileFormatArguments(
109                 fieldName, oldValue, newValue, contextData.second)) {
110             return true;
111         }
112     }
113     return false;
114 }
115 
116 const TfToken::Set &
GetRelevantFieldNames() const117 PcpDynamicFileFormatDependencyData::GetRelevantFieldNames() const
118 {
119     static const TfToken::Set empty;
120     return _data ? _data->relevantFieldNames : empty;
121 }
122 
123 void
_AddRelevantFieldNames(TfToken::Set && fieldNames)124 PcpDynamicFileFormatDependencyData::_Data::_AddRelevantFieldNames(
125     TfToken::Set &&fieldNames)
126 {
127     // Avoid copying if our current relevant fields list is empty.
128     if (relevantFieldNames.empty()) {
129         relevantFieldNames.swap(fieldNames);
130     } else {
131         relevantFieldNames.insert(fieldNames.begin(), fieldNames.end());
132     }
133 }
134 
135 PXR_NAMESPACE_CLOSE_SCOPE
136