diff options
author | Alan Young <consult.awy@gmail.com> | 2016-04-18 16:37:46 (GMT) |
---|---|---|
committer | Alan Young <consult.awy@gmail.com> | 2016-04-20 16:29:51 (GMT) |
commit | 9d50093bee736d2b7b43756e9a41cfafbd568ee2 (patch) | |
tree | 50923023315027b6a099f7349506868d58b4d736 /src/com/isode/stroke/signals/BaseSignal.java | |
parent | 82f43f69b1cdb1d2f6cd11c64a71dc99c8533d5a (diff) | |
download | stroke-9d50093bee736d2b7b43756e9a41cfafbd568ee2.zip stroke-9d50093bee736d2b7b43756e9a41cfafbd568ee2.tar.bz2 |
Rework Signals for time and space optimizations
Each Signal* class extends BaseSignal. Each Slot* class extends
BaseSlot.
BaseSignal manages the set of binds associated with it via addBind() and
getBinds() which are called from Signal*. It is optimized for the cases
of zero or one bind, only allocating a HashMap to hold a larger set when
needed.
The interaction with SignalConnection to handle disconnection is
effected via a callback interface rather than another Signal.
Change-Id: Ifa44c1eb40b778c303db947a6e74fe20d1b41a90
Diffstat (limited to 'src/com/isode/stroke/signals/BaseSignal.java')
-rw-r--r-- | src/com/isode/stroke/signals/BaseSignal.java | 62 |
1 files changed, 62 insertions, 0 deletions
diff --git a/src/com/isode/stroke/signals/BaseSignal.java b/src/com/isode/stroke/signals/BaseSignal.java new file mode 100644 index 0000000..de1bd6e --- /dev/null +++ b/src/com/isode/stroke/signals/BaseSignal.java @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2015, Isode Limited, London, England. + * All rights reserved. + */ +package com.isode.stroke.signals; + +import java.util.HashMap; +import java.util.Map; + +/* package */ abstract class BaseSignal implements SignalConnection.DisconnectListener { + + // Optimized for the case of 0 or 1 bind + private SignalConnection connection_; + private BaseSlot bind_; + private Map<SignalConnection, BaseSlot> binds_; + + protected final synchronized SignalConnection addBind(final BaseSlot bind) { + final SignalConnection connection = new SignalConnection(this); + if (binds_ != null) { + binds_.put(connection, bind); + } else if (connection_ != null) { + binds_ = new HashMap<SignalConnection, BaseSlot>(); + binds_.put(connection_, bind_); + connection_ = null; + bind_ = null; + binds_.put(connection, bind); + } else { + connection_ = connection; + bind_ = bind; + } + return connection; + } + + protected final synchronized BaseSlot[] getBinds() { + if (binds_ != null) { + return binds_.values().toArray(new BaseSlot[binds_.size()]); + } else if (connection_ != null) { + return new BaseSlot[]{bind_}; + } else { + return null; // return null rather than allocate an empty array + } + } + + @Override + public final synchronized void onSignalConnectionDisconnect(final SignalConnection connection) { + if (binds_ != null) { + binds_.remove(connection); + } else if (connection_ == connection) { + connection_ = null; + bind_ = null; + } + } + + public final synchronized void disconnectAll() { + if (binds_ != null) { + binds_.clear(); + } else { + connection_ = null; + bind_ = null; + } + } +} |