class RuntimeAsyncGate { RuntimeAsyncGate({bool initiallyClosed = false}) : _closed = initiallyClosed; int _generation = 0; bool _closed; int get generation => _generation; bool get isOpen => !_closed; bool get isClosed => _closed; RuntimeAsyncToken get token => RuntimeAsyncToken._(this, _generation); RuntimeAsyncToken activate() { _closed = false; _generation++; return token; } RuntimeAsyncToken advance() { _generation++; return token; } RuntimeAsyncToken close() { _closed = true; _generation++; return token; } bool accepts(RuntimeAsyncToken token) { return !_closed && identical(token._gate, this) && token.generation == _generation; } bool acceptsGeneration(int generation) { return !_closed && generation == _generation; } } class RuntimeAsyncToken { const RuntimeAsyncToken._(this._gate, this.generation); final RuntimeAsyncGate _gate; final int generation; bool get isAccepted => _gate.accepts(this); }