Kaydet (Commit) a738606d authored tarafından Michael Meeks's avatar Michael Meeks

PostUserEvent - instrument to allow holding a VclPtr reference.

This helps avoid things dying during emission in a robust manner.
Bit of an unpleasant 3rd optional parameter; better names appreciated.

Change-Id: I27571823f9d96caef1d07602785a02390d3a3591
üst 5c430093
...@@ -153,6 +153,7 @@ public: ...@@ -153,6 +153,7 @@ public:
{ return function_ == other.function_ && instance_ == other.instance_; }; { return function_ == other.function_ && instance_ == other.instance_; };
bool operator !=(Link const & other) const { return !operator ==(other); }; bool operator !=(Link const & other) const { return !operator ==(other); };
void *GetInstance() const { return instance_; }
private: private:
Stub * function_; Stub * function_;
......
...@@ -865,10 +865,12 @@ public: ...@@ -865,10 +865,12 @@ public:
@param rLink Link to event callback function @param rLink Link to event callback function
@param pCaller Pointer to data sent to the event by the caller. Optional. @param pCaller Pointer to data sent to the event by the caller. Optional.
@param bReferenceLink If true - hold a VclPtr<> reference on the Link's instance.
@return the event ID used to post the event. @return the event ID used to post the event.
*/ */
static ImplSVEvent * PostUserEvent( const Link<>& rLink, void* pCaller = NULL ); static ImplSVEvent * PostUserEvent( const Link<>& rLink, void* pCaller = NULL,
bool bReferenceLink = false );
/** Remove user event based on event ID /** Remove user event based on event ID
......
...@@ -728,7 +728,7 @@ public: ...@@ -728,7 +728,7 @@ public:
void AddChildEventListener( const Link<>& rEventListener ); void AddChildEventListener( const Link<>& rEventListener );
void RemoveChildEventListener( const Link<>& rEventListener ); void RemoveChildEventListener( const Link<>& rEventListener );
ImplSVEvent * PostUserEvent( const Link<>& rLink, void* pCaller = NULL ); ImplSVEvent * PostUserEvent( const Link<>& rLink, void* pCaller = NULL, bool bReferenceLink = false );
void RemoveUserEvent( ImplSVEvent * nUserEvent ); void RemoveUserEvent( ImplSVEvent * nUserEvent );
void IncrementLockCount(); void IncrementLockCount();
......
...@@ -400,6 +400,7 @@ struct ImplSVEvent ...@@ -400,6 +400,7 @@ struct ImplSVEvent
{ {
void* mpData; void* mpData;
Link<>* mpLink; Link<>* mpLink;
VclPtr<vcl::Window> mpInstanceRef;
VclPtr<vcl::Window> mpWindow; VclPtr<vcl::Window> mpWindow;
ImplDelData maDelData; ImplDelData maDelData;
bool mbCall; bool mbCall;
......
...@@ -897,13 +897,23 @@ void Application::RemoveMouseAndKeyEvents( vcl::Window* pWin ) ...@@ -897,13 +897,23 @@ void Application::RemoveMouseAndKeyEvents( vcl::Window* pWin )
} }
} }
ImplSVEvent * Application::PostUserEvent( const Link<>& rLink, void* pCaller ) ImplSVEvent * Application::PostUserEvent( const Link<>& rLink, void* pCaller,
bool bReferenceLink )
{ {
ImplSVEvent* pSVEvent = new ImplSVEvent; ImplSVEvent* pSVEvent = new ImplSVEvent;
pSVEvent->mpData = pCaller; pSVEvent->mpData = pCaller;
pSVEvent->mpLink = new Link<>( rLink ); pSVEvent->mpLink = new Link<>( rLink );
pSVEvent->mpWindow = NULL; pSVEvent->mpWindow = NULL;
pSVEvent->mbCall = true; pSVEvent->mbCall = true;
if (bReferenceLink)
{
// Double check that this is indeed a vcl::Window instance.
assert(dynamic_cast<vcl::Window *>(
reinterpret_cast<vcl::Window *>(rLink.GetInstance())) ==
reinterpret_cast<vcl::Window *>(rLink.GetInstance()));
pSVEvent->mpInstanceRef = reinterpret_cast<vcl::Window *>(rLink.GetInstance());
}
vcl::Window* pDefWindow = ImplGetDefaultWindow(); vcl::Window* pDefWindow = ImplGetDefaultWindow();
if ( pDefWindow == 0 || !pDefWindow->ImplGetFrame()->PostEvent( pSVEvent ) ) if ( pDefWindow == 0 || !pDefWindow->ImplGetFrame()->PostEvent( pSVEvent ) )
{ {
......
...@@ -263,13 +263,22 @@ void Window::RemoveChildEventListener( const Link<>& rEventListener ) ...@@ -263,13 +263,22 @@ void Window::RemoveChildEventListener( const Link<>& rEventListener )
mpWindowImpl->maChildEventListeners.removeListener( rEventListener ); mpWindowImpl->maChildEventListeners.removeListener( rEventListener );
} }
ImplSVEvent * Window::PostUserEvent( const Link<>& rLink, void* pCaller ) ImplSVEvent * Window::PostUserEvent( const Link<>& rLink, void* pCaller, bool bReferenceLink )
{ {
ImplSVEvent* pSVEvent = new ImplSVEvent; ImplSVEvent* pSVEvent = new ImplSVEvent;
pSVEvent->mpData = pCaller; pSVEvent->mpData = pCaller;
pSVEvent->mpLink = new Link<>( rLink ); pSVEvent->mpLink = new Link<>( rLink );
pSVEvent->mpWindow = this; pSVEvent->mpWindow = this;
pSVEvent->mbCall = true; pSVEvent->mbCall = true;
if (bReferenceLink)
{
// Double check that this is indeed a vcl::Window instance.
assert(dynamic_cast<vcl::Window *>(
reinterpret_cast<vcl::Window *>(rLink.GetInstance())) ==
reinterpret_cast<vcl::Window *>(rLink.GetInstance()));
pSVEvent->mpInstanceRef = reinterpret_cast<vcl::Window *>(rLink.GetInstance());
}
ImplAddDel( &(pSVEvent->maDelData) ); ImplAddDel( &(pSVEvent->maDelData) );
if ( !mpWindowImpl->mpFrame->PostEvent( pSVEvent ) ) if ( !mpWindowImpl->mpFrame->PostEvent( pSVEvent ) )
{ {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment