//////////////////////////////////////////////////////////////////////////////////////// // // Nestopia - NES/Famicom emulator written in C++ // // Copyright (C) 2003-2008 Martin Freij // // This file is part of Nestopia. // // Nestopia 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. // // Nestopia 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 Nestopia; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // //////////////////////////////////////////////////////////////////////////////////////// #ifndef NST_HOOK_H #define NST_HOOK_H #ifdef NST_PRAGMA_ONCE #pragma once #endif namespace Nes { namespace Core { #ifdef NST_FASTDELEGATE class Hook : public ImplicitBool { class Component {}; typedef void (Component::*Executor)(); Component* component; Executor executor; NST_COMPILE_ASSERT( sizeof(Executor) <= sizeof(void (*)(void*)) ); public: Hook() {} template Hook(T* c,void (T::*e)()) : component ( reinterpret_cast(c) ), executor ( reinterpret_cast(e) ) { NST_COMPILE_ASSERT( sizeof(executor) == sizeof(e) ); } void Execute() const { (*component.*executor)(); } void Unset() { component = NULL; executor = NULL; } bool operator ! () const { return !executor; } bool operator == (const Hook& h) const { return executor == h.executor && component == h.component; } }; #define NES_DECL_HOOK(a_) void Hook_##a_() #define NES_HOOK(o_,a_) void o_::Hook_##a_() #define NES_HOOK_T(t_,o_,a_) t_ void o_::Hook_##a_() #define NES_DO_HOOK(a_) Hook_##a_() #else class Hook : public ImplicitBool { typedef void* Component; typedef void (NST_REGCALL *Executor)(Component); Component component; Executor executor; public: Hook() {} Hook(Component c,Executor e) : component ( c ), executor ( e ) {} void Execute() const { executor( component ); } void Unset() { component = NULL; executor = NULL; } bool operator ! () const { return !executor; } bool operator == (const Hook& h) const { return executor == h.executor && component == h.component; } }; #define NES_DECL_HOOK(a_) \ \ NST_FORCE_INLINE void NST_FASTCALL Hook_M_##a_(); \ static void NST_REGCALL Hook_##a_(void*) #define NES_HOOK(o_,a_) \ \ void NST_REGCALL o_::Hook_##a_(void* p_) \ { \ static_cast(p_)->Hook_M_##a_(); \ } \ \ NST_FORCE_INLINE void NST_FASTCALL o_::Hook_M_##a_() #define NES_HOOK_T(t_,o_,a_) \ \ t_ void NST_REGCALL o_::Hook_##a_(void* p_) \ { \ static_cast(p_)->Hook_M_##a_(); \ } \ \ t_ NST_FORCE_INLINE void NST_FASTCALL o_::Hook_M_##a_() #define NES_DO_HOOK(a_) Hook_##a_(this) #endif } } #endif