updated to latest signals. some cleanup & refactoring begun.
This commit is contained in:
1 parent
ef1b465179
commit
c7d43807e3
28 files changed
+3892
-235
No files matched your search
+271
-151
@@ -1,151 +1,271 @@
|
||||
#include <cassert>
|
||||
#include "signal_base.h"
|
||||
|
||||
signal_base::signal_base() : head(0), tail(0)
|
||||
{
|
||||
// empty
|
||||
}
|
||||
|
||||
signal_base::~signal_base()
|
||||
{
|
||||
// clear the list
|
||||
clear_list();
|
||||
}
|
||||
|
||||
bool signal_base::bind(const slot_base& slot)
|
||||
{
|
||||
// add it to our signal list
|
||||
return add_to_list(slot);
|
||||
}
|
||||
|
||||
bool signal_base::unbind(const slot_base& slot)
|
||||
{
|
||||
// look for corresponding list_node in list
|
||||
list_node* n = find_in_list(slot);
|
||||
|
||||
// see if we found a match
|
||||
if ( !n )
|
||||
{
|
||||
return false; // no match found
|
||||
}
|
||||
|
||||
// take it out of the linked list
|
||||
remove_from_list(n);
|
||||
|
||||
// free it
|
||||
delete n;
|
||||
|
||||
// found a match, success
|
||||
return true;
|
||||
}
|
||||
|
||||
void signal_base::clear_list()
|
||||
{
|
||||
// start at head
|
||||
list_node* cur = head;
|
||||
|
||||
// iterate
|
||||
while ( cur )
|
||||
{
|
||||
// save off next so we can safely delete
|
||||
list_node* next = cur->next;
|
||||
|
||||
// free
|
||||
delete cur;
|
||||
|
||||
// advance
|
||||
cur = next;
|
||||
}
|
||||
|
||||
// reset head & tail
|
||||
head = tail = 0;
|
||||
}
|
||||
|
||||
signal_base::list_node* signal_base::find_in_list(const slot_base& slot) const
|
||||
{
|
||||
// start search at head of list
|
||||
list_node* cur = head;
|
||||
|
||||
// search list for slot
|
||||
while ( cur )
|
||||
{
|
||||
// see if this is a match
|
||||
if ( cur->slot == slot )
|
||||
{
|
||||
// we have a match, return it
|
||||
return cur;
|
||||
}
|
||||
|
||||
// advance to next in list
|
||||
cur = cur->next;
|
||||
}
|
||||
|
||||
// no match
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool signal_base::add_to_list(const slot_base& slot)
|
||||
{
|
||||
// a sanity check
|
||||
assert((head && tail) || (!head && !tail));
|
||||
|
||||
// make a new list_node to hold this slot in the list
|
||||
list_node* n = new list_node;
|
||||
if ( !n )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// initialize new list_node
|
||||
n->slot = slot; // copy slot into list_node
|
||||
n->prev = tail; // prev is tail because we'll put this list_node behind it (i.e. the new tail)
|
||||
n->next = 0; // next is 0 because we'll put this list_node on the tail
|
||||
|
||||
// add to tail
|
||||
if ( tail )
|
||||
{
|
||||
// tail exists, just append
|
||||
tail->next = n; // insert item after current tail
|
||||
tail = n; // now have a new tail
|
||||
}
|
||||
else
|
||||
{
|
||||
// list is currently empty, add this new list_node
|
||||
head = tail = n; // now have a single list_node, which is also both the head and tail
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void signal_base::remove_from_list(list_node* n)
|
||||
{
|
||||
// do a little sanity checking
|
||||
assert((head && tail) || (!head && !tail));
|
||||
assert(n->prev == 0 || n->prev->next == n);
|
||||
assert(n->next == 0 || n->next->prev == n);
|
||||
|
||||
// if this is the head, set the new head
|
||||
if ( n == head )
|
||||
{
|
||||
head = n->next;
|
||||
}
|
||||
|
||||
// if this is the tail, set the new tail
|
||||
if ( n == tail )
|
||||
{
|
||||
tail = n->prev;
|
||||
}
|
||||
|
||||
// set list to skip over this list_node
|
||||
if ( n->prev )
|
||||
{
|
||||
n->prev->next = n->next;
|
||||
}
|
||||
if ( n->next )
|
||||
{
|
||||
n->next->prev = n->prev;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
#include <cassert>
|
||||
#include "signal_base.h"
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------------------------------------------------------------------
|
||||
signal_base::signal_base() : head(0), tail(0), bEmitting(false)
|
||||
{
|
||||
// empty
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------------------------------------------------------------------
|
||||
signal_base::~signal_base()
|
||||
{
|
||||
// clear the list
|
||||
clear_list();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------------------------------------------------------------------
|
||||
signal_base::signal_base( const signal_base& rSource ) : head(0), tail(0), bEmitting(false)
|
||||
{
|
||||
// Set an assert to let the user know that we don't support construction of a signal by copying another one.
|
||||
// There are too many places where the signals are directly connected to objects, where copying them would create a disconnect
|
||||
// between the signal and the objects that want to react to the signal execution.
|
||||
assert( 0 );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------------------------------------------------------------------
|
||||
signal_base& signal_base::operator=( const signal_base& rSource )
|
||||
{
|
||||
// Set an assert to let the user know that we don't support signal copying.
|
||||
// There are too many places where the signals are directly connected to objects, where copying them would create a disconnect
|
||||
// between the signal and the objects that want to react to the signal execution.
|
||||
assert( 0 );
|
||||
return *this;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------------------------------------------------------------------
|
||||
int signal_base::Count( void )
|
||||
{
|
||||
int Count = 0;
|
||||
|
||||
list_node* pIndex;
|
||||
pIndex = head;
|
||||
|
||||
while( pIndex )
|
||||
{
|
||||
pIndex = pIndex->next;
|
||||
Count++;
|
||||
}
|
||||
|
||||
return Count;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------------------------------------------------------------------
|
||||
bool signal_base::bind(slot_base* slot)
|
||||
{
|
||||
// add it to our signal list
|
||||
return add_to_list(slot);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------------------------------------------------------------------
|
||||
bool signal_base::unbind(slot_base* slot)
|
||||
{
|
||||
// look for corresponding list_node in list
|
||||
list_node* n = find_in_list(slot);
|
||||
|
||||
// see if we found a match
|
||||
if( n )
|
||||
{
|
||||
// If we are not processing a signal emit sequence, then release the node.
|
||||
if( !IsSignalEmitting( ) )
|
||||
{
|
||||
// take it out of the linked list
|
||||
remove_from_list(n);
|
||||
|
||||
// found a match, return success
|
||||
return true;
|
||||
}
|
||||
// Otherwise mark it for removal.
|
||||
else
|
||||
{
|
||||
n->bDeleteRequested = true;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// no match
|
||||
return false;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------------------------------------------------------------------
|
||||
signal_base::list_node::list_node(slot_base* s) : slot(s),
|
||||
prev(0),
|
||||
next(0),
|
||||
bDeleteRequested(false)
|
||||
{
|
||||
// empty
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------------------------------------------------------------------
|
||||
signal_base::list_node::~list_node()
|
||||
{
|
||||
// release the slot
|
||||
delete slot;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------------------------------------------------------------------
|
||||
signal_base::list_node* signal_base::GetFirstNode( void ) const
|
||||
{
|
||||
return head;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------------------------------------------------------------------
|
||||
void signal_base::clear_list()
|
||||
{
|
||||
// start at head
|
||||
list_node* cur = head;
|
||||
|
||||
// iterate
|
||||
while ( cur )
|
||||
{
|
||||
// save off next so we can safely delete
|
||||
list_node* next = cur->next;
|
||||
|
||||
// free
|
||||
delete cur;
|
||||
|
||||
// advance
|
||||
cur = next;
|
||||
}
|
||||
|
||||
// reset head & tail
|
||||
head = tail = 0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------------------------------------------------------------------
|
||||
signal_base::list_node* signal_base::find_in_list(slot_base* slot) const
|
||||
{
|
||||
// start search at head of list
|
||||
list_node* cur = head;
|
||||
|
||||
// search list for slot
|
||||
while ( cur )
|
||||
{
|
||||
// see if this is a match
|
||||
if ( *(cur->slot) == *(slot) ) // note comparing values, not addresses !!!
|
||||
{
|
||||
// we have a match, return it
|
||||
return cur;
|
||||
}
|
||||
|
||||
// advance to next in list
|
||||
cur = cur->next;
|
||||
}
|
||||
|
||||
// no match
|
||||
return 0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------------------------------------------------------------------
|
||||
bool signal_base::add_to_list(slot_base* slot)
|
||||
{
|
||||
// a sanity check
|
||||
assert((head && tail) || (!head && !tail));
|
||||
|
||||
// make a new list_node to hold this slot in the list
|
||||
// and initialize with this slot pointer
|
||||
list_node* node = new list_node(slot);
|
||||
assert(node);
|
||||
if ( !node )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// setup new list_node
|
||||
node->prev = tail; // prev is tail because we'll put this list_node behind it (i.e. the new tail)
|
||||
node->next = 0; // next is 0 because we'll put this list_node on the tail
|
||||
|
||||
// add to tail
|
||||
if ( tail )
|
||||
{
|
||||
// tail exists, just append
|
||||
tail->next = node; // insert item after current tail
|
||||
tail = node; // now have a new tail
|
||||
}
|
||||
else
|
||||
{
|
||||
// list is currently empty, add this new list_node
|
||||
head = tail = node; // now have a single list_node, which is also both the head and tail
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------------------------------------------------------------------
|
||||
void signal_base::remove_from_list(list_node* n)
|
||||
{
|
||||
// do a little sanity checking
|
||||
assert((head && tail) || (!head && !tail));
|
||||
assert(n->prev == 0 || n->prev->next == n);
|
||||
assert(n->next == 0 || n->next->prev == n);
|
||||
|
||||
// if this is the head, set the new head
|
||||
if ( n == head )
|
||||
{
|
||||
head = n->next;
|
||||
}
|
||||
|
||||
// if this is the tail, set the new tail
|
||||
if ( n == tail )
|
||||
{
|
||||
tail = n->prev;
|
||||
}
|
||||
|
||||
// set list to skip over this list_node
|
||||
if ( n->prev )
|
||||
{
|
||||
n->prev->next = n->next;
|
||||
}
|
||||
if ( n->next )
|
||||
{
|
||||
n->next->prev = n->prev;
|
||||
}
|
||||
|
||||
// finally, destroy the node
|
||||
delete n;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------------------------------------------------------------------
|
||||
void signal_base::remove_pending_nodes( void )
|
||||
{
|
||||
list_node* pIndex;
|
||||
list_node* pNext;
|
||||
|
||||
pIndex = head;
|
||||
|
||||
while( pIndex )
|
||||
{
|
||||
// Prepare the next link in the list the removal stage.
|
||||
pNext = pIndex->next;
|
||||
|
||||
// Do we need to remove this link.
|
||||
if( pIndex->bDeleteRequested )
|
||||
remove_from_list( pIndex );
|
||||
|
||||
// Go to the next item.
|
||||
pIndex = pNext;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------------------------------------------------------------------
|
||||
void signal_base::BeginEmit( void )
|
||||
{
|
||||
bEmitting = true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------------------------------------------------------------------
|
||||
void signal_base::EndEmit( void )
|
||||
{
|
||||
bEmitting = false;
|
||||
|
||||
remove_pending_nodes( );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------------------------------------------------------------------
|
||||
bool signal_base::IsSignalEmitting( void ) const
|
||||
{
|
||||
return bEmitting;
|
||||
}
|
||||
Reference in new issue
Block a user