1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/skia/trunk/include/views/SkEvent.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,284 @@ 1.4 +/* 1.5 + * Copyright 2006 The Android Open Source Project 1.6 + * 1.7 + * Use of this source code is governed by a BSD-style license that can be 1.8 + * found in the LICENSE file. 1.9 + */ 1.10 + 1.11 +#ifndef SkEvent_DEFINED 1.12 +#define SkEvent_DEFINED 1.13 + 1.14 +#include "SkDOM.h" 1.15 +#include "SkMetaData.h" 1.16 +#include "SkString.h" 1.17 + 1.18 +/** Unique 32bit id used to identify an instance of SkEventSink. When events are 1.19 + posted, they are posted to a specific sinkID. When it is time to dispatch the 1.20 + event, the sinkID is used to find the specific SkEventSink object. If it is found, 1.21 + its doEvent() method is called with the event. 1.22 +*/ 1.23 +typedef uint32_t SkEventSinkID; 1.24 + 1.25 +/** 1.26 + * \class SkEvent 1.27 + * 1.28 + * When an event is dispatched from the event queue, it is either sent to 1.29 + * the eventsink matching the target ID (if not 0), or the target proc is 1.30 + * called (if not NULL). 1.31 + */ 1.32 +class SkEvent { 1.33 +public: 1.34 + /** 1.35 + * Function pointer that takes an event, returns true if it "handled" it. 1.36 + */ 1.37 + typedef bool (*Proc)(const SkEvent& evt); 1.38 + 1.39 + SkEvent(); 1.40 + explicit SkEvent(const SkString& type, SkEventSinkID = 0); 1.41 + explicit SkEvent(const char type[], SkEventSinkID = 0); 1.42 + SkEvent(const SkEvent& src); 1.43 + ~SkEvent(); 1.44 + 1.45 + /** Copy the event's type into the specified SkString parameter */ 1.46 + void getType(SkString* str) const; 1.47 + 1.48 + /** Returns true if the event's type matches exactly the specified type (case sensitive) */ 1.49 + bool isType(const SkString& str) const; 1.50 + 1.51 + /** Returns true if the event's type matches exactly the specified type (case sensitive) */ 1.52 + bool isType(const char type[], size_t len = 0) const; 1.53 + 1.54 + /** 1.55 + * Set the event's type to the specified string. 1.56 + */ 1.57 + void setType(const SkString&); 1.58 + 1.59 + /** 1.60 + * Set the event's type to the specified string. 1.61 + */ 1.62 + void setType(const char type[], size_t len = 0); 1.63 + 1.64 + /** 1.65 + * Return the target ID, or 0 if there is none. 1.66 + * 1.67 + * When an event is dispatched from the event queue, it is either sent to 1.68 + * the eventsink matching the targetID (if not 0), or the target proc is 1.69 + * called (if not NULL). 1.70 + */ 1.71 + SkEventSinkID getTargetID() const { return fTargetID; } 1.72 + 1.73 + /** 1.74 + * Set the target ID for this event. 0 means none. Calling this will 1.75 + * automatically clear the targetProc to null. 1.76 + * 1.77 + * When an event is dispatched from the event queue, it is either sent to 1.78 + * the eventsink matching the targetID (if not 0), or the target proc is 1.79 + * called (if not NULL). 1.80 + */ 1.81 + SkEvent* setTargetID(SkEventSinkID targetID) { 1.82 + fTargetProc = NULL; 1.83 + fTargetID = targetID; 1.84 + return this; 1.85 + } 1.86 + 1.87 + /** 1.88 + * Return the target proc, or NULL if it has none. 1.89 + * 1.90 + * When an event is dispatched from the event queue, it is either sent to 1.91 + * the eventsink matching the targetID (if not 0), or the target proc is 1.92 + * called (if not NULL). 1.93 + */ 1.94 + Proc getTargetProc() const { return fTargetProc; } 1.95 + 1.96 + /** 1.97 + * Set the target ID for this event. NULL means none. Calling this will 1.98 + * automatically clear the targetID to 0. 1.99 + * 1.100 + * When an event is dispatched from the event queue, it is either sent to 1.101 + * the eventsink matching the targetID (if not 0), or the target proc is 1.102 + * called (if not NULL). 1.103 + */ 1.104 + SkEvent* setTargetProc(Proc proc) { 1.105 + fTargetID = 0; 1.106 + fTargetProc = proc; 1.107 + return this; 1.108 + } 1.109 + 1.110 + /** 1.111 + * Return the event's unnamed 32bit field. Default value is 0 1.112 + */ 1.113 + uint32_t getFast32() const { return f32; } 1.114 + 1.115 + /** 1.116 + * Set the event's unnamed 32bit field. 1.117 + */ 1.118 + void setFast32(uint32_t x) { f32 = x; } 1.119 + 1.120 + /** Return true if the event contains the named 32bit field, and return the field 1.121 + in value (if value is non-null). If there is no matching named field, return false 1.122 + and ignore the value parameter. 1.123 + */ 1.124 + bool findS32(const char name[], int32_t* value = NULL) const { return fMeta.findS32(name, value); } 1.125 + /** Return true if the event contains the named SkScalar field, and return the field 1.126 + in value (if value is non-null). If there is no matching named field, return false 1.127 + and ignore the value parameter. 1.128 + */ 1.129 + bool findScalar(const char name[], SkScalar* value = NULL) const { return fMeta.findScalar(name, value); } 1.130 + /** Return true if the event contains the named SkScalar field, and return the fields 1.131 + in value[] (if value is non-null), and return the number of SkScalars in count (if count is non-null). 1.132 + If there is no matching named field, return false and ignore the value and count parameters. 1.133 + */ 1.134 + const SkScalar* findScalars(const char name[], int* count, SkScalar values[] = NULL) const { return fMeta.findScalars(name, count, values); } 1.135 + /** Return the value of the named string field, or if no matching named field exists, return null. 1.136 + */ 1.137 + const char* findString(const char name[]) const { return fMeta.findString(name); } 1.138 + /** Return true if the event contains the named pointer field, and return the field 1.139 + in value (if value is non-null). If there is no matching named field, return false 1.140 + and ignore the value parameter. 1.141 + */ 1.142 + bool findPtr(const char name[], void** value) const { return fMeta.findPtr(name, value); } 1.143 + bool findBool(const char name[], bool* value) const { return fMeta.findBool(name, value); } 1.144 + const void* findData(const char name[], size_t* byteCount = NULL) const { 1.145 + return fMeta.findData(name, byteCount); 1.146 + } 1.147 + 1.148 + /** Returns true if ethe event contains the named 32bit field, and if it equals the specified value */ 1.149 + bool hasS32(const char name[], int32_t value) const { return fMeta.hasS32(name, value); } 1.150 + /** Returns true if ethe event contains the named SkScalar field, and if it equals the specified value */ 1.151 + bool hasScalar(const char name[], SkScalar value) const { return fMeta.hasScalar(name, value); } 1.152 + /** Returns true if ethe event contains the named string field, and if it equals (using strcmp) the specified value */ 1.153 + bool hasString(const char name[], const char value[]) const { return fMeta.hasString(name, value); } 1.154 + /** Returns true if ethe event contains the named pointer field, and if it equals the specified value */ 1.155 + bool hasPtr(const char name[], void* value) const { return fMeta.hasPtr(name, value); } 1.156 + bool hasBool(const char name[], bool value) const { return fMeta.hasBool(name, value); } 1.157 + bool hasData(const char name[], const void* data, size_t byteCount) const { 1.158 + return fMeta.hasData(name, data, byteCount); 1.159 + } 1.160 + 1.161 + /** Add/replace the named 32bit field to the event. In XML use the subelement <data name=... s32=... /> */ 1.162 + void setS32(const char name[], int32_t value) { fMeta.setS32(name, value); } 1.163 + /** Add/replace the named SkScalar field to the event. In XML use the subelement <data name=... scalar=... /> */ 1.164 + void setScalar(const char name[], SkScalar value) { fMeta.setScalar(name, value); } 1.165 + /** Add/replace the named SkScalar[] field to the event. */ 1.166 + SkScalar* setScalars(const char name[], int count, const SkScalar values[] = NULL) { return fMeta.setScalars(name, count, values); } 1.167 + /** Add/replace the named string field to the event. In XML use the subelement <data name=... string=... */ 1.168 + void setString(const char name[], const SkString& value) { fMeta.setString(name, value.c_str()); } 1.169 + /** Add/replace the named string field to the event. In XML use the subelement <data name=... string=... */ 1.170 + void setString(const char name[], const char value[]) { fMeta.setString(name, value); } 1.171 + /** Add/replace the named pointer field to the event. There is no XML equivalent for this call */ 1.172 + void setPtr(const char name[], void* value) { fMeta.setPtr(name, value); } 1.173 + void setBool(const char name[], bool value) { fMeta.setBool(name, value); } 1.174 + void setData(const char name[], const void* data, size_t byteCount) { 1.175 + fMeta.setData(name, data, byteCount); 1.176 + } 1.177 + 1.178 + /** Return the underlying metadata object */ 1.179 + SkMetaData& getMetaData() { return fMeta; } 1.180 + /** Return the underlying metadata object */ 1.181 + const SkMetaData& getMetaData() const { return fMeta; } 1.182 + 1.183 + /** Call this to initialize the event from the specified XML node */ 1.184 + void inflate(const SkDOM&, const SkDOM::Node*); 1.185 + 1.186 + SkDEBUGCODE(void dump(const char title[] = NULL);) 1.187 + 1.188 + /////////////////////////////////////////////////////////////////////////// 1.189 + 1.190 + /** 1.191 + * Post to the event queue using the event's targetID or target-proc. 1.192 + * 1.193 + * The event must be dynamically allocated, as ownership is transferred to 1.194 + * the event queue. It cannot be allocated on the stack or in a global. 1.195 + */ 1.196 + void post() { 1.197 + return this->postDelay(0); 1.198 + } 1.199 + 1.200 + /** 1.201 + * Post to the event queue using the event's targetID or target-proc and 1.202 + * the specifed millisecond delay. 1.203 + * 1.204 + * The event must be dynamically allocated, as ownership is transferred to 1.205 + * the event queue. It cannot be allocated on the stack or in a global. 1.206 + */ 1.207 + void postDelay(SkMSec delay); 1.208 + 1.209 + /** 1.210 + * Post to the event queue using the event's targetID or target-proc. 1.211 + * The event will be delivered no sooner than the specified millisecond 1.212 + * time, as measured by SkTime::GetMSecs(). 1.213 + * 1.214 + * The event must be dynamically allocated, as ownership is transferred to 1.215 + * the event queue. It cannot be allocated on the stack or in a global. 1.216 + */ 1.217 + void postTime(SkMSec time); 1.218 + 1.219 + /////////////////////////////////////////////// 1.220 + /** Porting layer must call these functions **/ 1.221 + /////////////////////////////////////////////// 1.222 + 1.223 + /** Global initialization function for the SkEvent system. Should be called exactly 1.224 + once before any other event method is called, and should be called after the 1.225 + call to SkGraphics::Init(). 1.226 + */ 1.227 + static void Init(); 1.228 + /** Global cleanup function for the SkEvent system. Should be called exactly once after 1.229 + all event methods have been called, and should be called before calling SkGraphics::Term(). 1.230 + */ 1.231 + static void Term(); 1.232 + 1.233 + /** Call this to process one event from the queue. If it returns true, there are more events 1.234 + to process. 1.235 + */ 1.236 + static bool ProcessEvent(); 1.237 + /** Call this whenever the requested timer has expired (requested by a call to SetQueueTimer). 1.238 + It will post any delayed events whose time as "expired" onto the event queue. 1.239 + It may also call SignalQueueTimer() and SignalNonEmptyQueue(). 1.240 + */ 1.241 + static void ServiceQueueTimer(); 1.242 + 1.243 + /** Return the number of queued events. note that this value may be obsolete 1.244 + upon return, since another thread may have called ProcessEvent() or 1.245 + Post() after the count was made. 1.246 + */ 1.247 + static int CountEventsOnQueue(); 1.248 + 1.249 + //////////////////////////////////////////////////// 1.250 + /** Porting layer must implement these functions **/ 1.251 + //////////////////////////////////////////////////// 1.252 + 1.253 + /** Called whenever an SkEvent is posted to an empty queue, so that the OS 1.254 + can be told to later call Dequeue(). 1.255 + */ 1.256 + static void SignalNonEmptyQueue(); 1.257 + /** Called whenever the delay until the next delayed event changes. If zero is 1.258 + passed, then there are no more queued delay events. 1.259 + */ 1.260 + static void SignalQueueTimer(SkMSec delay); 1.261 + 1.262 +#if defined(SK_BUILD_FOR_WIN) 1.263 + static bool WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); 1.264 +#endif 1.265 + 1.266 +private: 1.267 + SkMetaData fMeta; 1.268 + mutable char* fType; // may be characters with low bit set to know that it is not a pointer 1.269 + uint32_t f32; 1.270 + 1.271 + // 'there can be only one' (non-zero) between target-id and target-proc 1.272 + SkEventSinkID fTargetID; 1.273 + Proc fTargetProc; 1.274 + 1.275 + // these are for our implementation of the event queue 1.276 + SkMSec fTime; 1.277 + SkEvent* fNextEvent; // either in the delay or normal event queue 1.278 + 1.279 + void initialize(const char* type, size_t typeLen, SkEventSinkID); 1.280 + 1.281 + static bool Enqueue(SkEvent* evt); 1.282 + static SkMSec EnqueueTime(SkEvent* evt, SkMSec time); 1.283 + static SkEvent* Dequeue(); 1.284 + static bool QHasEvents(); 1.285 +}; 1.286 + 1.287 +#endif