1 /+ 2 This file is part of Reloaded Vibes. 3 Copyright (c) 2019 0xEAB 4 5 Distributed under the Boost Software License, Version 1.0. 6 (See accompanying file LICENSE_1_0.txt or copy at 7 https://www.boost.org/LICENSE_1_0.txt) 8 +/ 9 module reloadedvibes.watcher; 10 11 import std.algorithm : remove; 12 import std.range : isInputRange; 13 import fswatch; 14 15 final class Watcher 16 { 17 private 18 { 19 FileWatch*[] _fws = []; 20 WatcherClient[] _cs = []; 21 } 22 23 public this(Range)(Range directories) if (isInputRange!Range) 24 { 25 foreach (dir; directories) 26 { 27 this._fws ~= new FileWatch(dir, true); 28 } 29 } 30 31 private 32 { 33 void registerClient(WatcherClient c) @safe pure nothrow 34 { 35 this._cs ~= c; 36 } 37 38 void unregisterClient(WatcherClient c) 39 { 40 this._cs = this._cs.remove!(x => x == c); 41 } 42 43 void query() 44 { 45 bool notify = false; 46 47 foreach (fw; this._fws) 48 { 49 if (fw.getEvents().length > 0) 50 { 51 notify = true; 52 } 53 } 54 55 if (notify) 56 { 57 foreach (c; this._cs) 58 { 59 c.notify(); 60 } 61 } 62 } 63 } 64 } 65 66 class WatcherClient 67 { 68 private 69 { 70 Watcher _w; 71 bool _notified = false; 72 } 73 74 public 75 { 76 Watcher watcher() 77 { 78 return this._w; 79 } 80 } 81 82 public final this(Watcher w) @safe pure nothrow 83 { 84 this._w = w; 85 this._w.registerClient(this); 86 } 87 88 public final 89 { 90 bool query() 91 { 92 if (this._notified) 93 { 94 this._notified = false; 95 return true; 96 } 97 98 this._w.query(); 99 100 if (this._notified) 101 { 102 this._notified = false; 103 return true; 104 } 105 106 return false; 107 } 108 109 void unregister() 110 { 111 this._w.unregisterClient(this); 112 } 113 } 114 115 protected 116 { 117 void notify() 118 { 119 this.setNotified(); 120 } 121 122 void setNotified() @safe pure nothrow @nogc 123 { 124 this._notified = true; 125 } 126 } 127 }