#include "stdafx.hpp"
using namespace NFR;
//
// CCallbackIdCreator
//
CCallbackIdCreator::CCallbackIdCreator()
{
m_dLastId = 0;
}
CCallbackIdCreator& CCallbackIdCreator::inst()
{
static CCallbackIdCreator m_inst;
return m_inst;
}
unsigned int CCallbackIdCreator::getId()
{
return ++m_dLastId;
}
//
// Callback
//
Callback::Callback()
{
m_vpParameters = NULL;
Reset();
}
Callback::Callback( const Callback& obj )
{
Reset( obj );
}
Callback::~Callback()
{
}
Callback::Callback( int parsNum, ... )
{
va_list list;
va_start( list, parsNum );
m_pThis = va_arg( list, void* );
m_pFunc = va_arg( list, void* );
m_dNumParameters = parsNum;
m_vpParameters = NULL;
if( parsNum )
{
m_vpParameters = new int[parsNum];
for( int i = parsNum - 1; i >= 0; i -- )
m_vpParameters[i] = va_arg( list, int );
}
va_end( list );
m_bIsInstantiated = true;
m_id = CCallbackIdCreator::inst().getId();
}
void Callback::call( void* par )
{
callInt( par );
}
int Callback::callInt( unsigned int parsNum, ... )
{
va_list list;
delete[] m_vpParameters;
m_vpParameters = NULL;
if( parsNum )
{
m_vpParameters = new int[parsNum];
va_start( list, parsNum );
for( unsigned int i = parsNum - 1; i >= 0; i -- )
va_arg( list, int );
va_end( list );
}
return callInt();
}
int Callback::callInt( void* par )
{
if( par != NULL )
{
setPar( par );
}
if( m_bIsInstantiated )
{
void* pFunc = (void*) m_pFunc;
void* pThis = m_pThis;
int dSize = 0;
int dNumParameters = m_dNumParameters;
int dOut = 0;
/* w tym miejscu wszystkie parametry sa juz ustawione w odpowiedniej konwencji wywolania */
int* pParameter = m_vpParameters;
__asm
{
mov ecx, 0 //zerujemy iterator
//while( true )
our_for: //{
cmp ecx, [dNumParameters] //if( i < dNumParameters )
jae end_our_for //goto end_our_for;
mov ebx, pParameter //wrzucamy parametr ze wskaznika
push [ebx] //na stos
add ecx, 1 //i++;
add dSize, 4 //zwiekszamy wielkosc oczyszczajaca stos
add pParameter, 4 //wybieramy nastepny parametr
jmp our_for
end_our_for: //}
mov ecx, pThis; //ustawiamy funkcje i wywolujemy ja
call pFunc; //
add esp, [dSize] //czas oczyscic stos
mov [dOut], eax; //umieszczamy wynik w zmiennej
//potrzebne to jest w zasadzie
//tylko dla wywolania callInt
//ale nic nie stoi na przeszkodzie
//aby wywolac to takze dla void
}
return dOut;
}
//aby kompilator sie nie plul w zasadzie :P
return 0;
}
void Callback::setPar( void* par )
{
setPars( 0 );
}
void Callback::setPars( int parsNum, ... )
{
va_list list;
delete[] m_vpParameters;
m_vpParameters = NULL;
if( parsNum )
{
m_vpParameters = new int[parsNum];
va_start( list, parsNum );
for( unsigned int i = parsNum - 1; i >= 0; i -- )
va_arg( list, int );
va_end( list );
}
}
unsigned int Callback::getId()
{
return m_id;
}
void Callback::operator= ( const Callback& obj )
{
Reset( obj );
}
bool Callback::operator== ( const Callback& obj ) const
{
if( m_id == m_id )
return true;
else
return false;
}
bool Callback::operator!= ( const Callback& obj ) const
{
if( m_id != obj.m_id )
return true;
else
return false;
}
void Callback::Reset( const Callback& obj )
{
m_pThis = obj.m_pThis;
m_pFunc = obj.m_pFunc;
m_dNumParameters = obj.m_dNumParameters;
m_vpParameters = new int[m_dNumParameters];
for( unsigned int i = 0; i < m_dNumParameters; i ++ )
m_vpParameters[i] = obj.m_vpParameters[i];
m_bIsInstantiated = obj.m_bIsInstantiated;
m_id = obj.m_id;
}
void Callback::Reset()
{
m_pThis = NULL;
m_pFunc = NULL;
delete[] m_vpParameters;
m_vpParameters = NULL;
m_dNumParameters = 0;
m_bIsInstantiated = NULL;
m_id = NULL;
}
Callback::operator bool() const
{
if( m_id )
return true;
return false;
}