/** @file functor.cpp
 * 	@headerfile functor.h "EABaseTypes/functor.h"
 *	@author Chris Burns (cburns@ea.com)
 *
 *	EABaseTypes
 *	(c) 2011 Electronic Arts Inc. 
 */

#include "EABaseTypes/functor.h"
#include "EAStdC/EAMemory.h"
#include "coreallocator/icoreallocatormacros.h"

namespace EA
{
	namespace Types
	{
		/* virtual */ Types::BaseTypeReturn FunctorBase::Clone()
		{
			AddRef();
			return this;
		}

		//lint -efunc(931, EA::Types::FunctorBase::Equals)
		/* virtual */ bool FunctorBase::Equals(Types::FunctionIn pCompare)
		{ 
			bool result = false;
			if(pCompare->GetFunctionType() == GetFunctionType())
			{
				result = (*this) == *(static_cast<FunctorBase*>(pCompare.GetUnsafePointer()));
			}
			return result;
		}

		bool FunctorBase::operator==(const FunctorBase& rhs) const
		{
			return (mObject == rhs.mObject && EA::StdC::Memcmp(mMemberFunc, rhs.mMemberFunc, sizeof(mMemberFunc)) == 0 );
		}

		FunctorBase::FunctorBase(Factory* factory, void* pFunction)
			: Function(factory)
			, mExecuteFunc(NULL)
			, mObject(NULL)
		{
			clear();
			mFunc = pFunction;

#if !defined(EA_FINAL)
			ArrayRef debugInfo = factory->Array();
			debugInfo->push_back(PtrUserData<void>::Create(factory, mFunc));

			SetDebugInfo(debugInfo);
#endif
		}

		FunctorBase::FunctorBase(Factory* factory, void * executePtr, void *object, void *memFunc, size_t memFuncSize)
			: Function(factory)
			, mExecuteFunc(NULL)
			, mObject(NULL)
		{
			mExecuteFunc = executePtr;
			mObject = object;
			EA::StdC::MemclearC(mMemberFunc, sizeof(mMemberFunc));
			EA_ASSERT_MESSAGE(memFuncSize <= sizeof(mMemberFunc), ("ERROR: MEMBER FUNCTION POITNER SIZE TOO LARGE!!!"));
			EA::StdC::MemcpyC(mMemberFunc, memFunc, memFuncSize);

#if !defined(EA_FINAL)
			ArrayRef debugInfo = factory->Array();
			debugInfo->push_back(PtrUserData<void>::Create(factory, mFunc));

			SetDebugInfo(debugInfo);
#endif
		}

		/* virtual */ FunctorBase::~FunctorBase()
		{
		}

		void FunctorBase::clear()
		{
			mExecuteFunc = NULL; 
			mObject = NULL; 
			memset(mMemberFunc, 0, sizeof(mMemberFunc));
		}
	}
}
