retool SkEvent to own its target ID or target proc
git-svn-id: http://skia.googlecode.com/svn/trunk@2041 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
parent
5aa937b300
commit
87fac4abd7
@ -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();
|
||||
};
|
||||
|
||||
|
@ -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:
|
||||
|
@ -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
|
||||
|
@ -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. */
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
|
@ -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() {
|
||||
|
@ -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() {
|
||||
|
@ -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) {
|
||||
|
@ -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());
|
||||
}
|
||||
#endif
|
||||
|
||||
globals.fEventMutex.acquire();
|
||||
bool wasEmpty = SkEvent::Enqueue(evt);
|
||||
globals.fEventMutex.release();
|
||||
|
||||
// call outside of us holding the mutex
|
||||
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());
|
||||
}
|
||||
#endif
|
||||
|
||||
globals.fEventMutex.acquire();
|
||||
SkMSec queueDelay = SkEvent::EnqueueTime(evt, time);
|
||||
globals.fEventMutex.release();
|
||||
|
||||
// call outside of us holding the mutex
|
||||
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 {
|
||||
void SkEvent::postDelay(SkMSec delay) {
|
||||
if (!fTargetID && !fTargetProc) {
|
||||
delete this;
|
||||
return false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (delay) {
|
||||
this->postTime(SkTime::GetMSecs() + delay);
|
||||
return;
|
||||
}
|
||||
|
||||
SkEvent_Globals& globals = *(SkEvent_Globals*)SkGlobals::Find(SK_Event_GlobalsTag, create_globals);
|
||||
|
||||
globals.fEventMutex.acquire();
|
||||
bool wasEmpty = SkEvent::Enqueue(this);
|
||||
globals.fEventMutex.release();
|
||||
|
||||
// call outside of us holding the mutex
|
||||
if (wasEmpty) {
|
||||
SkEvent::SignalNonEmptyQueue();
|
||||
}
|
||||
}
|
||||
|
||||
bool SkEvent::Enqueue(SkEvent* evt)
|
||||
{
|
||||
void SkEvent::postTime(SkMSec time) {
|
||||
if (!fTargetID && !fTargetProc) {
|
||||
delete this;
|
||||
return;
|
||||
}
|
||||
|
||||
SkEvent_Globals& globals = *(SkEvent_Globals*)SkGlobals::Find(SK_Event_GlobalsTag, create_globals);
|
||||
|
||||
globals.fEventMutex.acquire();
|
||||
SkMSec queueDelay = SkEvent::EnqueueTime(this, time);
|
||||
globals.fEventMutex.release();
|
||||
|
||||
// call outside of us holding the mutex
|
||||
if ((int32_t)queueDelay != ~0) {
|
||||
SkEvent::SignalQueueTimer(queueDelay);
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user