All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
rankedTypeMap.h
Go to the documentation of this file.
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 GLF_RANKED_TYPE_MAP_H
25 #define GLF_RANKED_TYPE_MAP_H
26 
28 
29 #include "pxr/pxr.h"
30 #include "pxr/base/plug/plugin.h"
31 #include "pxr/base/plug/registry.h"
32 #include "pxr/base/tf/debug.h"
33 #include "pxr/base/tf/hashmap.h"
34 #include "pxr/base/tf/stringUtils.h"
35 #include "pxr/base/tf/token.h"
36 #include "pxr/base/tf/type.h"
37 
38 PXR_NAMESPACE_OPEN_SCOPE
39 
40 
46 public:
47  typedef TfToken key_type;
48  typedef TfType mapped_type;
49  typedef int Precedence;
50 
56  template <class DEBUG_TYPE>
57  void Add(const mapped_type& baseType,
58  const std::string& keyMetadataName,
59  DEBUG_TYPE debugType,
60  const std::string& whitelist = std::string());
61 
65  void Add(const key_type& key,const mapped_type& type, Precedence precedence)
66  {
67  if (type) {
68  auto i = _typeMap.find(key);
69  if (i == _typeMap.end() || i->second.precedence < precedence) {
70  _typeMap[key] = { type, precedence };
71  }
72  }
73  }
74 
77  mapped_type Find(const key_type& key) const
78  {
79  auto i = _typeMap.find(key);
80  return i == _typeMap.end() ? mapped_type() : i->second.type;
81  }
82 
83 private:
84  struct _Mapped {
85  TfType type;
86  Precedence precedence;
87  };
88  typedef TfToken::HashFunctor _Hash;
89  typedef TfHashMap<key_type, _Mapped, _Hash> _TypeMap;
90 
91  _TypeMap _typeMap;
92 };
93 
94 template <class DEBUG_TYPE>
95 void
97  const mapped_type& baseType,
98  const std::string& keyMetadataName,
99  DEBUG_TYPE debugType,
100  const std::string& whitelist)
101 {
102  // Statically load all plugin information, note that Plug does not crack
103  // open the libraries, it only reads metadata from text files.
105  std::set<TfType> types;
106  PlugRegistry::GetAllDerivedTypes(baseType, &types);
107 
108  const std::vector<std::string> restrictions = TfStringSplit(whitelist, ",");
109 
110  for (auto type: types) {
111  // Get the plugin.
112  PlugPluginPtr plugin = plugReg.GetPluginForType(type);
113  if (!plugin) {
114  TF_DEBUG(debugType).Msg(
115  "[PluginDiscover] Plugin could not be loaded "
116  "for TfType '%s'\n",
117  type.GetTypeName().c_str());
118  continue;
119  }
120 
121  // Check the whitelist.
122  if (!restrictions.empty()) {
123  bool goodPlugin = false;
124  for (const auto& restriction: restrictions) {
125  if (type.GetTypeName() == restriction) {
126  goodPlugin = true;
127  }
128  }
129  if (!goodPlugin) {
130  TF_DEBUG(debugType).Msg(
131  "[PluginDiscover] Skipping restricted plugin: '%s'\n",
132  type.GetTypeName().c_str());
133  continue;
134  }
135  }
136 
137  JsObject const& metadata = plugin->GetMetadataForType(type);
138 
139  JsObject::const_iterator keyIt = metadata.find(keyMetadataName);
140  if (keyIt == metadata.end()) {
141  TF_RUNTIME_ERROR("[PluginDiscover] '%s' metadata "
142  "was not present for plugin '%s'\n",
143  keyMetadataName.c_str(), type.GetTypeName().c_str());
144  continue;
145  }
146 
147  // Default precedence is 1. Plugins at equal precedence will be
148  // registered in order of discovery.
149  int precedence = 1;
150 
151  JsObject::const_iterator precedenceIt = metadata.find("precedence");
152  if (precedenceIt != metadata.end()) {
153  if (!precedenceIt->second.Is<int>()) {
154  TF_RUNTIME_ERROR("[PluginDiscover] 'precedence' metadata "
155  "can not be read for plugin '%s'\n",
156  type.GetTypeName().c_str());
157  } else {
158  precedence = precedenceIt->second.Get<int>();
159  }
160  }
161 
162  TF_DEBUG(debugType).Msg(
163  "[PluginDiscover] Plugin discovered '%s'\n",
164  type.GetTypeName().c_str());
165 
166  typedef std::string Name;
167  if (keyIt->second.Is<Name>()) {
168  // single name
169  Name const & name = keyIt->second.Get<Name>();
170  Add(TfToken(name), type, precedence);
171 
172  } else if (keyIt->second.IsArrayOf<Name>()) {
173  // list of names
174  for (const auto& name: keyIt->second.GetArrayOf<Name>()) {
175  Add(TfToken(name), type, precedence);
176  }
177  }
178  }
179 }
180 
181 
182 PXR_NAMESPACE_CLOSE_SCOPE
183 
184 #endif
Holds a token-to-type map with support for precedence per type.
Definition: rankedTypeMap.h:45
mapped_type Find(const key_type &key) const
Returns the highest precedence type for the given key or the unknown type if the key was not added...
Definition: rankedTypeMap.h:77
void Add(const key_type &key, const mapped_type &type, Precedence precedence)
Add a key/value pair if it&#39;s not in the map or the given precedence is larger than the current preced...
Definition: rankedTypeMap.h:65
Defines an interface for registering plugins.
Definition: registry.h:336
TF_API std::vector< std::string > TfStringSplit(std::string const &src, std::string const &separator)
Breaks the given string apart, returning a vector of strings.
PLUG_API PlugPluginPtr GetPluginForType(TfType t) const
Returns the plug-in for the given type, or a null pointer if there is no registered plug-in...
Functor to use for hash maps from tokens to other things.
Definition: token.h:168
Token for efficient comparison, assignment, and hashing of known strings.
Definition: token.h:89
void Add(const mapped_type &baseType, const std::string &keyMetadataName, DEBUG_TYPE debugType, const std::string &whitelist=std::string())
Add key/value pairs from plugins.
Definition: rankedTypeMap.h:96
#define TF_DEBUG(enumVal)
Evaluate and print debugging message msg if enumVal is enabled for debugging.
Definition: debug.h:497
static PLUG_API PlugRegistry & GetInstance()
Returns the singleton PlugRegistry instance.
static PLUG_API void GetAllDerivedTypes(TfType base, std::set< TfType > *result)
Return the set of all types derived (directly or indirectly) from base.
TfType represents a dynamic runtime type.
Definition: type.h:70
#define TF_RUNTIME_ERROR(fmt, args)
Issue a generic runtime error, but continue execution.
Definition: diagnostic.h:103