12 #ifndef hifi_AssociatedTraitValues_h
13 #define hifi_AssociatedTraitValues_h
15 #include "AvatarTraits.h"
28 namespace AvatarTraits {
29 template<
typename T, T defaultValue>
30 class AssociatedTraitValues {
31 using SimpleTypesArray = std::array<T, NUM_SIMPLE_TRAITS>;
34 AssociatedTraitValues() { std::fill(_simpleTypes.begin(), _simpleTypes.end(), defaultValue); }
37 void insert(TraitType type, T value) { _simpleTypes[type] = value; }
39 void erase(TraitType type) { _simpleTypes[type] = defaultValue; }
42 T& getInstanceValueRef(TraitType traitType, TraitInstanceID instanceID);
45 void instanceInsert(TraitType traitType, TraitInstanceID instanceID, T value);
47 struct InstanceIDValuePair {
51 InstanceIDValuePair(TraitInstanceID
id, T value) : id(id), value(value) {};
54 using InstanceIDValuePairs = std::vector<InstanceIDValuePair>;
57 InstanceIDValuePairs& getInstanceIDValuePairs(TraitType traitType);
60 void instanceErase(TraitType traitType, TraitInstanceID instanceID);
62 void eraseAllInstances(TraitType traitType);
65 T operator[](TraitType traitType)
const {
return _simpleTypes[traitType]; }
66 T& operator[](TraitType traitType) {
return _simpleTypes[traitType]; }
70 std::fill(_simpleTypes.begin(), _simpleTypes.end(), defaultValue);
71 _instancedTypes.clear();
75 typename SimpleTypesArray::const_iterator simpleCBegin()
const {
return _simpleTypes.cbegin(); }
76 typename SimpleTypesArray::const_iterator simpleCEnd()
const {
return _simpleTypes.cend(); }
79 typename SimpleTypesArray::iterator simpleBegin() {
return _simpleTypes.begin(); }
80 typename SimpleTypesArray::iterator simpleEnd() {
return _simpleTypes.end(); }
82 struct TraitWithInstances {
84 InstanceIDValuePairs instances;
86 TraitWithInstances(TraitType traitType) : traitType(traitType) {};
87 TraitWithInstances(TraitType traitType, TraitInstanceID instanceID, T value) :
88 traitType(traitType), instances({{ instanceID, value }}) {};
92 typename std::vector<TraitWithInstances>::const_iterator instancedCBegin()
const {
return _instancedTypes.cbegin(); }
93 typename std::vector<TraitWithInstances>::const_iterator instancedCEnd()
const {
return _instancedTypes.cend(); }
96 typename std::vector<TraitWithInstances>::iterator instancedBegin() {
return _instancedTypes.begin(); }
97 typename std::vector<TraitWithInstances>::iterator instancedEnd() {
return _instancedTypes.end(); }
100 SimpleTypesArray _simpleTypes;
103 typename std::vector<TraitWithInstances>::iterator instancesForTrait(TraitType traitType) {
104 return std::find_if(_instancedTypes.begin(), _instancedTypes.end(),
105 [traitType](TraitWithInstances& traitWithInstances){
106 return traitWithInstances.traitType == traitType;
110 std::vector<TraitWithInstances> _instancedTypes;
114 template <
typename T, T defaultValue>
115 inline typename AssociatedTraitValues<T, defaultValue>::InstanceIDValuePairs&
116 AssociatedTraitValues<T, defaultValue>::getInstanceIDValuePairs(TraitType traitType) {
118 auto it = instancesForTrait(traitType);
120 if (it != _instancedTypes.end()) {
121 return it->instances;
125 _instancedTypes.emplace_back(traitType);
126 return _instancedTypes.back().instances;
131 template <
typename T, T defaultValue>
132 inline T& AssociatedTraitValues<T, defaultValue>::getInstanceValueRef(TraitType traitType, TraitInstanceID instanceID) {
134 auto it = instancesForTrait(traitType);
136 if (it != _instancedTypes.end()) {
138 auto& instancesVector = it->instances;
141 auto instanceIt = std::find_if(instancesVector.begin(), instancesVector.end(),
142 [instanceID](InstanceIDValuePair& idValuePair){
143 return idValuePair.id == instanceID;
145 if (instanceIt != instancesVector.end()) {
146 return instanceIt->value;
149 instancesVector.emplace_back(instanceID, defaultValue);
150 return instancesVector.back().value;
155 _instancedTypes.emplace_back(traitType, instanceID, defaultValue);
156 return _instancedTypes.back().instances.back().value;
161 template <
typename T, T defaultValue>
162 inline void AssociatedTraitValues<T, defaultValue>::instanceInsert(TraitType traitType, TraitInstanceID instanceID, T value) {
164 auto it = instancesForTrait(traitType);
166 if (it != _instancedTypes.end()) {
168 auto& instancesVector = it->instances;
169 auto instanceIt = std::find_if(instancesVector.begin(), instancesVector.end(),
170 [instanceID](InstanceIDValuePair& idValuePair){
171 return idValuePair.id == instanceID;
173 if (instanceIt != instancesVector.end()) {
175 instanceIt->value = value;
178 instancesVector.emplace_back(instanceID, value);
183 _instancedTypes.emplace_back(traitType, instanceID, value);
188 template <
typename T, T defaultValue>
189 inline void AssociatedTraitValues<T, defaultValue>::instanceErase(TraitType traitType, TraitInstanceID instanceID) {
191 auto it = instancesForTrait(traitType);
193 if (it != _instancedTypes.end()) {
195 auto& instancesVector = it->instances;
196 instancesVector.erase(std::remove_if(instancesVector.begin(),
197 instancesVector.end(),
198 [&instanceID](InstanceIDValuePair& idValuePair){
199 return idValuePair.id == instanceID;
204 using TraitVersions = AssociatedTraitValues<TraitVersion, DEFAULT_TRAIT_VERSION>;