home *** CD-ROM | disk | FTP | other *** search
- /*
- * BryLib - a mishmash of useful library routines
- * Copyright (C) 1992 Bryan Ford
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library 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
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the Free
- * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * Reminder list handling
- * $Id$
- *
- * $Log$
- *
- */
- #ifndef BRY_REMIND_H
- #define BRY_REMIND_H
-
- #ifndef BRY_CLIST_H
- #include "bry/clist.h"
- #endif
-
-
- /* One of these structures "remembers" a function to be called later. */
- struct RemindNode
- {
- struct CNode node; /* Circular-list node */
- long (*callfunc)(long globaldata,long localdata); /* What to call */
- long localdata;
- short sequence; /* Lower-sequence nodes get called first */
- char inlist; /* Nonzero if this node is linked into a CallList */
- char reserved;
- };
-
-
- /* Handy macro to declare preinitialized instances of RemindNodes */
- #define remind_decl(name,func,seq) struct RemindNode name = {{0},func,seq}
-
-
- /* We don't need any fancy structures here--just a normal circular list. */
- #define RemindList CList
-
-
- /* Initializing a CallList is also very simple. */
- #define remind_initlist(calllistptr) clist_init(calllistptr)
-
-
- /* Add a RemindNode to a RemindList. Only adds if node->inlist is zero
- (i.e. if the node is not already on the list). Sets node->inlist to
- nonzero. This function keeps the list in order of sequence, so
- when the list is traversed by one of the functions below the nodes
- will be called in order from lowest sequence number to highest.
- Nodes with the same sequence numbers are called in first-in, first-out
- (i.e. first-added, first called) order. */
- void remind_add(struct RemindList *list,struct RemindNode *node);
-
-
- /* Remove a RemindNode from a RemindList. Only removes if node->inlist
- is nonzero (i.e. if the node is on a list). Sets node->inlist to zero. */
- void remind_rem(struct RemindNode *node);
- #define remind_remove(node) remind_rem(node)
-
-
- /* Call all the nodes on a RemindList non-destructively (leaving the nodes
- in place as it goes along). Note that though this function does not
- remove any nodes, the functions it calls through the RemindNodes may
- remove their own nodes. callfuncs must return 0 to keep going through
- list; nonzero causes remind_call to stop and return that value
- immediately. Returns -1 if the list was empty; 0 if all nodes processed
- successfully.
-
- While callfuncs may remove their own nodes (the nodes that were used
- to call them), they may not remove any other nodes on the list being
- traversed. They may add new nodes to the list being traversed, but
- whether or not that node will get called on this particular run is
- unspecified. */
- long remind_call(struct RemindList *l,long globaldata);
-
-
- /* Extension to remind_call: afterfunc is called after each callfunc is
- called. It is passed the return code of the callfunc that was just
- called, and its return code is used in place of the callfunc's return
- code to determine whether to keep going in the list or stop. */
- long remind_callext(struct RemindList *l,long globaldata,
- long (*afterfunc)(struct RemindNode *node,long retcode,long globaldata));
-
-
- /* Call the nodes on a RemindList destructively, removing each node as it
- progresses. Returncode conventions work the same way as remind_call. Each
- node is removed before its callfunc is called, so callfuncs may add their
- own nodes back onto the list; the node will be called again later during
- this same traversal, according to sequence. (Be careful not to create
- infinite loops.) For that matter, callfuncs can safely add or delete any
- nodes (their own or others) from the list while inside a remind_callrem. */
- long remind_callrem(struct RemindList *l,long globaldata);
-
-
- /* Variation of remind_callrem with the afterfunc feature; differences are
- the same as with remind_callext. */
- long remind_callremext(struct RemindList *l,long globaldata,
- long (*afterfunc)(struct RemindNode *node,long retcode,long globaldata));
-
-
- #endif