home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 1999 mARCH / PCWK3A99.iso / Linux / DDD331 / DDD-3_1_.000 / DDD-3_1_ / ddd-3.1.1 / ddd / HandlerL.C < prev    next >
C/C++ Source or Header  |  1998-03-25  |  5KB  |  196 lines

  1. // $Id: HandlerL.C,v 1.10 1998/03/25 12:43:23 zeller Exp $
  2. // General-purpose Handler Manager
  3.  
  4. // Copyright (C) 1995 Technische Universitaet Braunschweig, Germany.
  5. // Written by Andreas Zeller <zeller@ips.cs.tu-bs.de>.
  6. // 
  7. // This file is part of DDD.
  8. // 
  9. // DDD is free software; you can redistribute it and/or
  10. // modify it under the terms of the GNU General Public
  11. // License as published by the Free Software Foundation; either
  12. // version 2 of the License, or (at your option) any later version.
  13. // 
  14. // DDD is distributed in the hope that it will be useful,
  15. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  17. // See the GNU General Public License for more details.
  18. // 
  19. // You should have received a copy of the GNU General Public
  20. // License along with DDD -- see the file COPYING.
  21. // If not, write to the Free Software Foundation, Inc.,
  22. // 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  23. // 
  24. // DDD is the data display debugger.
  25. // For details, see the DDD World-Wide-Web page, 
  26. // `http://www.cs.tu-bs.de/softech/ddd/',
  27. // or send a mail to the DDD developers <ddd@ips.cs.tu-bs.de>.
  28.  
  29. char HandlerList_rcsid[] = 
  30.     "$Id: HandlerL.C,v 1.10 1998/03/25 12:43:23 zeller Exp $";
  31.  
  32. #ifdef __GNUG__
  33. #pragma implementation
  34. #endif
  35.  
  36. #include "assert.h"
  37. #include "HandlerL.h"
  38.  
  39. // Create Handler List
  40. HandlerList::HandlerList(unsigned n):
  41.     _nTypes(n),
  42.     handlers(new HandlerRec *[n]),
  43.     active(new int[n])
  44. {
  45.     for (unsigned type = 0; type < _nTypes; type++)
  46.     {
  47.     handlers[type] = 0;
  48.     active[type]   = 0;
  49.     }
  50. }
  51.  
  52.  
  53. // Duplicate List
  54. HandlerList::HandlerList(const HandlerList& l):
  55.     _nTypes(l._nTypes),
  56.     handlers(new HandlerRec *[l._nTypes]),
  57.     active(new int [l._nTypes])
  58. {
  59.     for (unsigned type = 0; type < nTypes(); type++)
  60.     {
  61.     handlers[type] = 0;
  62.     active[type]   = l.active[type];
  63.     }
  64.  
  65.     add(l);
  66. }
  67.  
  68. // Add Handler
  69. void HandlerList::add(unsigned type, HandlerProc proc, void *client_data)
  70. {
  71.     assert(type < nTypes());
  72.  
  73.     // Adding handlers takes effect only the next time the list is processed
  74.     handlers[type] = new HandlerRec(proc, client_data, handlers[type]);
  75. }
  76.  
  77. // Remove Handler
  78. // Note: this function is const, but the others are not.
  79. void HandlerList::processRemovals(unsigned type) const
  80. {
  81.     assert(type < nTypes());
  82.     assert(active[type] == 0);
  83.  
  84.     HandlerRec *prev = 0;
  85.     HandlerRec *next = 0;
  86.     for (HandlerRec *h = handlers[type]; h != 0; h = next)
  87.     {
  88.     next = h->next;
  89.     if (h->remove_me)
  90.     {
  91.         if (prev == 0)
  92.         handlers[type] = next;
  93.         else
  94.         prev->next = next;
  95.  
  96.         delete h;
  97.     }
  98.     else
  99.     { 
  100.         prev = h;
  101.     }
  102.     }
  103. }
  104.  
  105. // Remove Handler
  106. void HandlerList::remove(unsigned type,
  107.              HandlerProc proc,
  108.              void *client_data)
  109. {
  110.     assert(type < nTypes());
  111.  
  112.     for (HandlerRec *h = handlers[type]; h != 0; h = h->next)
  113.     if (proc == h->proc && client_data == h->client_data)
  114.         h->remove_me = true;
  115.  
  116.     if (active[type] == 0)
  117.     processRemovals(type);
  118. }
  119.  
  120. // Remove all Handlers
  121. void HandlerList::removeAll(unsigned type)
  122. {
  123.     assert(type < nTypes());
  124.  
  125.     for (HandlerRec *h = handlers[type]; h != 0; h = h->next)
  126.     h->remove_me = true;
  127.  
  128.     if (active[type] == 0)
  129.     processRemovals(type);
  130. }
  131.  
  132. // Remove all Handlers for all types
  133. void HandlerList::removeAll()
  134. {
  135.     for (unsigned type = 0; type < nTypes(); type++)
  136.     removeAll(type);
  137. }
  138.  
  139. // Call Handlers
  140. // We do not remove handlers while the list is being processed
  141. void HandlerList::call(unsigned type,
  142.                void *const source, 
  143.                void *const call_data) const
  144. {
  145.     assert(type < nTypes());
  146.  
  147.     active[type]++;
  148.  
  149.     for (HandlerRec *h = handlers[type]; h != 0; h = h->next)
  150.     {
  151.     if (!h->remove_me)
  152.         h->proc(source, h->client_data, call_data);
  153.     }
  154.  
  155.     // Removing handlers takes effect only the next time the list is processed
  156.     if (--active[type] == 0)
  157.     processRemovals(type);
  158. }
  159.  
  160. // Compare Handler lists
  161. int HandlerList::compare(const HandlerList& l) const
  162. {
  163.     // Compare this
  164.     if (this == &l)
  165.     return 0;
  166.  
  167.     // Compare number of types
  168.     int c = ::compare(nTypes(), l.nTypes());
  169.     if (c)
  170.     return c;
  171.  
  172.     // Compare individual lists
  173.     for (unsigned t = 0; t < nTypes(); t++)
  174.     {
  175.     HandlerRec *r1 = handlers[t];
  176.     HandlerRec *r2 = l.handlers[t];
  177.  
  178.     while (r1 != 0 && r2 != 0)
  179.     {
  180.         c = compare(*r1, *r2);
  181.         if (c)
  182.         return c;
  183.  
  184.         r1 = r1->next;
  185.         r2 = r2->next;
  186.     }
  187.  
  188.     // If one of the lists is longer, it is also the greater one
  189.     c = ::compare((void *)r1, (void *)r2);
  190.     if (c)
  191.         return c;
  192.     }
  193.  
  194.     return 0;
  195. }
  196.