1 //
2 // Copyright 2016 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 #ifndef PXR_USD_SDF_LAYER_REGISTRY_H
25 #define PXR_USD_SDF_LAYER_REGISTRY_H
26 
27 /// \file sdf/layerRegistry.h
28 
29 #include "pxr/pxr.h"
30 #include "pxr/usd/sdf/declareHandles.h"
31 #include "pxr/base/tf/hash.h"
32 
33 #include <boost/multi_index_container.hpp>
34 #include <boost/multi_index/hashed_index.hpp>
35 #include <boost/multi_index/identity.hpp>
36 #include <boost/noncopyable.hpp>
37 
38 #include <string>
39 #include <iosfwd>
40 
41 PXR_NAMESPACE_OPEN_SCOPE
42 
43 SDF_DECLARE_HANDLES(SdfLayer);
44 
45 /// \class Sdf_LayerRegistry
46 ///
47 /// A class that provides functionality to look up layers by asset path that
48 /// are tracked by the registry. Currently, when a new SdfLayer is created, it
49 /// is inserted into the layer registry. This allows SdfLayer::Find/FindOrOpen
50 /// to locate loaded layers.
51 ///
52 class Sdf_LayerRegistry : boost::noncopyable
53 {
54 public:
55     /// Constructor.
56     Sdf_LayerRegistry();
57 
58     /// Inserts layer into the registry, or updates an existing registry entry
59     /// if an entry is found for the same layer.
60     void InsertOrUpdate(const SdfLayerHandle& layer);
61 
62     /// Erases the layer from the registry, if found.
63     void Erase(const SdfLayerHandle& layer);
64 
65     /// Returns a layer from the registry, searching first by identifier using
66     /// FindByIdentifier, then by real path using FindByRealPath. If the layer
67     /// cannot be found, a null layer handle is returned. If the \p layerPath
68     /// is relative, it is made absolute by anchoring to the current working
69     /// directory.
70     SdfLayerHandle Find(const std::string &layerPath,
71                         const std::string &resolvedPath=std::string()) const;
72 
73     /// Returns a layer from the registry, consulting the by_identifier index
74     /// with the \p layerPath as provided.
75     SdfLayerHandle FindByIdentifier(const std::string& layerPath) const;
76 
77     /// Returns a layer from the registry, consulting the by_repository_path index
78     /// with the \p layerPath as provided.
79     SdfLayerHandle FindByRepositoryPath(const std::string& layerPath) const;
80 
81     /// Returns a layer from the registry, consulting the by_real_path index.
82     /// If \p layerPath is an absolute file system path, the index is searched
83     /// using the input path. Otherwise, \p layerPath is resolved and the
84     /// resulting path is used to search the index.
85     SdfLayerHandle FindByRealPath(
86         const std::string& layerPath,
87         const std::string& resolvedPath=std::string()) const;
88 
89     /// Returns all valid layers held in the registry as a set.
90     SdfLayerHandleSet GetLayers() const;
91 
92 private:
93     // Index tags.
94     struct by_identity {};
95     struct by_identifier {};
96     struct by_repository_path {};
97     struct by_real_path {};
98 
99     // Key Extractors.
100     struct layer_identifier {
101         typedef std::string result_type;
102         const result_type& operator()(const SdfLayerHandle& layer) const;
103     };
104 
105     struct layer_repository_path {
106         typedef std::string result_type;
107         result_type operator()(const SdfLayerHandle& layer) const;
108     };
109 
110     struct layer_real_path {
111         typedef std::string result_type;
112         result_type operator()(const SdfLayerHandle& layer) const;
113     };
114 
115     // Unordered associative layer container.
116     typedef boost::multi_index::multi_index_container<
117         SdfLayerHandle,
118         boost::multi_index::indexed_by<
119             // Layer<->Layer, one-to-one. Duplicate layer handles cannot be
120             // inserted into the container.
121             boost::multi_index::hashed_unique<
122                 boost::multi_index::tag<by_identity>,
123                 boost::multi_index::identity<SdfLayerHandle>,
124                 TfHash
125                 >,
126 
127             // Layer<->RealPath, one-to-one. The real path is the file from
128             // which an existing layer asset was read, or the path to which a
129             // newly created layer asset will be written.
130             boost::multi_index::hashed_unique<
131                 boost::multi_index::tag<by_real_path>,
132                 layer_real_path
133                 >,
134 
135             // Layer<->Identifier, one-to-many. The identifier is the path
136             // passed in to CreateNew/FindOrOpen, and may be any path form
137             // resolvable to a single real path.
138             boost::multi_index::hashed_non_unique<
139                 boost::multi_index::tag<by_identifier>,
140                 layer_identifier
141                 >,
142 
143             // Layer<->RepositoryPath
144             boost::multi_index::hashed_non_unique<
145                 boost::multi_index::tag<by_repository_path>,
146                 layer_repository_path
147                 >
148             >
149         > _Layers;
150 
151     // Identity index.
152     typedef _Layers::index<by_identity>::type _LayersByIdentity;
153     // Identifier index.
154     typedef _Layers::index<by_identifier>::type _LayersByIdentifier;
155     // Real path index.
156     typedef _Layers::index<by_real_path>::type _LayersByRealPath;
157     // Repository path index.
158     typedef _Layers::index<by_repository_path>::type _LayersByRepositoryPath;
159 
160     _Layers _layers;
161 };
162 
163 std::ostream&
164 operator<<(std::ostream& ostr, const Sdf_LayerRegistry& registry);
165 
166 PXR_NAMESPACE_CLOSE_SCOPE
167 
168 #endif // PXR_USD_SDF_LAYER_REGISTRY_H
169