diff options
-rw-r--r-- | include/views/SkEvent.h | 231 | ||||
-rw-r--r-- | include/views/SkEventSink.h | 75 | ||||
-rw-r--r-- | include/views/SkOSMenu.h | 4 | ||||
-rw-r--r-- | include/views/SkView.h | 4 | ||||
-rw-r--r-- | samplecode/SampleApp.cpp | 7 | ||||
-rw-r--r-- | samplecode/SampleGM.cpp | 2 | ||||
-rw-r--r-- | samplecode/SamplePicture.cpp | 2 | ||||
-rw-r--r-- | samplecode/SampleXfermodesBlur.cpp | 24 | ||||
-rw-r--r-- | src/animator/SkAnimateMaker.cpp | 6 | ||||
-rw-r--r-- | src/animator/SkAnimator.cpp | 4 | ||||
-rw-r--r-- | src/utils/mac/SkOSWindow_Mac.cpp | 3 | ||||
-rw-r--r-- | src/views/SkEvent.cpp | 168 | ||||
-rw-r--r-- | src/views/SkEventSink.cpp | 55 |
13 files changed, 275 insertions, 310 deletions
diff --git a/include/views/SkEvent.h b/include/views/SkEvent.h index 71a2a72527..b3a07e9551 100644 --- a/include/views/SkEvent.h +++ b/include/views/SkEvent.h @@ -21,71 +21,111 @@ */ typedef uint32_t SkEventSinkID; -/** \class SkEvent - - SkEvents are used to communicate type-safe information to SkEventSinks. - SkEventSinks (including SkViews) each have a unique ID, which is stored - in an event. This ID is used to target the event once it has been "posted". -*/ +/** + * \class SkEvent + * + * When an event is dispatched from the event queue, it is either sent to + * the eventsink matching the target ID (if not 0), or the target proc is + * called (if not NULL). + */ class SkEvent { public: - /** Default construct, creating an empty event. - */ + /** + * Function pointer that takes an event, returns true if it "handled" it. + */ + typedef bool (*Proc)(const SkEvent& evt); + SkEvent(); - /** Construct a new event with the specified type. - */ - explicit SkEvent(const SkString& type); - /** Construct a new event with the specified type. - */ - explicit SkEvent(const char type[]); - /** Construct a new event by copying the fields from the src event. - */ + explicit SkEvent(const SkString& type, SkEventSinkID = 0); + explicit SkEvent(const char type[], SkEventSinkID = 0); SkEvent(const SkEvent& src); ~SkEvent(); /** Copy the event's type into the specified SkString parameter */ - void getType(SkString* str) const; + void getType(SkString* str) const; + /** Returns true if the event's type matches exactly the specified type (case sensitive) */ - bool isType(const SkString& str) const; + bool isType(const SkString& str) const; + /** Returns true if the event's type matches exactly the specified type (case sensitive) */ - bool isType(const char type[], size_t len = 0) const; - /** Set the event's type to the specified string. - In XML, use the "type" attribute. - */ - void setType(const SkString&); - /** Set the event's type to the specified string. - In XML, use the "type" attribute. - */ - void setType(const char type[], size_t len = 0); + bool isType(const char type[], size_t len = 0) const; + + /** + * Set the event's type to the specified string. + */ + void setType(const SkString&); + + /** + * Set the event's type to the specified string. + */ + void setType(const char type[], size_t len = 0); /** * Return the target ID, or 0 if there is none. + * + * When an event is dispatched from the event queue, it is either sent to + * the eventsink matching the targetID (if not 0), or the target proc is + * called (if not NULL). */ SkEventSinkID getTargetID() const { return fTargetID; } /** - * Set the target ID for this event. 0 means none. Can be specified when - * the event is posted or sent. + * Set the target ID for this event. 0 means none. Calling this will + * automatically clear the targetProc to null. + * + * When an event is dispatched from the event queue, it is either sent to + * the eventsink matching the targetID (if not 0), or the target proc is + * called (if not NULL). */ - void setTargetID(SkEventSinkID targetID) { fTargetID = targetID; } + SkEvent* setTargetID(SkEventSinkID targetID) { + fTargetProc = NULL; + fTargetID = targetID; + return this; + } - /** Return the event's unnamed 32bit field. Default value is 0 */ + /** + * Return the target proc, or NULL if it has none. + * + * When an event is dispatched from the event queue, it is either sent to + * the eventsink matching the targetID (if not 0), or the target proc is + * called (if not NULL). + */ + Proc getTargetProc() const { return fTargetProc; } + + /** + * Set the target ID for this event. NULL means none. Calling this will + * automatically clear the targetID to 0. + * + * When an event is dispatched from the event queue, it is either sent to + * the eventsink matching the targetID (if not 0), or the target proc is + * called (if not NULL). + */ + SkEvent* setTargetProc(Proc proc) { + fTargetID = 0; + fTargetProc = proc; + return this; + } + + /** + * Return the event's unnamed 32bit field. Default value is 0 + */ uint32_t getFast32() const { return f32; } - /** Set the event's unnamed 32bit field. In XML, use - the subelement <data fast32=... /> - */ - void setFast32(uint32_t x) { f32 = x; } + + /** + * Set the event's unnamed 32bit field. + */ + void setFast32(uint32_t x) { f32 = x; } /** Return true if the event contains the named 32bit field, and return the field in value (if value is non-null). If there is no matching named field, return false and ignore the value parameter. */ - bool findS32(const char name[], int32_t* value = NULL) const { return fMeta.findS32(name, value); } + bool findS32(const char name[], int32_t* value = NULL) const { return fMeta.findS32(name, value); } /** Return true if the event contains the named SkScalar field, and return the field in value (if value is non-null). If there is no matching named field, return false and ignore the value parameter. */ - bool findScalar(const char name[], SkScalar* value = NULL) const { return fMeta.findScalar(name, value); } + bool findScalar(const char name[], SkScalar* value = NULL) const { return fMeta.findScalar(name, value); } /** Return true if the event contains the named SkScalar field, and return the fields in value[] (if value is non-null), and return the number of SkScalars in count (if count is non-null). If there is no matching named field, return false and ignore the value and count parameters. @@ -98,112 +138,82 @@ public: in value (if value is non-null). If there is no matching named field, return false and ignore the value parameter. */ - bool findPtr(const char name[], void** value) const { return fMeta.findPtr(name, value); } - bool findBool(const char name[], bool* value) const { return fMeta.findBool(name, value); } + bool findPtr(const char name[], void** value) const { return fMeta.findPtr(name, value); } + bool findBool(const char name[], bool* value) const { return fMeta.findBool(name, value); } const void* findData(const char name[], size_t* byteCount = NULL) const { return fMeta.findData(name, byteCount); } /** Returns true if ethe event contains the named 32bit field, and if it equals the specified value */ - bool hasS32(const char name[], int32_t value) const { return fMeta.hasS32(name, value); } + bool hasS32(const char name[], int32_t value) const { return fMeta.hasS32(name, value); } /** Returns true if ethe event contains the named SkScalar field, and if it equals the specified value */ - bool hasScalar(const char name[], SkScalar value) const { return fMeta.hasScalar(name, value); } + bool hasScalar(const char name[], SkScalar value) const { return fMeta.hasScalar(name, value); } /** Returns true if ethe event contains the named string field, and if it equals (using strcmp) the specified value */ - bool hasString(const char name[], const char value[]) const { return fMeta.hasString(name, value); } + bool hasString(const char name[], const char value[]) const { return fMeta.hasString(name, value); } /** Returns true if ethe event contains the named pointer field, and if it equals the specified value */ - bool hasPtr(const char name[], void* value) const { return fMeta.hasPtr(name, value); } - bool hasBool(const char name[], bool value) const { return fMeta.hasBool(name, value); } + bool hasPtr(const char name[], void* value) const { return fMeta.hasPtr(name, value); } + bool hasBool(const char name[], bool value) const { return fMeta.hasBool(name, value); } bool hasData(const char name[], const void* data, size_t byteCount) const { return fMeta.hasData(name, data, byteCount); } /** Add/replace the named 32bit field to the event. In XML use the subelement <data name=... s32=... /> */ - void setS32(const char name[], int32_t value) { fMeta.setS32(name, value); } + void setS32(const char name[], int32_t value) { fMeta.setS32(name, value); } /** Add/replace the named SkScalar field to the event. In XML use the subelement <data name=... scalar=... /> */ - void setScalar(const char name[], SkScalar value) { fMeta.setScalar(name, value); } + void setScalar(const char name[], SkScalar value) { fMeta.setScalar(name, value); } /** Add/replace the named SkScalar[] field to the event. */ SkScalar* setScalars(const char name[], int count, const SkScalar values[] = NULL) { return fMeta.setScalars(name, count, values); } /** Add/replace the named string field to the event. In XML use the subelement <data name=... string=... */ - void setString(const char name[], const SkString& value) { fMeta.setString(name, value.c_str()); } + void setString(const char name[], const SkString& value) { fMeta.setString(name, value.c_str()); } /** Add/replace the named string field to the event. In XML use the subelement <data name=... string=... */ - void setString(const char name[], const char value[]) { fMeta.setString(name, value); } + void setString(const char name[], const char value[]) { fMeta.setString(name, value); } /** Add/replace the named pointer field to the event. There is no XML equivalent for this call */ - void setPtr(const char name[], void* value) { fMeta.setPtr(name, value); } - void setBool(const char name[], bool value) { fMeta.setBool(name, value); } + void setPtr(const char name[], void* value) { fMeta.setPtr(name, value); } + void setBool(const char name[], bool value) { fMeta.setBool(name, value); } void setData(const char name[], const void* data, size_t byteCount) { fMeta.setData(name, data, byteCount); } /** Return the underlying metadata object */ - SkMetaData& getMetaData() { return fMeta; } + SkMetaData& getMetaData() { return fMeta; } /** Return the underlying metadata object */ - const SkMetaData& getMetaData() const { return fMeta; } - - void tron() { SkDEBUGCODE(fDebugTrace = true;) } - void troff() { SkDEBUGCODE(fDebugTrace = false;) } - bool isDebugTrace() const - { -#ifdef SK_DEBUG - return fDebugTrace; -#else - return false; -#endif - } + const SkMetaData& getMetaData() const { return fMeta; } /** Call this to initialize the event from the specified XML node */ - void inflate(const SkDOM&, const SkDOM::Node*); + void inflate(const SkDOM&, const SkDOM::Node*); SkDEBUGCODE(void dump(const char title[] = NULL);) - /** Post the specified event to the event queue, targeting the specified eventsink, with an optional - delay. The event must be dynamically allocated for this. It cannot be a global or on the stack. - After this call, ownership is transfered to the system, so the caller must not retain - the event's ptr. Returns false if the event could not be posted (which means it will have been deleted). - */ - static bool Post(SkEvent* evt, SkEventSinkID targetID, SkMSec delay = 0); - /** Post the specified event to the event queue, targeting the specified eventsink, to be delivered on/after the - specified millisecond time. The event must be dynamically allocated for this. It cannot be a global or on the stack. - After this call, ownership is transfered to the system, so the caller must not retain - the event's ptr. Returns false if the event could not be posted (which means it will have been deleted). - */ - static bool PostTime(SkEvent* evt, SkEventSinkID targetID, SkMSec time); + /////////////////////////////////////////////////////////////////////////// /** - * Post to the event queue using the event's targetID. If this is 0, then - * false is returned and the event is deleted, otherwise true is returned - * and ownership of the event passes to the event queue. + * Post to the event queue using the event's targetID or target-proc. + * + * The event must be dynamically allocated, as ownership is transferred to + * the event queue. It cannot be allocated on the stack or in a global. */ - bool post() { + void post() { return this->postDelay(0); } /** - * Post to the event queue using the event's targetID and the specifed - * millisecond delay. If the event's targetID is 0, then false is returned - * and the event is deleted, otherwise true is returned and ownership of - * the event passes to the event queue. + * Post to the event queue using the event's targetID or target-proc and + * the specifed millisecond delay. + * + * The event must be dynamically allocated, as ownership is transferred to + * the event queue. It cannot be allocated on the stack or in a global. */ - bool postDelay(SkMSec delay); + void postDelay(SkMSec delay); /** - * Post to the event queue using the event's targetID and the specifed - * millisecond time. If the event's targetID is 0, then false is returned - * and the event is deleted, otherwise true is returned and ownership of - * the event passes to the event queue. + * Post to the event queue using the event's targetID or target-proc. + * The event will be delivered no sooner than the specified millisecond + * time, as measured by SkTime::GetMSecs(). + * + * The event must be dynamically allocated, as ownership is transferred to + * the event queue. It cannot be allocated on the stack or in a global. */ - bool postTime(SkMSec time); - - /** Helper method for calling SkEvent::PostTime(this, ...), where the caller specifies a delay. - The real "time" will be computed automatically by sampling the clock and adding its value - to delay. - */ - bool post(SkEventSinkID sinkID, SkMSec delay = 0) { - return SkEvent::Post(this, sinkID, delay); - } - - void postTime(SkEventSinkID sinkID, SkMSec time) { - SkEvent::PostTime(this, sinkID, time); - } + void postTime(SkMSec time); /////////////////////////////////////////////// /** Porting layer must call these functions **/ @@ -213,21 +223,21 @@ public: once before any other event method is called, and should be called after the call to SkGraphics::Init(). */ - static void Init(); + static void Init(); /** Global cleanup function for the SkEvent system. Should be called exactly once after all event methods have been called, and should be called before calling SkGraphics::Term(). */ - static void Term(); + static void Term(); /** Call this to process one event from the queue. If it returns true, there are more events to process. */ - static bool ProcessEvent(); + static bool ProcessEvent(); /** Call this whenever the requested timer has expired (requested by a call to SetQueueTimer). It will post any delayed events whose time as "expired" onto the event queue. It may also call SignalQueueTimer() and SignalNonEmptyQueue(). */ - static void ServiceQueueTimer(); + static void ServiceQueueTimer(); /** Return the number of queued events. note that this value may be obsolete upon return, since another thread may have called ProcessEvent() or @@ -264,17 +274,20 @@ private: SkMetaData fMeta; mutable char* fType; // may be characters with low bit set to know that it is not a pointer uint32_t f32; + + // 'there can be only one' (non-zero) between target-id and target-proc SkEventSinkID fTargetID; - SkDEBUGCODE(bool fDebugTrace;) + Proc fTargetProc; // these are for our implementation of the event queue SkMSec fTime; SkEvent* fNextEvent; // either in the delay or normal event queue - void initialize(const char* type, size_t typeLen); + + void initialize(const char* type, size_t typeLen, SkEventSinkID); static bool Enqueue(SkEvent* evt); static SkMSec EnqueueTime(SkEvent* evt, SkMSec time); - static SkEvent* Dequeue(SkEventSinkID* targetID); + static SkEvent* Dequeue(); static bool QHasEvents(); }; diff --git a/include/views/SkEventSink.h b/include/views/SkEventSink.h index 6ba4dfad08..69981facff 100644 --- a/include/views/SkEventSink.h +++ b/include/views/SkEventSink.h @@ -24,53 +24,66 @@ public: SkEventSink(); virtual ~SkEventSink(); - /** Returns this eventsink's unique ID. Use this to post SkEvents to - this eventsink. - */ + /** + * Returns this eventsink's unique ID. Use this to post SkEvents to + * this eventsink. + */ SkEventSinkID getSinkID() const { return fID; } - /** Call this to pass an event to this object for processing. Returns true if the - event was handled. - */ + /** + * Call this to pass an event to this object for processing. Returns true if the + * event was handled. + */ bool doEvent(const SkEvent&); + /** Returns true if the sink (or one of its subclasses) understands the event as a query. If so, the sink may modify the event to communicate its "answer". */ bool doQuery(SkEvent* query); - /** Add sinkID to the list of listeners, to receive events from calls to sendToListeners() - and postToListeners(). If sinkID already exists in the listener list, no change is made. - */ - void addListenerID(SkEventSinkID sinkID); - /** Copy listeners from one event sink to another, typically from parent to child. - @param from the event sink to copy the listeners from - */ + /** + * Add sinkID to the list of listeners, to receive events from calls to sendToListeners() + * and postToListeners(). If sinkID already exists in the listener list, no change is made. + */ + void addListenerID(SkEventSinkID sinkID); + + /** + * Copy listeners from one event sink to another, typically from parent to child. + * @param from the event sink to copy the listeners from + */ void copyListeners(const SkEventSink& from); - /** Remove sinkID from the list of listeners. If sinkID does not appear in the list, - no change is made. - */ - void removeListenerID(SkEventSinkID); - /** Returns true if there are 1 or more listeners attached to this eventsink - */ - bool hasListeners() const; - /** Posts a copy of evt to each of the eventsinks in the lisener list. - */ - void postToListeners(const SkEvent& evt, SkMSec delay = 0); + + /** + * Remove sinkID from the list of listeners. If sinkID does not appear in the list, + * no change is made. + */ + void removeListenerID(SkEventSinkID); + + /** + * Returns true if there are 1 or more listeners attached to this eventsink + */ + bool hasListeners() const; + + /** + * Posts a copy of evt to each of the eventsinks in the lisener list. + * This ignores the targetID and target proc in evt. + */ + void postToListeners(const SkEvent& evt, SkMSec delay = 0); enum EventResult { kHandled_EventResult, //!< the eventsink returned true from its doEvent method kNotHandled_EventResult, //!< the eventsink returned false from its doEvent method kSinkNotFound_EventResult //!< no matching eventsink was found for the event's getSink(). }; - /** DoEvent handles searching for an eventsink object that matches the targetID. - If one is found, it calls the sink's doEvent method, returning - either kHandled_EventResult or kNotHandled_EventResult. If no matching - eventsink is found, kSinkNotFound_EventResult is returned. - */ - static EventResult DoEvent(const SkEvent&, SkEventSinkID targetID); - /** Returns the matching eventsink, or null if not found - */ + /** + * DoEvent handles dispatching the event to its target ID or proc. + */ + static EventResult DoEvent(const SkEvent&); + + /** + * Returns the matching eventsink, or null if not found + */ static SkEventSink* FindSink(SkEventSinkID); protected: diff --git a/include/views/SkOSMenu.h b/include/views/SkOSMenu.h index 2dbc1a5a36..54c7dbe249 100644 --- a/include/views/SkOSMenu.h +++ b/include/views/SkOSMenu.h @@ -64,7 +64,9 @@ public: //Post event associated with the menu item to target, any changes to the //associated event must be made prior to calling this method. - void postEvent() const { (new SkEvent(*(fEvent)))->post(fTarget); } + void postEvent() const { + (new SkEvent(*(fEvent)))->setTargetID(fTarget)->post(); + } //Helper functions for predefined types void postEventWithBool(bool value) const; //For Switch diff --git a/include/views/SkView.h b/include/views/SkView.h index acac745c10..5cb6e4aff5 100644 --- a/include/views/SkView.h +++ b/include/views/SkView.h @@ -162,10 +162,6 @@ public: */ SkView* sendQueryToParents(SkEvent*); - /** Depricated helper function. Just call event->post(sinkID, delay); - */ - bool postEvent(SkEvent* evt, SkEventSinkID sinkID, SkMSec delay) { return evt->post(sinkID, delay); } - // View hierarchy management /** Return the view's parent, or null if it has none. This does not affect the parent's reference count. */ diff --git a/samplecode/SampleApp.cpp b/samplecode/SampleApp.cpp index 0d70f660df..92004f9e31 100644 --- a/samplecode/SampleApp.cpp +++ b/samplecode/SampleApp.cpp @@ -156,8 +156,7 @@ private: static const char view_inval_msg[] = "view-inval-msg"; void SampleWindow::postInvalDelay() { - SkEvent* evt = new SkEvent(view_inval_msg); - evt->post(this->getSinkID(), 1); + (new SkEvent(view_inval_msg, this->getSinkID()))->postDelay(1); } static bool isInvalEvent(const SkEvent& evt) { @@ -1002,8 +1001,7 @@ int SampleWindow::sampleCount() { void SampleWindow::postAnimatingEvent() { if (fAnimating) { - SkEvent* evt = new SkEvent(ANIMATING_EVENTTYPE); - evt->post(this->getSinkID(), ANIMATING_DELAY); + (new SkEvent(ANIMATING_EVENTTYPE, this->getSinkID()))->postDelay(ANIMATING_DELAY); } } @@ -1416,6 +1414,7 @@ void SampleWindow::loadView(SkView* view) { if (NULL == view) { view = create_overview(fSamples.count(), fSamples.begin()); } + view->setVisibleP(true); view->setClipToBounds(false); this->attachChildToFront(view)->unref(); diff --git a/samplecode/SampleGM.cpp b/samplecode/SampleGM.cpp index 7319af8aa3..2d172af3dc 100644 --- a/samplecode/SampleGM.cpp +++ b/samplecode/SampleGM.cpp @@ -96,7 +96,7 @@ protected: private: void postNextGM() { - (new SkEvent("next-gm"))->post(this->getSinkID(), 1500); + (new SkEvent("next-gm", this->getSinkID()))->postDelay(1500); } typedef SampleView INHERITED; diff --git a/samplecode/SamplePicture.cpp b/samplecode/SamplePicture.cpp index d0ec092942..d2c9d659cc 100644 --- a/samplecode/SamplePicture.cpp +++ b/samplecode/SamplePicture.cpp @@ -173,7 +173,7 @@ private: #define INVAL_ALL_TYPE "inval-all" void delayInval(SkMSec delay) { - (new SkEvent(INVAL_ALL_TYPE))->post(this->getSinkID(), delay); + (new SkEvent(INVAL_ALL_TYPE, this->getSinkID()))->postDelay(delay); } virtual bool onEvent(const SkEvent& evt) { diff --git a/samplecode/SampleXfermodesBlur.cpp b/samplecode/SampleXfermodesBlur.cpp index c1aaf98e33..f0dcf312ab 100644 --- a/samplecode/SampleXfermodesBlur.cpp +++ b/samplecode/SampleXfermodesBlur.cpp @@ -95,6 +95,30 @@ protected: virtual void onDrawContent(SkCanvas* canvas) { canvas->translate(SkIntToScalar(10), SkIntToScalar(20)); + if (false) { + SkPaint paint; + paint.setAntiAlias(true); + paint.setTextSize(50); + paint.setTypeface(SkTypeface::CreateFromName("Arial Unicode MS", SkTypeface::kNormal)); + SkSafeUnref(paint.getTypeface()); + char buffer[10]; + size_t len = SkUTF8_FromUnichar(0x8500, buffer); + canvas->drawText(buffer, len, 40, 40, paint); + return; + } + if (true) { + SkPaint paint; + paint.setAntiAlias(true); + + SkRect r0 = { 0, 0, 10.5f, 20 }; + SkRect r1 = { 10.5f, 10, 20, 30 }; + paint.setColor(SK_ColorRED); + canvas->drawRect(r0, paint); + paint.setColor(SK_ColorBLUE); + canvas->drawRect(r1, paint); + return; + } + const struct { SkXfermode::Mode fMode; const char* fLabel; diff --git a/src/animator/SkAnimateMaker.cpp b/src/animator/SkAnimateMaker.cpp index ce4ddfdec7..414e728979 100644 --- a/src/animator/SkAnimateMaker.cpp +++ b/src/animator/SkAnimateMaker.cpp @@ -121,9 +121,11 @@ extern "C" { void SkAnimateMaker::delayEnable(SkApply* apply, SkMSec time) { int index = fDelayed.find(apply); - if (index < 0) + if (index < 0) { *fDelayed.append() = apply; - (new SkEvent(SK_EventType_Delay))->postTime(fAnimator->getSinkID(), time); + } + + (new SkEvent(SK_EventType_Delay, fAnimator->getSinkID()))->postTime(time); } void SkAnimateMaker::deleteMembers() { diff --git a/src/animator/SkAnimator.cpp b/src/animator/SkAnimator.cpp index 9b5b061c29..a8f23fe9b5 100644 --- a/src/animator/SkAnimator.cpp +++ b/src/animator/SkAnimator.cpp @@ -479,7 +479,7 @@ void SkAnimator::onEventPost(SkEvent* evt, SkEventSinkID sinkID) #else SkASSERT(sinkID == this->getSinkID() || this->getHostEventSinkID() == sinkID); #endif - SkEvent::Post(evt, sinkID); + evt->setTargetID(sinkID)->post(); } void SkAnimator::onEventPostTime(SkEvent* evt, SkEventSinkID sinkID, SkMSec time) @@ -493,7 +493,7 @@ void SkAnimator::onEventPostTime(SkEvent* evt, SkEventSinkID sinkID, SkMSec time #else SkASSERT(sinkID == this->getSinkID() || this->getHostEventSinkID() == sinkID); #endif - SkEvent::PostTime(evt, sinkID, time); + evt->setTargetID(sinkID)->postTime(time); } void SkAnimator::reset() { diff --git a/src/utils/mac/SkOSWindow_Mac.cpp b/src/utils/mac/SkOSWindow_Mac.cpp index 5731a4d1a6..2940cbdc12 100644 --- a/src/utils/mac/SkOSWindow_Mac.cpp +++ b/src/utils/mac/SkOSWindow_Mac.cpp @@ -204,8 +204,7 @@ void SkOSWindow::updateSize() void SkOSWindow::onHandleInval(const SkIRect& r) { - SkEvent* evt = new SkEvent("inval-imageview"); - evt->post(this->getSinkID()); + (new SkEvent("inval-imageview", this->getSinkID()))->post(); } bool SkOSWindow::onEvent(const SkEvent& evt) { diff --git a/src/views/SkEvent.cpp b/src/views/SkEvent.cpp index d330636207..c7ac638ce8 100644 --- a/src/views/SkEvent.cpp +++ b/src/views/SkEvent.cpp @@ -9,21 +9,22 @@ #include "SkEvent.h" -void SkEvent::initialize(const char* type, size_t typeLen) { +void SkEvent::initialize(const char* type, size_t typeLen, + SkEventSinkID targetID) { fType = NULL; setType(type, typeLen); f32 = 0; + fTargetID = targetID; + fTargetProc = NULL; #ifdef SK_DEBUG - fTargetID = 0; fTime = 0; fNextEvent = NULL; #endif - SkDEBUGCODE(fDebugTrace = false;) } SkEvent::SkEvent() { - initialize("", 0); + initialize("", 0, 0); } SkEvent::SkEvent(const SkEvent& src) @@ -33,15 +34,15 @@ SkEvent::SkEvent(const SkEvent& src) setType(src.fType); } -SkEvent::SkEvent(const SkString& type) +SkEvent::SkEvent(const SkString& type, SkEventSinkID targetID) { - initialize(type.c_str(), type.size()); + initialize(type.c_str(), type.size(), targetID); } -SkEvent::SkEvent(const char type[]) +SkEvent::SkEvent(const char type[], SkEventSinkID targetID) { SkASSERT(type); - initialize(type, strlen(type)); + initialize(type, strlen(type), targetID); } SkEvent::~SkEvent() @@ -288,90 +289,50 @@ static SkGlobals::Rec* create_globals() return rec; } -bool SkEvent::Post(SkEvent* evt, SkEventSinkID sinkID, SkMSec delay) -{ - if (delay) - return SkEvent::PostTime(evt, sinkID, SkTime::GetMSecs() + delay); - - SkEvent_Globals& globals = *(SkEvent_Globals*)SkGlobals::Find(SK_Event_GlobalsTag, create_globals); - - evt->fTargetID = sinkID; +/////////////////////////////////////////////////////////////////////////////// -#ifdef SK_TRACE_EVENTS - { - SkString str("SkEvent::Post("); - str.append(evt->getType()); - str.append(", 0x"); - str.appendHex(sinkID); - str.append(", "); - str.appendS32(delay); - str.append(")"); - event_log(str.c_str()); +void SkEvent::postDelay(SkMSec delay) { + if (!fTargetID && !fTargetProc) { + delete this; + return; + } + + if (delay) { + this->postTime(SkTime::GetMSecs() + delay); + return; } -#endif + + SkEvent_Globals& globals = *(SkEvent_Globals*)SkGlobals::Find(SK_Event_GlobalsTag, create_globals); globals.fEventMutex.acquire(); - bool wasEmpty = SkEvent::Enqueue(evt); + bool wasEmpty = SkEvent::Enqueue(this); globals.fEventMutex.release(); - + // call outside of us holding the mutex - if (wasEmpty) + if (wasEmpty) { SkEvent::SignalNonEmptyQueue(); - return true; + } } -#if defined(SK_SIMULATE_FAILED_MALLOC) && defined(SK_FIND_MEMORY_LEAKS) -SkMSec gMaxDrawTime; -#endif - -bool SkEvent::PostTime(SkEvent* evt, SkEventSinkID sinkID, SkMSec time) -{ -#if defined(SK_SIMULATE_FAILED_MALLOC) && defined(SK_FIND_MEMORY_LEAKS) - gMaxDrawTime = time; -#endif - SkEvent_Globals& globals = *(SkEvent_Globals*)SkGlobals::Find(SK_Event_GlobalsTag, create_globals); - - evt->fTargetID = sinkID; - -#ifdef SK_TRACE_EVENTS - { - SkString str("SkEvent::Post("); - str.append(evt->getType()); - str.append(", 0x"); - str.appendHex(sinkID); - str.append(", "); - str.appendS32(time); - str.append(")"); - event_log(str.c_str()); +void SkEvent::postTime(SkMSec time) { + if (!fTargetID && !fTargetProc) { + delete this; + return; } -#endif + SkEvent_Globals& globals = *(SkEvent_Globals*)SkGlobals::Find(SK_Event_GlobalsTag, create_globals); + globals.fEventMutex.acquire(); - SkMSec queueDelay = SkEvent::EnqueueTime(evt, time); + SkMSec queueDelay = SkEvent::EnqueueTime(this, time); globals.fEventMutex.release(); - + // call outside of us holding the mutex - if ((int32_t)queueDelay != ~0) + if ((int32_t)queueDelay != ~0) { SkEvent::SignalQueueTimer(queueDelay); - return true; -} - -bool SkEvent::postDelay(SkMSec delay) { - return SkEvent::Post(this, this->getTargetID(), delay); -} - -bool SkEvent::postTime(SkMSec time) { - SkEventSinkID target = this->getTargetID(); - if (target) { - return SkEvent::PostTime(this, target, time); - } else { - delete this; - return false; } } -bool SkEvent::Enqueue(SkEvent* evt) -{ +bool SkEvent::Enqueue(SkEvent* evt) { SkEvent_Globals& globals = *(SkEvent_Globals*)SkGlobals::Find(SK_Event_GlobalsTag, create_globals); // gEventMutex acquired by caller @@ -387,37 +348,29 @@ bool SkEvent::Enqueue(SkEvent* evt) evt->fNextEvent = NULL; SkDEBUGCODE(++globals.fEventCounter); -// SkDebugf("Enqueue: count=%d\n", gEventCounter); return wasEmpty; } -SkEvent* SkEvent::Dequeue(SkEventSinkID* sinkID) -{ +SkEvent* SkEvent::Dequeue() { SkEvent_Globals& globals = *(SkEvent_Globals*)SkGlobals::Find(SK_Event_GlobalsTag, create_globals); globals.fEventMutex.acquire(); SkEvent* evt = globals.fEventQHead; - if (evt) - { + if (evt) { SkDEBUGCODE(--globals.fEventCounter); - if (sinkID) - *sinkID = evt->fTargetID; - globals.fEventQHead = evt->fNextEvent; - if (globals.fEventQHead == NULL) + if (globals.fEventQHead == NULL) { globals.fEventQTail = NULL; + } } globals.fEventMutex.release(); -// SkDebugf("Dequeue: count=%d\n", gEventCounter); - return evt; } -bool SkEvent::QHasEvents() -{ +bool SkEvent::QHasEvents() { SkEvent_Globals& globals = *(SkEvent_Globals*)SkGlobals::Find(SK_Event_GlobalsTag, create_globals); // this is not thread accurate, need a semaphore for that @@ -428,60 +381,49 @@ bool SkEvent::QHasEvents() static int gDelayDepth; #endif -SkMSec SkEvent::EnqueueTime(SkEvent* evt, SkMSec time) -{ -#ifdef SK_TRACE_EVENTS - SkDebugf("enqueue-delay %s %d (%d)", evt->getType(), time, gDelayDepth); - const char* idStr = evt->findString("id"); - if (idStr) - SkDebugf(" (%s)", idStr); - SkDebugf("\n"); - ++gDelayDepth; -#endif - +SkMSec SkEvent::EnqueueTime(SkEvent* evt, SkMSec time) { SkEvent_Globals& globals = *(SkEvent_Globals*)SkGlobals::Find(SK_Event_GlobalsTag, create_globals); // gEventMutex acquired by caller SkEvent* curr = globals.fDelayQHead; SkEvent* prev = NULL; - while (curr) - { - if (SkMSec_LT(time, curr->fTime)) + while (curr) { + if (SkMSec_LT(time, curr->fTime)) { break; + } prev = curr; curr = curr->fNextEvent; } evt->fTime = time; evt->fNextEvent = curr; - if (prev == NULL) + if (prev == NULL) { globals.fDelayQHead = evt; - else + } else { prev->fNextEvent = evt; + } SkMSec delay = globals.fDelayQHead->fTime - SkTime::GetMSecs(); - if ((int32_t)delay <= 0) + if ((int32_t)delay <= 0) { delay = 1; + } return delay; } -////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// #include "SkEventSink.h" -bool SkEvent::ProcessEvent() -{ - SkEventSinkID sinkID; - SkEvent* evt = SkEvent::Dequeue(&sinkID); +bool SkEvent::ProcessEvent() { + SkEvent* evt = SkEvent::Dequeue(); SkAutoTDelete<SkEvent> autoDelete(evt); - bool again = false; + bool again = false; EVENT_LOGN("ProcessEvent", (int32_t)evt); - if (evt) - { - (void)SkEventSink::DoEvent(*evt, sinkID); + if (evt) { + (void)SkEventSink::DoEvent(*evt); again = SkEvent::QHasEvents(); } return again; diff --git a/src/views/SkEventSink.cpp b/src/views/SkEventSink.cpp index 3c3aa5d213..9d3482af2a 100644 --- a/src/views/SkEventSink.cpp +++ b/src/views/SkEventSink.cpp @@ -213,58 +213,33 @@ bool SkEventSink::hasListeners() const return this->findTagList(kListeners_SkTagList) != NULL; } -void SkEventSink::postToListeners(const SkEvent& evt, SkMSec delay) -{ +void SkEventSink::postToListeners(const SkEvent& evt, SkMSec delay) { SkListenersTagList* list = (SkListenersTagList*)this->findTagList(kListeners_SkTagList); - if (list) - { + if (list) { SkASSERT(list->countListners() > 0); const SkEventSinkID* iter = list->fIDs; const SkEventSinkID* stop = iter + list->countListners(); - while (iter < stop) - (SkNEW_ARGS(SkEvent, (evt)))->post(*iter++, delay); + while (iter < stop) { + SkEvent* copy = SkNEW_ARGS(SkEvent, (evt)); + copy->setTargetID(*iter++)->postDelay(delay); + } } } /////////////////////////////////////////////////////////////////////////////// -SkEventSink::EventResult SkEventSink::DoEvent(const SkEvent& evt, SkEventSinkID sinkID) -{ - SkEventSink* sink = SkEventSink::FindSink(sinkID); - - if (sink) - { -#ifdef SK_DEBUG - if (evt.isDebugTrace()) - { - SkString etype; - evt.getType(&etype); - SkDebugf("SkEventTrace: dispatching event <%s> to 0x%x", etype.c_str(), sinkID); - const char* idStr = evt.findString("id"); - if (idStr) - SkDebugf(" (%s)", idStr); - SkDebugf("\n"); - } -#endif +SkEventSink::EventResult SkEventSink::DoEvent(const SkEvent& evt) { + SkEvent::Proc proc = evt.getTargetProc(); + if (proc) { + return proc(evt) ? kHandled_EventResult : kNotHandled_EventResult; + } + + SkEventSink* sink = SkEventSink::FindSink(evt.getTargetID()); + if (sink) { return sink->doEvent(evt) ? kHandled_EventResult : kNotHandled_EventResult; } - else - { -#ifdef SK_DEBUG - if (sinkID) - SkDebugf("DoEvent: Can't find sink for ID(%x)\n", sinkID); - else - SkDebugf("Event sent to 0 sinkID\n"); - if (evt.isDebugTrace()) - { - SkString etype; - evt.getType(&etype); - SkDebugf("SkEventTrace: eventsink not found <%s> for 0x%x\n", etype.c_str(), sinkID); - } -#endif - return kSinkNotFound_EventResult; - } + return kSinkNotFound_EventResult; } SkEventSink* SkEventSink::FindSink(SkEventSinkID sinkID) |