1 /* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifndef CHRE_CORE_REQUEST_MULTIPLEXER_H_ 18 #define CHRE_CORE_REQUEST_MULTIPLEXER_H_ 19 20 #include "chre/util/dynamic_vector.h" 21 #include "chre/util/non_copyable.h" 22 23 namespace chre { 24 25 /** 26 * This class multiplexes multiple generic requests into one maximal request. 27 * This is a templated class and the template type is required to implement the 28 * following API: 29 * 30 * 1. RequestType(); 31 * 32 * RequestTypes must be default constructable and constructed to a state 33 * that is the lowest possible priority for a request. The lowest priority 34 * state must be equivalent to being restored to the initial state for the 35 * RequestType. 36 * 37 * 2. bool isEquivalentTo(const RequestType& request) const; 38 * 39 * Perform a comparison to another request to determine if they are 40 * equivalent. This is different from equality in that the request object 41 * may have other internal state that makes two requests different, but 42 * their net request is considered to be equal. This function returns true 43 * if the requests are equivalent. 44 * 45 * 3. bool mergeWith(const RequestType& request); 46 * 47 * Merges a request with the current request. This method must set the 48 * attributes of the current request to the highest priority attributes of 49 * both the current and other. The method returns true if the current 50 * request has changed. 51 * 52 * NOTE: The request multiplexer makes use of move-semantics for certain 53 * operations so mergeWith must perform a deep copy when creating the merged 54 * output. 55 */ 56 template <typename RequestType> 57 class RequestMultiplexer : public NonCopyable { 58 public: 59 RequestMultiplexer() = default; RequestMultiplexer(RequestMultiplexer && other)60 RequestMultiplexer(RequestMultiplexer &&other) { 61 *this = std::move(other); 62 } 63 64 RequestMultiplexer &operator=(RequestMultiplexer &&other) { 65 mRequests = std::move(other.mRequests); 66 67 mCurrentMaximalRequest = other.mCurrentMaximalRequest; 68 other.mCurrentMaximalRequest = RequestType(); 69 70 return *this; 71 } 72 73 /** 74 * Adds a request to the list of requests being managed by this multiplexer. 75 * 76 * @param request The request to add to the list. 77 * @param index A non-null pointer to an index that is populated with the 78 * location that the request was added. 79 * @param maximalRequestChanged A non-null pointer to a bool that is set to 80 * true if current maximal request has changed. The user of this API 81 * must query the getCurrentMaximalRequest method to get the new 82 * maximal request. 83 * @return Returns false if the request cannot be inserted into the 84 * multiplexer. 85 */ 86 bool addRequest(const RequestType &request, size_t *index, 87 bool *maximalRequestChanged); 88 89 /** 90 * Same as addRequest above, but uses move semantics. 91 */ 92 bool addRequest(RequestType &&request, size_t *index, 93 bool *maximalRequestChanged); 94 95 /** 96 * Updates a request in the list of requests being managed by this 97 * multiplexer. 98 * 99 * @param index The index of the request to be updated. This param must fall 100 * in the range of indices provided by getRequests(). 101 * @param request The request to update to. 102 * @param maximalRequestChanged A non-null pointer to a bool that is set to 103 * true if the current maximal request has changed. The user of this 104 * API must query the getCurrentMaximalRequest() method to get the new 105 * maximal request. 106 */ 107 void updateRequest(size_t index, const RequestType &request, 108 bool *maximalRequestChanged); 109 110 /** 111 * Same as updateRequest above, but uses move semantics. 112 */ 113 void updateRequest(size_t index, RequestType &&request, 114 bool *maximalRequestChanged); 115 116 /** 117 * Removes a request from the list of requests being managed by this 118 * multiplexer. 119 * 120 * @param index The index of the request to be removed. This index must fall 121 * in the range of indices provided by getRequests(). 122 * @param maximalRequestChanged A non-null pointer to a bool that is set to 123 * true if the current maximal request has changed. The user of this 124 * API must query the getCurrentMaximalRequest method to get the new 125 * maximal request. 126 */ 127 void removeRequest(size_t index, bool *maximalRequestChanged); 128 129 /* 130 * Removes all requests managed by this multiplexer. The maximal request will 131 * change if the multiplexer is not empty. 132 * 133 * @param maximalRequestChanged A non-null pointer to a bool that is set to 134 * true if the current maximal request has changed. 135 */ 136 void removeAllRequests(bool *maximalRequestChanged); 137 138 /** 139 * @return The list of requests managed by this multiplexer. 140 */ 141 const DynamicVector<RequestType> &getRequests() const; 142 143 /** 144 * @return Returns the current maximal request. 145 */ 146 const RequestType &getCurrentMaximalRequest() const; 147 148 protected: 149 //! The list of requests to track. 150 DynamicVector<RequestType> mRequests; 151 152 /** 153 * Iterates over all tracked requests and updates the current maximal request 154 * if it has changed. 155 * 156 * @param maximalRequestChanged A non-null pointer to a bool that is set to 157 * true if the current maximal request has changed. 158 */ 159 void updateMaximalRequest(bool *maximalRequestChanged); 160 161 private: 162 //! The current maximal request as generated by this multiplexer. 163 RequestType mCurrentMaximalRequest; 164 }; 165 166 } // namespace chre 167 168 #include "chre/core/request_multiplexer_impl.h" 169 170 #endif // CHRE_CORE_REQUEST_MULTIPLEXER_H_ 171