home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / threads.zip / iasyngui.cpp < prev    next >
Text File  |  1995-11-11  |  9KB  |  274 lines

  1. /*******************************************************************************
  2. * FILE NAME: iasyngui.cpp
  3. *
  4. * DESCRIPTION:
  5. *   Functions to implement the class(es):
  6. *     IAsyncNotifierGUIThread
  7. *
  8. * COPYRIGHT:
  9. *   Licensed Materials - Property of IBM
  10. *   (C) Copyright IBM Corporation 1995
  11. *   All Rights Reserved
  12. *   US Government Users Restricted Rights - Use, duplication, or disclosure
  13. *   restricted by GSA ADP Schedule Contract with IBM Corp.
  14. *
  15. *******************************************************************************/
  16. #include <iasyngui.hpp>
  17.  
  18. #ifndef _IASYNTFY_
  19.   #include <iasyntfy.hpp>
  20. #endif
  21.  
  22. #ifndef _INOTIFEV_
  23.   #include <inotifev.hpp>
  24. #endif
  25.  
  26. #ifndef _ITHREAD_
  27.   #include <ithread.hpp>
  28. #endif
  29.  
  30. #ifndef _IEVNTSEM_
  31.   #include <ievntsem.hpp>
  32. #endif
  33.  
  34. #ifndef _IEXCEPT_
  35.   #include <iexcept.hpp>
  36. #endif
  37.  
  38. #ifndef _IHANDLER_
  39.   #include <ihandler.hpp>
  40. #endif
  41.  
  42. #ifndef _IOBJWIN_
  43.   #include <iobjwin.hpp>
  44. #endif
  45.  
  46. #ifndef _ISEQ_H
  47.   #include <iseq.h>
  48. #endif
  49.  
  50. #define INCL_WINMESSAGEMGR
  51. #include <os2.h>
  52.  
  53.  
  54. //------------------------------------------------------------------------------
  55. // Declare the event notification handler for the object window.
  56. //------------------------------------------------------------------------------
  57. class IAsyncNotificationHandler : public IHandler
  58. {
  59. public:
  60.   IAsyncNotificationHandler ( );
  61.   virtual ~IAsyncNotificationHandler ( );
  62.  
  63.   virtual IBoolean dispatchHandlerEvent ( IEvent & event );
  64.  
  65. private:
  66.   // Private copy constructor and assignment operator are not implemented.
  67.   IAsyncNotificationHandler ( const IAsyncNotificationHandler & );
  68.   IAsyncNotificationHandler & operator = ( const IAsyncNotificationHandler & );
  69. };
  70.  
  71.  
  72. /*------------------------------------------------------------------------------
  73. | Function Name: IAsyncNotifierGUIThread :: IAsyncNotifierGUIThread
  74. |
  75. | Implementation:
  76. |   Initialize the base class then create our object window and handler.
  77. |-----------------------------------------------------------------------------*/
  78. IAsyncNotifierGUIThread :: IAsyncNotifierGUIThread ( ) :
  79.                    IAsyncNotifierThread ( ),
  80.                    objectWindow ( new IObjectWindow ),
  81.                    asyncNotificationHandler ( new IAsyncNotificationHandler ),
  82.                    objectWindowKey ( )
  83. {
  84.   objectWindow->setAutoDeleteObject ( true );
  85.   asyncNotificationHandler->handleEventsFor ( objectWindow );
  86. }
  87.  
  88. /*------------------------------------------------------------------------------
  89. | Function Name: IAsyncNotifierGUIThread :: ~IAsyncNotifierGUIThread
  90. |
  91. | Implementation:
  92. |   If the object window is still around, close the object window (it is
  93. |     auto deleted).
  94. |   Delete the handler.
  95. |-----------------------------------------------------------------------------*/
  96. IAsyncNotifierGUIThread :: ~IAsyncNotifierGUIThread ( )
  97. {
  98.   if ( objectWindow != NULL )
  99.   {
  100.     asyncNotificationHandler->stopHandlingEventsFor ( objectWindow );
  101.     objectWindow->close();
  102.   }
  103.  
  104.   delete asyncNotificationHandler;
  105. }
  106.  
  107. /*------------------------------------------------------------------------------
  108. | Function Name: IAsyncNotifierGUIThread :: removeRef
  109. |
  110. | Implementation:
  111. |   Decrement the async notifier count.
  112. |   If the count is now zero, close the object window (it is auto deleted).
  113. |     Make sure the destructor does not try to clean this up by clearing the
  114. |     object window pointer.
  115. |-----------------------------------------------------------------------------*/
  116. unsigned long IAsyncNotifierGUIThread :: removeRef ( )
  117. {
  118.   unsigned long count = IAsyncNotifierThread::removeRef();
  119.   if ( count == 0 )
  120.   {
  121.     asyncNotificationHandler->stopHandlingEventsFor ( objectWindow );
  122.     objectWindow->close();
  123.     objectWindow = NULL;
  124.   }
  125.  
  126.   return count;
  127. }
  128.  
  129. /*------------------------------------------------------------------------------
  130. | Function Name: IAsyncNotifierGUIThread :: enqueueNotification
  131. |
  132. | Implementation:
  133. |   Copy and enqueue the notification.
  134. |-----------------------------------------------------------------------------*/
  135. IAsyncNotifierGUIThread & IAsyncNotifierGUIThread :: enqueueNotification (
  136.                             const INotificationEvent & anEvent )
  137. {
  138.   IResourceLock objectWindowLock ( objectWindowKey );
  139.  
  140.   INotificationEvent * copiedEvent = new INotificationEvent ( anEvent );
  141.   objectWindow->postEvent ( WM_USER, IEventData ( copiedEvent ) );
  142.  
  143.   return *this;
  144. }
  145.  
  146. /*------------------------------------------------------------------------------
  147. | Function Name: IAsyncNotifierGUIThread :: processMsgs
  148. |
  149. | Implementation:
  150. |   Pass the call on to ICurrentThread.
  151. |-----------------------------------------------------------------------------*/
  152. IAsyncNotifierGUIThread & IAsyncNotifierGUIThread :: processMsgs ( )
  153. {
  154.   IASSERTSTATE ( threadId() == IThread::currentId() );
  155.  
  156.   setIsRunning ( true );
  157.   IThread::current().processMsgs();
  158.   setIsRunning ( false );
  159.  
  160.   return *this;
  161. }
  162.  
  163. /*------------------------------------------------------------------------------
  164. | Function Name: IAsyncNotifierGUIThread :: deleteNotificationsFor
  165. |
  166. | Implementation:
  167. |   Peek at all notifcation events coming to our object window.
  168. |   If it is for the passed async notifier, delete it.
  169. |   Else, save it and requeue it at the end.
  170. |-----------------------------------------------------------------------------*/
  171. IAsyncNotifierGUIThread & IAsyncNotifierGUIThread
  172.                                    :: deleteNotificationsFor (
  173.                                         const IAsyncNotifier & asyncNotifier )
  174. {
  175.   IASSERTSTATE ( threadId() == IThread::currentId() );
  176.  
  177.   IResourceLock objectWindowLock ( objectWindowKey );
  178.  
  179.   ISequence<INotificationEvent *> savedEvents;
  180.  
  181.   HAB hab = IThread::current().anchorBlock();
  182.   QMSG msg;
  183.   HWND handle = objectWindow->handle();
  184.  
  185.   INotificationEvent * nextEvent = NULL;
  186.   const IAsyncNotifier * nextNotifier = NULL;
  187.  
  188.   IBoolean msgFound = true;
  189.   while ( msgFound )
  190.   {
  191.     msgFound = WinPeekMsg ( hab, &msg, handle, WM_USER, WM_USER, PM_REMOVE );
  192.  
  193.     if ( msgFound )
  194.     {
  195.       nextEvent = (INotificationEvent *)(msg.mp1);
  196.       nextNotifier = (const IAsyncNotifier *)(&(nextEvent->notifier()));
  197.       if ( nextNotifier == &asyncNotifier )
  198.       {
  199.         nextNotifier->notificationCleanUp ( *nextEvent );
  200.         delete nextEvent;
  201.       }
  202.       else
  203.       {
  204.         savedEvents.addAsLast ( nextEvent );
  205.       }
  206.     }
  207.   }
  208.  
  209.   while ( ! ( savedEvents.isEmpty() ) )
  210.   {
  211.     nextEvent = savedEvents.firstElement();
  212.     savedEvents.removeFirst();
  213.     objectWindow->postEvent ( WM_USER, IEventData ( nextEvent ) );
  214.   }
  215.  
  216.   return *this;
  217. }
  218.  
  219. /*------------------------------------------------------------------------------
  220. | Function Name: IAsyncNotificationHandler :: IAsyncNotificationHandler
  221. |
  222. | Implementation:
  223. |   Initialize the base class.
  224. |-----------------------------------------------------------------------------*/
  225. IAsyncNotificationHandler :: IAsyncNotificationHandler ( ) :
  226.                    IHandler ( )
  227. {
  228. }
  229.  
  230. /*------------------------------------------------------------------------------
  231. | Function Name: IAsyncNotificationHandler :: ~IAsyncNotificationHandler
  232. |
  233. | Implementation:
  234. |   Nothing to delete.
  235. |-----------------------------------------------------------------------------*/
  236. IAsyncNotificationHandler :: ~IAsyncNotificationHandler ( )
  237. {
  238. }
  239.  
  240. /*------------------------------------------------------------------------------
  241. | Function Name: IAsyncNotificationHandler :: dispatchHandlerEvent
  242. |
  243. | Implementation:
  244. |   If the event is one of our notifications, notify the observers of the
  245. |   notifier on this thread and delete the event.
  246. |-----------------------------------------------------------------------------*/
  247. IBoolean IAsyncNotificationHandler :: dispatchHandlerEvent ( IEvent & event )
  248. {
  249.   IBoolean handledEvent = false;
  250.  
  251.   if ( event.eventId() == WM_USER )
  252.   {
  253.     INotificationEvent * theEvent = (INotificationEvent *)
  254.                                        ((char *)(event.parameter1()));
  255.  
  256.     IAsyncNotifier * theNotifier = (IAsyncNotifier *)(&(theEvent->notifier()));
  257.     if ( theEvent->notificationId() == IAsyncNotifierThread::deleteThisId )
  258.     {
  259.       delete theNotifier;
  260.     }
  261.     else
  262.     {
  263.       theNotifier->IStandardNotifier::notifyObservers ( *theEvent );
  264.       theNotifier->notificationCleanUp ( *theEvent );
  265.     }
  266.  
  267.     delete theEvent;
  268.  
  269.     handledEvent = true;
  270.   }
  271.  
  272.   return handledEvent;
  273. }
  274.