gfx/skia/trunk/include/views/SkEvent.h

Thu, 15 Jan 2015 15:55:04 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 15 Jan 2015 15:55:04 +0100
branch
TOR_BUG_9701
changeset 9
a63d609f5ebe
permissions
-rw-r--r--

Back out 97036ab72558 which inappropriately compared turds to third parties.

michael@0 1 /*
michael@0 2 * Copyright 2006 The Android Open Source Project
michael@0 3 *
michael@0 4 * Use of this source code is governed by a BSD-style license that can be
michael@0 5 * found in the LICENSE file.
michael@0 6 */
michael@0 7
michael@0 8 #ifndef SkEvent_DEFINED
michael@0 9 #define SkEvent_DEFINED
michael@0 10
michael@0 11 #include "SkDOM.h"
michael@0 12 #include "SkMetaData.h"
michael@0 13 #include "SkString.h"
michael@0 14
michael@0 15 /** Unique 32bit id used to identify an instance of SkEventSink. When events are
michael@0 16 posted, they are posted to a specific sinkID. When it is time to dispatch the
michael@0 17 event, the sinkID is used to find the specific SkEventSink object. If it is found,
michael@0 18 its doEvent() method is called with the event.
michael@0 19 */
michael@0 20 typedef uint32_t SkEventSinkID;
michael@0 21
michael@0 22 /**
michael@0 23 * \class SkEvent
michael@0 24 *
michael@0 25 * When an event is dispatched from the event queue, it is either sent to
michael@0 26 * the eventsink matching the target ID (if not 0), or the target proc is
michael@0 27 * called (if not NULL).
michael@0 28 */
michael@0 29 class SkEvent {
michael@0 30 public:
michael@0 31 /**
michael@0 32 * Function pointer that takes an event, returns true if it "handled" it.
michael@0 33 */
michael@0 34 typedef bool (*Proc)(const SkEvent& evt);
michael@0 35
michael@0 36 SkEvent();
michael@0 37 explicit SkEvent(const SkString& type, SkEventSinkID = 0);
michael@0 38 explicit SkEvent(const char type[], SkEventSinkID = 0);
michael@0 39 SkEvent(const SkEvent& src);
michael@0 40 ~SkEvent();
michael@0 41
michael@0 42 /** Copy the event's type into the specified SkString parameter */
michael@0 43 void getType(SkString* str) const;
michael@0 44
michael@0 45 /** Returns true if the event's type matches exactly the specified type (case sensitive) */
michael@0 46 bool isType(const SkString& str) const;
michael@0 47
michael@0 48 /** Returns true if the event's type matches exactly the specified type (case sensitive) */
michael@0 49 bool isType(const char type[], size_t len = 0) const;
michael@0 50
michael@0 51 /**
michael@0 52 * Set the event's type to the specified string.
michael@0 53 */
michael@0 54 void setType(const SkString&);
michael@0 55
michael@0 56 /**
michael@0 57 * Set the event's type to the specified string.
michael@0 58 */
michael@0 59 void setType(const char type[], size_t len = 0);
michael@0 60
michael@0 61 /**
michael@0 62 * Return the target ID, or 0 if there is none.
michael@0 63 *
michael@0 64 * When an event is dispatched from the event queue, it is either sent to
michael@0 65 * the eventsink matching the targetID (if not 0), or the target proc is
michael@0 66 * called (if not NULL).
michael@0 67 */
michael@0 68 SkEventSinkID getTargetID() const { return fTargetID; }
michael@0 69
michael@0 70 /**
michael@0 71 * Set the target ID for this event. 0 means none. Calling this will
michael@0 72 * automatically clear the targetProc to null.
michael@0 73 *
michael@0 74 * When an event is dispatched from the event queue, it is either sent to
michael@0 75 * the eventsink matching the targetID (if not 0), or the target proc is
michael@0 76 * called (if not NULL).
michael@0 77 */
michael@0 78 SkEvent* setTargetID(SkEventSinkID targetID) {
michael@0 79 fTargetProc = NULL;
michael@0 80 fTargetID = targetID;
michael@0 81 return this;
michael@0 82 }
michael@0 83
michael@0 84 /**
michael@0 85 * Return the target proc, or NULL if it has none.
michael@0 86 *
michael@0 87 * When an event is dispatched from the event queue, it is either sent to
michael@0 88 * the eventsink matching the targetID (if not 0), or the target proc is
michael@0 89 * called (if not NULL).
michael@0 90 */
michael@0 91 Proc getTargetProc() const { return fTargetProc; }
michael@0 92
michael@0 93 /**
michael@0 94 * Set the target ID for this event. NULL means none. Calling this will
michael@0 95 * automatically clear the targetID to 0.
michael@0 96 *
michael@0 97 * When an event is dispatched from the event queue, it is either sent to
michael@0 98 * the eventsink matching the targetID (if not 0), or the target proc is
michael@0 99 * called (if not NULL).
michael@0 100 */
michael@0 101 SkEvent* setTargetProc(Proc proc) {
michael@0 102 fTargetID = 0;
michael@0 103 fTargetProc = proc;
michael@0 104 return this;
michael@0 105 }
michael@0 106
michael@0 107 /**
michael@0 108 * Return the event's unnamed 32bit field. Default value is 0
michael@0 109 */
michael@0 110 uint32_t getFast32() const { return f32; }
michael@0 111
michael@0 112 /**
michael@0 113 * Set the event's unnamed 32bit field.
michael@0 114 */
michael@0 115 void setFast32(uint32_t x) { f32 = x; }
michael@0 116
michael@0 117 /** Return true if the event contains the named 32bit field, and return the field
michael@0 118 in value (if value is non-null). If there is no matching named field, return false
michael@0 119 and ignore the value parameter.
michael@0 120 */
michael@0 121 bool findS32(const char name[], int32_t* value = NULL) const { return fMeta.findS32(name, value); }
michael@0 122 /** Return true if the event contains the named SkScalar field, and return the field
michael@0 123 in value (if value is non-null). If there is no matching named field, return false
michael@0 124 and ignore the value parameter.
michael@0 125 */
michael@0 126 bool findScalar(const char name[], SkScalar* value = NULL) const { return fMeta.findScalar(name, value); }
michael@0 127 /** Return true if the event contains the named SkScalar field, and return the fields
michael@0 128 in value[] (if value is non-null), and return the number of SkScalars in count (if count is non-null).
michael@0 129 If there is no matching named field, return false and ignore the value and count parameters.
michael@0 130 */
michael@0 131 const SkScalar* findScalars(const char name[], int* count, SkScalar values[] = NULL) const { return fMeta.findScalars(name, count, values); }
michael@0 132 /** Return the value of the named string field, or if no matching named field exists, return null.
michael@0 133 */
michael@0 134 const char* findString(const char name[]) const { return fMeta.findString(name); }
michael@0 135 /** Return true if the event contains the named pointer field, and return the field
michael@0 136 in value (if value is non-null). If there is no matching named field, return false
michael@0 137 and ignore the value parameter.
michael@0 138 */
michael@0 139 bool findPtr(const char name[], void** value) const { return fMeta.findPtr(name, value); }
michael@0 140 bool findBool(const char name[], bool* value) const { return fMeta.findBool(name, value); }
michael@0 141 const void* findData(const char name[], size_t* byteCount = NULL) const {
michael@0 142 return fMeta.findData(name, byteCount);
michael@0 143 }
michael@0 144
michael@0 145 /** Returns true if ethe event contains the named 32bit field, and if it equals the specified value */
michael@0 146 bool hasS32(const char name[], int32_t value) const { return fMeta.hasS32(name, value); }
michael@0 147 /** Returns true if ethe event contains the named SkScalar field, and if it equals the specified value */
michael@0 148 bool hasScalar(const char name[], SkScalar value) const { return fMeta.hasScalar(name, value); }
michael@0 149 /** Returns true if ethe event contains the named string field, and if it equals (using strcmp) the specified value */
michael@0 150 bool hasString(const char name[], const char value[]) const { return fMeta.hasString(name, value); }
michael@0 151 /** Returns true if ethe event contains the named pointer field, and if it equals the specified value */
michael@0 152 bool hasPtr(const char name[], void* value) const { return fMeta.hasPtr(name, value); }
michael@0 153 bool hasBool(const char name[], bool value) const { return fMeta.hasBool(name, value); }
michael@0 154 bool hasData(const char name[], const void* data, size_t byteCount) const {
michael@0 155 return fMeta.hasData(name, data, byteCount);
michael@0 156 }
michael@0 157
michael@0 158 /** Add/replace the named 32bit field to the event. In XML use the subelement <data name=... s32=... /> */
michael@0 159 void setS32(const char name[], int32_t value) { fMeta.setS32(name, value); }
michael@0 160 /** Add/replace the named SkScalar field to the event. In XML use the subelement <data name=... scalar=... /> */
michael@0 161 void setScalar(const char name[], SkScalar value) { fMeta.setScalar(name, value); }
michael@0 162 /** Add/replace the named SkScalar[] field to the event. */
michael@0 163 SkScalar* setScalars(const char name[], int count, const SkScalar values[] = NULL) { return fMeta.setScalars(name, count, values); }
michael@0 164 /** Add/replace the named string field to the event. In XML use the subelement <data name=... string=... */
michael@0 165 void setString(const char name[], const SkString& value) { fMeta.setString(name, value.c_str()); }
michael@0 166 /** Add/replace the named string field to the event. In XML use the subelement <data name=... string=... */
michael@0 167 void setString(const char name[], const char value[]) { fMeta.setString(name, value); }
michael@0 168 /** Add/replace the named pointer field to the event. There is no XML equivalent for this call */
michael@0 169 void setPtr(const char name[], void* value) { fMeta.setPtr(name, value); }
michael@0 170 void setBool(const char name[], bool value) { fMeta.setBool(name, value); }
michael@0 171 void setData(const char name[], const void* data, size_t byteCount) {
michael@0 172 fMeta.setData(name, data, byteCount);
michael@0 173 }
michael@0 174
michael@0 175 /** Return the underlying metadata object */
michael@0 176 SkMetaData& getMetaData() { return fMeta; }
michael@0 177 /** Return the underlying metadata object */
michael@0 178 const SkMetaData& getMetaData() const { return fMeta; }
michael@0 179
michael@0 180 /** Call this to initialize the event from the specified XML node */
michael@0 181 void inflate(const SkDOM&, const SkDOM::Node*);
michael@0 182
michael@0 183 SkDEBUGCODE(void dump(const char title[] = NULL);)
michael@0 184
michael@0 185 ///////////////////////////////////////////////////////////////////////////
michael@0 186
michael@0 187 /**
michael@0 188 * Post to the event queue using the event's targetID or target-proc.
michael@0 189 *
michael@0 190 * The event must be dynamically allocated, as ownership is transferred to
michael@0 191 * the event queue. It cannot be allocated on the stack or in a global.
michael@0 192 */
michael@0 193 void post() {
michael@0 194 return this->postDelay(0);
michael@0 195 }
michael@0 196
michael@0 197 /**
michael@0 198 * Post to the event queue using the event's targetID or target-proc and
michael@0 199 * the specifed millisecond delay.
michael@0 200 *
michael@0 201 * The event must be dynamically allocated, as ownership is transferred to
michael@0 202 * the event queue. It cannot be allocated on the stack or in a global.
michael@0 203 */
michael@0 204 void postDelay(SkMSec delay);
michael@0 205
michael@0 206 /**
michael@0 207 * Post to the event queue using the event's targetID or target-proc.
michael@0 208 * The event will be delivered no sooner than the specified millisecond
michael@0 209 * time, as measured by SkTime::GetMSecs().
michael@0 210 *
michael@0 211 * The event must be dynamically allocated, as ownership is transferred to
michael@0 212 * the event queue. It cannot be allocated on the stack or in a global.
michael@0 213 */
michael@0 214 void postTime(SkMSec time);
michael@0 215
michael@0 216 ///////////////////////////////////////////////
michael@0 217 /** Porting layer must call these functions **/
michael@0 218 ///////////////////////////////////////////////
michael@0 219
michael@0 220 /** Global initialization function for the SkEvent system. Should be called exactly
michael@0 221 once before any other event method is called, and should be called after the
michael@0 222 call to SkGraphics::Init().
michael@0 223 */
michael@0 224 static void Init();
michael@0 225 /** Global cleanup function for the SkEvent system. Should be called exactly once after
michael@0 226 all event methods have been called, and should be called before calling SkGraphics::Term().
michael@0 227 */
michael@0 228 static void Term();
michael@0 229
michael@0 230 /** Call this to process one event from the queue. If it returns true, there are more events
michael@0 231 to process.
michael@0 232 */
michael@0 233 static bool ProcessEvent();
michael@0 234 /** Call this whenever the requested timer has expired (requested by a call to SetQueueTimer).
michael@0 235 It will post any delayed events whose time as "expired" onto the event queue.
michael@0 236 It may also call SignalQueueTimer() and SignalNonEmptyQueue().
michael@0 237 */
michael@0 238 static void ServiceQueueTimer();
michael@0 239
michael@0 240 /** Return the number of queued events. note that this value may be obsolete
michael@0 241 upon return, since another thread may have called ProcessEvent() or
michael@0 242 Post() after the count was made.
michael@0 243 */
michael@0 244 static int CountEventsOnQueue();
michael@0 245
michael@0 246 ////////////////////////////////////////////////////
michael@0 247 /** Porting layer must implement these functions **/
michael@0 248 ////////////////////////////////////////////////////
michael@0 249
michael@0 250 /** Called whenever an SkEvent is posted to an empty queue, so that the OS
michael@0 251 can be told to later call Dequeue().
michael@0 252 */
michael@0 253 static void SignalNonEmptyQueue();
michael@0 254 /** Called whenever the delay until the next delayed event changes. If zero is
michael@0 255 passed, then there are no more queued delay events.
michael@0 256 */
michael@0 257 static void SignalQueueTimer(SkMSec delay);
michael@0 258
michael@0 259 #if defined(SK_BUILD_FOR_WIN)
michael@0 260 static bool WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
michael@0 261 #endif
michael@0 262
michael@0 263 private:
michael@0 264 SkMetaData fMeta;
michael@0 265 mutable char* fType; // may be characters with low bit set to know that it is not a pointer
michael@0 266 uint32_t f32;
michael@0 267
michael@0 268 // 'there can be only one' (non-zero) between target-id and target-proc
michael@0 269 SkEventSinkID fTargetID;
michael@0 270 Proc fTargetProc;
michael@0 271
michael@0 272 // these are for our implementation of the event queue
michael@0 273 SkMSec fTime;
michael@0 274 SkEvent* fNextEvent; // either in the delay or normal event queue
michael@0 275
michael@0 276 void initialize(const char* type, size_t typeLen, SkEventSinkID);
michael@0 277
michael@0 278 static bool Enqueue(SkEvent* evt);
michael@0 279 static SkMSec EnqueueTime(SkEvent* evt, SkMSec time);
michael@0 280 static SkEvent* Dequeue();
michael@0 281 static bool QHasEvents();
michael@0 282 };
michael@0 283
michael@0 284 #endif

mercurial