1 // Copyright (C) 2020 The Android Open Source Project 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 #pragma once 15 16 #include "aemu/base/containers/Lookup.h" 17 #include "aemu/base/containers/EntityManager.h" 18 19 #include <unordered_map> 20 21 namespace gfxstream { 22 namespace guest { 23 24 template <size_t maxIndex, 25 class IndexType, // must be castable to uint64_t 26 class Data> 27 class HybridComponentManager { 28 public: 29 using UCM = UnpackedComponentManager<32, 16, 16, Data>; 30 using EM = EntityManager<32, 16, 16, Data>; 31 using IterFunc = typename UCM::ComponentIteratorFunc; 32 using ConstIterFunc = typename UCM::ConstComponentIteratorFunc; 33 using Handle = typename EM::EntityHandle; 34 add(IndexType index,const Data & data)35 void add(IndexType index, const Data& data) { 36 uint64_t index_u64 = (uint64_t)index; 37 if (index_u64 < maxIndex) { 38 auto internal_handle = index2Handle(index_u64); 39 mComponentManager.add(internal_handle, data); 40 } else { 41 mMap[index] = data; 42 } 43 44 } 45 clear()46 void clear() { 47 mComponentManager.clear(); 48 mMap.clear(); 49 } 50 remove(IndexType index)51 void remove(IndexType index) { 52 uint64_t index_u64 = (uint64_t)index; 53 if (index_u64 < maxIndex) { 54 auto internal_handle = index2Handle(index_u64); 55 mComponentManager.remove(internal_handle); 56 } else { 57 mMap.erase(index); 58 } 59 } 60 get(IndexType index)61 Data* get(IndexType index) { 62 uint64_t index_u64 = (uint64_t)index; 63 if (index_u64 < maxIndex) { 64 auto internal_handle = index2Handle(index_u64); 65 return mComponentManager.get(internal_handle); 66 } else { 67 return gfxstream::guest::find(mMap, index); 68 } 69 } 70 get_const(IndexType index)71 const Data* get_const(IndexType index) const { 72 uint64_t index_u64 = (uint64_t)index; 73 if (index_u64 < maxIndex) { 74 auto internal_handle = index2Handle(index_u64); 75 return mComponentManager.get_const(internal_handle); 76 } else { 77 return gfxstream::guest::find(mMap, index); 78 } 79 } 80 getExceptZero(IndexType index)81 Data* getExceptZero(IndexType index) { 82 Data* res = get(index); 83 if (!res) return nullptr; 84 if (!(*res)) return nullptr; 85 return res; 86 } 87 getExceptZero_const(IndexType index)88 const Data* getExceptZero_const(IndexType index) const { 89 const Data* res = get_const(index); 90 if (!res) return nullptr; 91 if (!(*res)) return nullptr; 92 return res; 93 } 94 forEach(IterFunc func)95 void forEach(IterFunc func) { 96 mComponentManager.forEach(func); 97 98 for (auto it : mMap) { 99 auto handle = index2Handle(it.first); 100 func(true /* live */, handle, handle, it.second); 101 } 102 } 103 forEachLive(IterFunc func)104 void forEachLive(IterFunc func) { 105 mComponentManager.forEachLiveComponent(func); 106 107 for (auto it : mMap) { 108 auto handle = index2Handle(it.first); 109 func(true /* live */, handle, handle, it.second); 110 } 111 } 112 forEachLive_const(ConstIterFunc func)113 void forEachLive_const(ConstIterFunc func) const { 114 mComponentManager.forEachLiveComponent_const(func); 115 116 for (const auto it : mMap) { 117 auto handle = index2Handle(it.first); 118 func(true /* live */, handle, handle, it.second); 119 } 120 } 121 122 private: index2Handle(uint64_t index)123 static Handle index2Handle(uint64_t index) { 124 return EM::makeHandle((uint32_t)index, 1, 1); 125 } 126 127 UCM mComponentManager; 128 std::unordered_map<IndexType, Data> mMap; 129 }; 130 131 } // namespace android 132 } // namespace base 133