|
9 | 9 | import android.widget.ScrollView;
|
10 | 10 | import com.scrappers.superiorExtendedEngine.menuStates.UiStateManager;
|
11 | 11 | import com.scrappers.superiorExtendedEngine.menuStates.UiStatesLooper;
|
| 12 | +import java.util.ArrayList; |
| 13 | +import java.util.Collections; |
12 | 14 | import java.util.ConcurrentModificationException;
|
13 | 15 | import java.util.HashMap;
|
| 16 | +import java.util.List; |
| 17 | +import java.util.concurrent.Executors; |
14 | 18 | import androidx.annotation.IdRes;
|
| 19 | +import androidx.annotation.Nullable; |
15 | 20 |
|
16 | 21 | /**
|
17 | 22 | * A UiState Class that could hold multiple UiStates in a list/grid form.
|
|
20 | 25 | */
|
21 | 26 | public class UiPager extends GridLayout {
|
22 | 27 | public static final int SEQUENTIAL_ADD = -1;
|
| 28 | + public static final int A_Z = 200; |
| 29 | + public static final int Z_A = 300; |
23 | 30 | private final HashMap<Integer, View> uiStates = new HashMap<>();
|
24 | 31 | private int stateIndex=0;
|
25 | 32 |
|
@@ -168,6 +175,112 @@ public void forEachUiState(UiStatesLooper.Modifiable.Looper uiStatesLooper){
|
168 | 175 | uiStatesLooper.applyUpdate(getChildUiStateByIndex(position), position);
|
169 | 176 | }
|
170 | 177 | }
|
| 178 | + |
| 179 | + /** |
| 180 | + * Runs an anonymous asynchronous searching task function for some items inside a searchList based on a list of searchKeyWords. |
| 181 | + * @param searchList the search list you want to traverse through, it should be parallel to the UiStates you want to update. |
| 182 | + * @param searchKeyWords the keywords you want to look for inside this search list. |
| 183 | + * @param injector injects what you want to do when an item is returned by the search engine. |
| 184 | + * @return a list of the founded strings from the searchList based on the search keywords. |
| 185 | + * @throws Exception throws an exception if the search custom thread fails. |
| 186 | + * @apiNote <b> <T extends Object> synchronized(T)</b> marks a thread-safe function by the dead locking other threads synchronized on the same object scheduled or started by the thread factory. |
| 187 | + */ |
| 188 | + public String[] search(String[] searchList, String[] searchKeyWords, ActionInjector injector) throws Exception { |
| 189 | + synchronized(this) { |
| 190 | + final String[] resultList = new String[searchList.length]; |
| 191 | + return Executors.callable(() -> { |
| 192 | + //format the list |
| 193 | + removeAllViews(); |
| 194 | + for (int pos = 0; pos < searchList.length; pos++) { |
| 195 | + for (String keyword : searchKeyWords) { |
| 196 | + if (searchList[pos].replaceAll(" ","").trim().toLowerCase().contains(keyword.replaceAll(" ","").trim().toLowerCase())) { |
| 197 | + resultList[pos] = searchList[pos]; |
| 198 | + View uiState = getChildUiStateByIndex(pos); |
| 199 | + addView(uiState); |
| 200 | + if(injector != null){ |
| 201 | + injector.execute(uiState, pos); |
| 202 | + } |
| 203 | + break; |
| 204 | + } |
| 205 | + } |
| 206 | + } |
| 207 | + }, resultList).call(); |
| 208 | + } |
| 209 | + } |
| 210 | + |
| 211 | + /** |
| 212 | + * Revert the search results executed by the search function, to the full length of UiStates, this doesn't stop the searching thread though, it rather waits until it finishes searching. |
| 213 | + * @param actionInjector injects actions to execute accompanied by the reversion. |
| 214 | + * @throws Exception throws an exception if the revert custom thread fails. |
| 215 | + * @apiNote <b> <T extends Object> synchronized(T)</b> marks a thread-safe function by the dead locking other threads synchronized on the same object scheduled or started by the thread factory. |
| 216 | + */ |
| 217 | + public void revertSearchEngine(@Nullable ActionInjector actionInjector) throws Exception { |
| 218 | + synchronized(this){ |
| 219 | + //format the states |
| 220 | + removeAllViews(); |
| 221 | + Executors.callable(() -> forEachUiState((UiStatesLooper.Modifiable.Looper) (currentView, position) -> { |
| 222 | + if (actionInjector != null) { |
| 223 | + actionInjector.execute(currentView, position); |
| 224 | + } |
| 225 | + addView(currentView, position); |
| 226 | + })).call(); |
| 227 | + } |
| 228 | + } |
| 229 | + |
| 230 | + /** |
| 231 | + * Sort a String list either by A_Z or Z_A swapping algorithm, the sort runs in an async task in the same called thread. |
| 232 | + * @param list the list to order sort for. |
| 233 | + * @param sortAlgorithm the sort algorithm either {@link UiPager#A_Z} or {@link UiPager#Z_A}. |
| 234 | + * @return the new sorted String in the shape of Collection List. |
| 235 | + * @throws Exception if process is interrupted or -1 is returned. |
| 236 | + * @apiNote you will need to loop over this list to provide the uiStates with new update. |
| 237 | + */ |
| 238 | + public String[] sort(String[] list, int sortAlgorithm) throws Exception { |
| 239 | + synchronized(this) { |
| 240 | + return Executors.callable(() -> { |
| 241 | + String tempPointer = ""; |
| 242 | + //main String List looping |
| 243 | + for (int i = 0; i < list.length; i++) { |
| 244 | + //looping over the String again to compare each one String member var with the sequence of the String member vars after that item |
| 245 | + for(int j = i+1; j < list.length; j++ ){ |
| 246 | + //loop over chars inside the 2 strings & compare those suckers |
| 247 | + for(int k = 0; k < Math.min(list[i].length(), list[j].length()); k++){ |
| 248 | + //sort from A-Z ascendingly |
| 249 | + if(sortAlgorithm == A_Z){ |
| 250 | + if ( list[i].toLowerCase().charAt(k) > list[j].toLowerCase().charAt(k) ){ |
| 251 | + //format the pointer |
| 252 | + tempPointer = ""; |
| 253 | + //then swap list[i] & list[j] because list[i] is after the list[k] |
| 254 | + //store the list[i] inside the tempPointer for later access |
| 255 | + tempPointer = list[i]; |
| 256 | + //get the list[i] after |
| 257 | + list[i] = list[j]; |
| 258 | + //get the list[j] before |
| 259 | + list[j] = tempPointer; |
| 260 | + //terminate the comparison when goal is reached; for a new round |
| 261 | + break; |
| 262 | + } |
| 263 | + }else if(sortAlgorithm == Z_A){ |
| 264 | + if ( list[i].toLowerCase().charAt(k) < list[j].toLowerCase().charAt(k) ){ |
| 265 | + //format the pointer |
| 266 | + tempPointer = ""; |
| 267 | + //then swap list[i] & list[j] because list[i] is before the list[k] |
| 268 | + //store the list[j] inside the tempPointer for later access |
| 269 | + tempPointer = list[j]; |
| 270 | + //get the list[j] before |
| 271 | + list[j] = list[i]; |
| 272 | + //get the list[i] after |
| 273 | + list[i] = tempPointer; |
| 274 | + //terminate the comparison when goal is reached; for a new round |
| 275 | + break; |
| 276 | + } |
| 277 | + } |
| 278 | + } |
| 279 | + } |
| 280 | + } |
| 281 | + }, list).call(); |
| 282 | + } |
| 283 | + } |
171 | 284 | /**
|
172 | 285 | * gets the index of the Last UI-State attached to the UI-State-Manager.
|
173 | 286 | * @return the index of the last UI state.
|
|
0 commit comments