/* * Copyright (C) 2004-2005 Vadim Berezniker * http://www.kryptolus.com * * This Program 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, or (at your option) * any later version. * * This Program 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 GNU Make; see the file COPYING. If not, write to * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. * http://www.gnu.org/copyleft/gpl.html * */ #include "stdafx.h" #include "common.h" /* * Creates a new empty signal. */ krySignal::krySignal() : m_disabled(FALSE) { } /* * Assigns a Signal to another signal. */ void krySignal::operator =(krySignal & signal) { // makes a shallow copy of the hooked functions list this->m_funcs = signal.m_funcs; // make a deep copy of the callback function information stored inside the list kryListIterator iter; this->m_funcs.GetIterator(&iter); while(krySignalFuncInfo *info = iter.GetNext()) { krySignalFuncInfo *info_copy = new krySignalFuncInfo; info_copy->func0 = info->func0; info_copy->connect_data1 = info->connect_data1; info_copy->connect_data2 = info->connect_data2; info_copy->type = info->type; iter.SetData(info_copy); } } /* * Destroys the signal object. */ krySignal::~krySignal() { kryListIterator iter; this->m_funcs.GetIterator(&iter); while(krySignalFuncInfo *info = iter.GetNext()) delete info; } /* * Connects the given function to this signal with no extra connect data. * * The callback will be invoked with two parameters: * The object that raised the signal. * The parameter passed when invoked. */ long krySignal::Connect(krySignalFunc0 func) { krySignalFuncInfo *info = new krySignalFuncInfo; info->func0 = func; info->connect_data1 = NULL; info->connect_data2 = NULL; info->type = KRY_SIGNAL_FUNC0; this->m_funcs.Append(info); return (long) info; } /* * Connects the given function to this signal with one connect data. * * The callback will be invoked with three parameters: * The object that raised the signal. * The parameter passed when invoked. * The connect data parameter passed to this function. */ long krySignal::Connect(krySignalFunc1 func, void *connect_data1) { krySignalFuncInfo *info = new krySignalFuncInfo; info->func1 = func; info->connect_data1 = connect_data1; info->connect_data2 = NULL; info->type = KRY_SIGNAL_FUNC1; this->m_funcs.Append(info); return (long) info; } /* * Connects the given function to this signal with two connect data. * * The callback will be invoked with four parameters: * The object that raised the signal. * The parameter passed when invoked. * The first connect data parameter passed to this function. * The second connect data parameter passed to this function. */ long krySignal::Connect(krySignalFunc2 func, void *connect_data1, void *connect_data2) { krySignalFuncInfo *info = new krySignalFuncInfo; info->func2 = func; info->connect_data1 = connect_data1; info->connect_data2 = connect_data2; info->type = KRY_SIGNAL_FUNC2; this->m_funcs.Append(info); return (long) info; } /* * Disconnects any callback that matches the given function. */ void krySignal::Disconnect(void *func) { kryListIterator iter; this->m_funcs.GetIterator(&iter); while(krySignalFuncInfo *info = iter.GetNext()) { if(info->func0 == func) { iter.Remove(); delete info; } } } /* * Disconnecs any callback that matches the given ID. * (This ID is obtained when calling the Connect method.) */ void krySignal::Disconnect(int id) { kryListIterator iter; iter.AllowRemoveCurrent(); this->m_funcs.GetIterator(&iter); while(krySignalFuncInfo *info = iter.GetNext()) { if(info == (krySignalFuncInfo *) id) { iter.Remove(); delete info; } } } /* * Disables this signal. * While the signal is in the "disabled" state, callbacks will not be invoked. */ void krySignal::Disable() { this->m_disabled = TRUE; } /* * Enables this signal. * * If this signal was previously disabled, resumes callback invokation. */ void krySignal::Enable() { this->m_disabled = FALSE; } /* * Invoke all callbacks associated with this signal. * object: Object that raised the event. * param: Data to be passed to the callback. */ void krySignal::Invoke(kryObject *object, void *param) { if(this->m_disabled) return; kryListIterator iter; this->m_funcs.GetIterator(&iter); while(krySignalFuncInfo *func = iter.GetNext()) { if(func->type == KRY_SIGNAL_FUNC0) func->func0(object, param); else if(func->type == KRY_SIGNAL_FUNC1) func->func1(object, param, func->connect_data1); else if(func->type == KRY_SIGNAL_FUNC2) func->func2(object, param, func->connect_data1, func->connect_data2); } }