1 /* 2 * Hunt - A cross-platform abstraction library with asynchronous I/O. 3 * 4 * Copyright (C) 2021-2022 Kerisy.com 5 * 6 * Website: https://www.kerisy.com 7 * 8 * Licensed under the Apache-2.0 License. 9 * 10 */ 11 module geario.util.Common; 12 13 import geario.util.Runnable; 14 15 import geario.logging; 16 17 18 /** 19 * Implementing this interface allows an object to be the target of 20 * the "for-each loop" statement. 21 * @param (T) the type of elements returned by the iterator 22 */ 23 interface Iterable(T) { 24 int opApply(scope int delegate(ref T) dg); 25 } 26 27 interface Iterable(K, V) { 28 int opApply(scope int delegate(ref K, ref V) dg); 29 } 30 31 32 /** 33 * A class implements the <code>Cloneable</code> interface to 34 * indicate to the {@link java.lang.Object#clone()} method that it 35 * is legal for that method to make a 36 * field-for-field copy of instances of that class. 37 * <p> 38 * Invoking Object's clone method on an instance that does not implement the 39 * <code>Cloneable</code> interface results in the exception 40 * <code>CloneNotSupportedException</code> being thrown. 41 * <p> 42 * By convention, classes that implement this interface should override 43 * <tt>Object.clone</tt> (which is protected) with a method. 44 * See {@link java.lang.Object#clone()} for details on overriding this 45 * method. 46 * <p> 47 * Note that this interface does <i>not</i> contain the <tt>clone</tt> method. 48 * Therefore, it is not possible to clone an object merely by virtue of the 49 * fact that it implements this interface. Even if the clone method is invoked 50 * reflectively, there is no guarantee that it will succeed. 51 */ 52 interface Cloneable { 53 //Object clone(); 54 } 55 56 57 // /** 58 // * A {@code Flushable} is a destination of data that can be flushed. The 59 // * flush method is invoked to write any buffered output to the underlying 60 // * stream. 61 // */ 62 // interface Flushable { 63 64 // /** 65 // * Flushes this stream by writing any buffered output to the underlying 66 // * stream. 67 // * 68 // * @throws IOException If an I/O error occurs 69 // */ 70 // void flush(); 71 // } 72 73 // /** 74 // */ 75 // interface Serializable { 76 77 // ubyte[] serialize(); 78 79 // // void deserialize(ubyte[] data); 80 // } 81 82 83 interface Comparable(T) { 84 // TODO: Tasks pending completion -@zxp at 12/30/2018, 10:17:44 AM 85 // 86 // int opCmp(T o) nothrow; 87 int opCmp(T o); 88 89 // deprecated("Use opCmp instead.") 90 // alias compareTo = opCmp; 91 } 92 93 94 /** 95 * A task that returns a result and may throw an exception. 96 * Implementors define a single method with no arguments called 97 * {@code call}. 98 * 99 * <p>The {@code Callable} interface is similar to {@link 100 * java.lang.Runnable}, in that both are designed for classes whose 101 * instances are potentially executed by another thread. A 102 * {@code Runnable}, however, does not return a result and cannot 103 * throw a checked exception. 104 * 105 * <p>The {@link Executors} class contains utility methods to 106 * convert from other common forms to {@code Callable} classes. 107 * 108 * @see Executor 109 * @author Doug Lea 110 * @param <V> the result type of method {@code call} 111 */ 112 interface Callable(V) { 113 /** 114 * Computes a result, or throws an exception if unable to do so. 115 * 116 * @return computed result 117 * @throws Exception if unable to compute a result 118 */ 119 V call(); 120 } 121 122 123 /** 124 * An object that executes submitted {@link Runnable} tasks. This 125 * interface provides a way of decoupling task submission from the 126 * mechanics of how each task will be run, including details of thread 127 * use, scheduling, etc. An {@code Executor} is normally used 128 * instead of explicitly creating threads. For example, rather than 129 * invoking {@code new Thread(new RunnableTask()).start()} for each 130 * of a set of tasks, you might use: 131 * 132 * <pre> {@code 133 * Executor executor = anExecutor(); 134 * executor.Execute(new RunnableTask1()); 135 * executor.Execute(new RunnableTask2()); 136 * ...}</pre> 137 * 138 * However, the {@code Executor} interface does not strictly require 139 * that execution be asynchronous. In the simplest case, an executor 140 * can run the submitted task immediately in the caller's thread: 141 * 142 * <pre> {@code 143 * class DirectExecutor implements Executor { 144 * public void Execute(Runnable r) { 145 * r.run(); 146 * } 147 * }}</pre> 148 * 149 * More typically, tasks are executed in some thread other than the 150 * caller's thread. The executor below spawns a new thread for each 151 * task. 152 * 153 * <pre> {@code 154 * class ThreadPerTaskExecutor implements Executor { 155 * public void Execute(Runnable r) { 156 * new Thread(r).start(); 157 * } 158 * }}</pre> 159 * 160 * Many {@code Executor} implementations impose some sort of 161 * limitation on how and when tasks are scheduled. The executor below 162 * serializes the submission of tasks to a second executor, 163 * illustrating a composite executor. 164 * 165 * <pre> {@code 166 * class SerialExecutor implements Executor { 167 * final Queue!(Runnable) tasks = new ArrayDeque<>(); 168 * final Executor executor; 169 * Runnable active; 170 * 171 * SerialExecutor(Executor executor) { 172 * this.executor = executor; 173 * } 174 * 175 * public synchronized void Execute(Runnable r) { 176 * tasks.add(() -> { 177 * try { 178 * r.run(); 179 * } finally { 180 * scheduleNext(); 181 * } 182 * }); 183 * if (active is null) { 184 * scheduleNext(); 185 * } 186 * } 187 * 188 * protected synchronized void scheduleNext() { 189 * if ((active = tasks.poll()) !is null) { 190 * executor.Execute(active); 191 * } 192 * } 193 * }}</pre> 194 * 195 * The {@code Executor} implementations provided in this package 196 * implement {@link ExecutorService}, which is a more extensive 197 * interface. The {@link ThreadPoolExecutor} class provides an 198 * extensible thread pool implementation. The {@link Executors} class 199 * provides convenient factory methods for these Executors. 200 * 201 * <p>Memory consistency effects: Actions in a thread prior to 202 * submitting a {@code Runnable} object to an {@code Executor} 203 * <a href="package-summary.html#MemoryVisibility"><i>happen-before</i></a> 204 * its execution begins, perhaps in another thread. 205 * 206 * @author Doug Lea 207 */ 208 interface Executor { 209 210 /** 211 * Executes the given command at some time in the future. The command 212 * may execute in a new thread, in a pooled thread, or in the calling 213 * thread, at the discretion of the {@code Executor} implementation. 214 * 215 * @param command the runnable task 216 * @throws RejectedExecutionException if this task cannot be 217 * accepted for execution 218 * @throws NullPointerException if command is null 219 */ 220 void Execute(Runnable command); 221 } 222 223 224 225 // /** 226 // * <p> 227 // * A callback abstraction that handles completed/failed events of asynchronous 228 // * operations. 229 // * </p> 230 // * <p> 231 // * <p> 232 // * Semantically this is equivalent to an optimise Promise<Void>, but 233 // * callback is a more meaningful name than EmptyPromise 234 // * </p> 235 // */ 236 // interface Callback { 237 // /** 238 // * Instance of Adapter that can be used when the callback methods need an 239 // * empty implementation without incurring in the cost of allocating a new 240 // * Adapter object. 241 // */ 242 // __gshared Callback NOOP; 243 244 // shared static this() { 245 // NOOP = new NoopCallback(); 246 // } 247 248 // /** 249 // * <p> 250 // * Callback invoked when the operation completes. 251 // * </p> 252 // * 253 // * @see #Failed(Throwable) 254 // */ 255 // void Succeeded(); 256 257 // /** 258 // * <p> 259 // * Callback invoked when the operation fails. 260 // * </p> 261 // * 262 // * @param x the reason for the operation failure 263 // */ 264 // void Failed(Exception x); 265 266 // /** 267 // * @return True if the callback is known to never block the caller 268 // */ 269 // bool IsNonBlocking(); 270 // } 271 272 // /** 273 // * 274 // */ 275 // class NestedCallback : Callback { 276 // private Callback callback; 277 278 // this(Callback callback) { 279 // this.callback = callback; 280 // } 281 282 // this(NestedCallback nested) { 283 // this.callback = nested.callback; 284 // } 285 286 // Callback GetCallback() { 287 // return callback; 288 // } 289 290 // void Succeeded() { 291 // if(callback is null) { 292 // version(GEAR_DEBUG) warning("callback is null"); 293 // } else { 294 // callback.Succeeded(); 295 // } 296 // } 297 298 // void Failed(Exception x) { 299 // if(callback is null) { 300 // version(GEAR_DEBUG) warning("callback is null"); 301 // } else { 302 // callback.Failed(x); 303 // } 304 // } 305 306 // bool IsNonBlocking() { 307 // if(callback is null) { 308 // version(GEAR_DEBUG) warning("callback is null"); 309 // return false; 310 // } else { 311 // return callback.IsNonBlocking(); 312 // } 313 // } 314 // } 315 316 // /** 317 // * <p> 318 // * A callback abstraction that handles completed/failed events of asynchronous 319 // * operations. 320 // * </p> 321 // * <p> 322 // * <p> 323 // * Semantically this is equivalent to an optimise Promise<Void>, but 324 // * callback is a more meaningful name than EmptyPromise 325 // * </p> 326 // */ 327 // class NoopCallback : Callback { 328 // /** 329 // * <p> 330 // * Callback invoked when the operation completes. 331 // * </p> 332 // * 333 // * @see #Failed(Throwable) 334 // */ 335 // void Succeeded() { 336 // } 337 338 // /** 339 // * <p> 340 // * Callback invoked when the operation fails. 341 // * </p> 342 // * 343 // * @param x the reason for the operation failure 344 // */ 345 // void Failed(Exception x) { 346 // } 347 348 // /** 349 // * @return True if the callback is known to never block the caller 350 // */ 351 // bool IsNonBlocking() { 352 // return true; 353 // } 354 // }