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 >
Wrap
C/C++ Source or Header
|
1998-03-25
|
5KB
|
196 lines
// $Id: HandlerL.C,v 1.10 1998/03/25 12:43:23 zeller Exp $
// General-purpose Handler Manager
// Copyright (C) 1995 Technische Universitaet Braunschweig, Germany.
// Written by Andreas Zeller <zeller@ips.cs.tu-bs.de>.
//
// This file is part of DDD.
//
// DDD is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// DDD is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public
// License along with DDD -- see the file COPYING.
// If not, write to the Free Software Foundation, Inc.,
// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//
// DDD is the data display debugger.
// For details, see the DDD World-Wide-Web page,
// `http://www.cs.tu-bs.de/softech/ddd/',
// or send a mail to the DDD developers <ddd@ips.cs.tu-bs.de>.
char HandlerList_rcsid[] =
"$Id: HandlerL.C,v 1.10 1998/03/25 12:43:23 zeller Exp $";
#ifdef __GNUG__
#pragma implementation
#endif
#include "assert.h"
#include "HandlerL.h"
// Create Handler List
HandlerList::HandlerList(unsigned n):
_nTypes(n),
handlers(new HandlerRec *[n]),
active(new int[n])
{
for (unsigned type = 0; type < _nTypes; type++)
{
handlers[type] = 0;
active[type] = 0;
}
}
// Duplicate List
HandlerList::HandlerList(const HandlerList& l):
_nTypes(l._nTypes),
handlers(new HandlerRec *[l._nTypes]),
active(new int [l._nTypes])
{
for (unsigned type = 0; type < nTypes(); type++)
{
handlers[type] = 0;
active[type] = l.active[type];
}
add(l);
}
// Add Handler
void HandlerList::add(unsigned type, HandlerProc proc, void *client_data)
{
assert(type < nTypes());
// Adding handlers takes effect only the next time the list is processed
handlers[type] = new HandlerRec(proc, client_data, handlers[type]);
}
// Remove Handler
// Note: this function is const, but the others are not.
void HandlerList::processRemovals(unsigned type) const
{
assert(type < nTypes());
assert(active[type] == 0);
HandlerRec *prev = 0;
HandlerRec *next = 0;
for (HandlerRec *h = handlers[type]; h != 0; h = next)
{
next = h->next;
if (h->remove_me)
{
if (prev == 0)
handlers[type] = next;
else
prev->next = next;
delete h;
}
else
{
prev = h;
}
}
}
// Remove Handler
void HandlerList::remove(unsigned type,
HandlerProc proc,
void *client_data)
{
assert(type < nTypes());
for (HandlerRec *h = handlers[type]; h != 0; h = h->next)
if (proc == h->proc && client_data == h->client_data)
h->remove_me = true;
if (active[type] == 0)
processRemovals(type);
}
// Remove all Handlers
void HandlerList::removeAll(unsigned type)
{
assert(type < nTypes());
for (HandlerRec *h = handlers[type]; h != 0; h = h->next)
h->remove_me = true;
if (active[type] == 0)
processRemovals(type);
}
// Remove all Handlers for all types
void HandlerList::removeAll()
{
for (unsigned type = 0; type < nTypes(); type++)
removeAll(type);
}
// Call Handlers
// We do not remove handlers while the list is being processed
void HandlerList::call(unsigned type,
void *const source,
void *const call_data) const
{
assert(type < nTypes());
active[type]++;
for (HandlerRec *h = handlers[type]; h != 0; h = h->next)
{
if (!h->remove_me)
h->proc(source, h->client_data, call_data);
}
// Removing handlers takes effect only the next time the list is processed
if (--active[type] == 0)
processRemovals(type);
}
// Compare Handler lists
int HandlerList::compare(const HandlerList& l) const
{
// Compare this
if (this == &l)
return 0;
// Compare number of types
int c = ::compare(nTypes(), l.nTypes());
if (c)
return c;
// Compare individual lists
for (unsigned t = 0; t < nTypes(); t++)
{
HandlerRec *r1 = handlers[t];
HandlerRec *r2 = l.handlers[t];
while (r1 != 0 && r2 != 0)
{
c = compare(*r1, *r2);
if (c)
return c;
r1 = r1->next;
r2 = r2->next;
}
// If one of the lists is longer, it is also the greater one
c = ::compare((void *)r1, (void *)r2);
if (c)
return c;
}
return 0;
}