summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'src/com/isode/stroke/eventloop/EventLoop.java')
-rw-r--r--src/com/isode/stroke/eventloop/EventLoop.java90
1 files changed, 90 insertions, 0 deletions
diff --git a/src/com/isode/stroke/eventloop/EventLoop.java b/src/com/isode/stroke/eventloop/EventLoop.java
new file mode 100644
index 0000000..9399d9a
--- /dev/null
+++ b/src/com/isode/stroke/eventloop/EventLoop.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2010 Remko Tron¨on
+ * Licensed under the GNU General Public License v3.
+ * See Documentation/Licenses/GPLv3.txt for more information.
+ */
+/*
+ * Copyright (c) 2010, Isode Limited, London, England.
+ * All rights reserved.
+ */
+package com.isode.stroke.eventloop;
+
+import java.util.ArrayList;
+import java.util.Vector;
+
+public abstract class EventLoop {
+
+ public EventLoop() {
+ }
+
+ public void postEvent(Event.Callback callback) {
+ postEvent(callback, null);
+ }
+
+ public void postEvent(Event.Callback callback, EventOwner owner) {
+ Event event;
+ synchronized (eventsMutex_) {
+ event = new Event(owner, callback, nextEventID_);
+ nextEventID_++;
+ events_.add(event);
+ }
+ post(event);
+ }
+
+ public void removeEventsFromOwner(EventOwner owner) {
+ synchronized (eventsMutex_) {
+ ArrayList<Event> matches = new ArrayList<Event>();
+ for (Event event : events_) {
+ if (event.owner == owner) {
+ matches.add(event);
+ }
+ }
+ events_.removeAll(matches);
+ }
+ }
+
+ /**
+ * Reimplement this to call handleEvent(event) from the thread in which
+ * the event loop is residing.
+ */
+ protected abstract void post(Event event);
+
+ protected void handleEvent(Event event) {
+ if (handlingEvents_) {
+ // We're being called recursively. Push in the list of events to
+ // handle in the parent handleEvent()
+ eventsToHandle_.add(event);
+ return;
+ }
+
+ boolean doCallback = false;
+ synchronized (eventsMutex_) {
+ doCallback = events_.contains(event);
+ if (doCallback) {
+ events_.remove(event);
+ }
+ }
+ if (doCallback) {
+ handlingEvents_ = true;
+ event.callback.run();
+ // Process events that were passed to handleEvent during the callback
+ // (i.e. through recursive calls of handleEvent)
+ while (!eventsToHandle_.isEmpty()) {
+ Event nextEvent = eventsToHandle_.firstElement();
+ eventsToHandle_.remove(0);
+ nextEvent.callback.run();
+ }
+ handlingEvents_ = false;
+ }
+ }
+ // struct HasOwner {
+ // HasOwner(boost::shared_ptr<EventOwner> owner) : owner(owner) {}
+ // bool operator()(const Event& event) { return event.owner == owner; }
+ // boost::shared_ptr<EventOwner> owner;
+ // };
+ private final Object eventsMutex_ = new Object();
+ private int nextEventID_ = 0;
+ private Vector<Event> events_ = new Vector<Event>();
+ boolean handlingEvents_ = false;
+ private Vector<Event> eventsToHandle_ = new Vector<Event>();
+}