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