void TestChannelsAccessorTypeConvert(void)
{
	CChannels*					pcChannels;
	CChannelsAccessor*			pcAccessor;
	CChannelsAccessorCreator	cCreator;
	float*						pfData;
	float						afData[3];

	pcChannels = UMalloc(CChannels);
	pcChannels->Init();
	pcChannels->BeginChange();
	pcChannels->SetSize(2);
	pcChannels->AddChannel(CHANNEL_NAME_JACK, PT_ushort);
	pcChannels->AddChannel(CHANNEL_NAME_BOB, PT_uint);
	pcChannels->AddChannel(CHANNEL_NAME_ALICE, PT_ushort);
	pcChannels->EndChange();
	pcChannels->Clear();

	cCreator.Init(pcChannels);
	cCreator.AddAccess(CHANNEL_NAME_JACK, PT_float);
	cCreator.AddAccess(CHANNEL_NAME_ALICE, PT_float);
	pcAccessor = cCreator.CreateAndKill();
	AssertString("CChannelsAccessorTypeConvert", pcAccessor->ClassName());
	afData[0] = 1.0f;
	afData[1] = 0.34f;
	pcAccessor->Set(1, afData);
	AssertShortHex((short)0xffff, *(unsigned short*)RemapSinglePointer(pcChannels->GetData(), 8 + 0));
	AssertShortHex(0x5709, *(unsigned short*)RemapSinglePointer(pcChannels->GetData(), 8 + 6));
	pfData = (float*)pcAccessor->Get(1);
	AssertFloat(1.0f, pfData[0], 2);
	AssertFloat(0.34f, pfData[1], 2);
	pcAccessor->Kill();

	cCreator.Init(pcChannels);
	cCreator.AddAccess(CHANNEL_NAME_BOB, PT_float);
	pcAccessor = cCreator.CreateAndKill();
	AssertString("CChannelsAccessorTypeConvert", pcAccessor->ClassName());
	afData[0] = 0.8f;
	pcAccessor->Set(1, afData);
	AssertIntHex(0xcccccd00, *(int*)RemapSinglePointer(pcChannels->GetData(), 8 + 2));
	pcAccessor->Kill();

	cCreator.Init(pcChannels);
	cCreator.AddAccess(CHANNEL_NAME_ALICE, PT_float);
	cCreator.AddAccess(CHANNEL_NAME_BOB, PT_float);
	pcAccessor = cCreator.CreateAndKill();
	AssertString("CChannelsAccessorTypeConvert", pcAccessor->ClassName());
	pfData = (float*)pcAccessor->Get(1);
	AssertFloat(0.34f, pfData[0], 2);
	AssertFloat(0.80f, pfData[1], 2);
	pcAccessor->Kill();
}
void TestImageColourMultiAccessor(void)
{
	CImageColourNormal		cNormal;
	CImageColourOpacity		cAlpha;
	CImageColourCombo2		cColour;
	CChannels*				pcChannels;
	CImageAccessor*			pcAccessor;
	CImage					cImage;
	SImageColour			sDest;
	BOOL					bResult;

	cNormal.Init(0.7f, -0.6f, -0.5f);
	cAlpha.Init(0.333f);
	cColour.Init(&cNormal, &cAlpha);

	cImage.Init();
	cImage.BeginChange();
	cImage.AddChannel(IMAGE_DIFFUSE_GREEN, PT_uchar);
	cImage.AddChannel(IMAGE_NORMAL_Y, PT_float);
	cImage.AddChannel(IMAGE_DIFFUSE_BLUE, PT_uchar);
	cImage.AddChannel(IMAGE_OPACITY, PT_ushort);
	cImage.AddChannel(IMAGE_DIFFUSE_RED, PT_uchar);
	cImage.AddChannel(IMAGE_MASK, PT_int);
	cImage.AddChannel(IMAGE_NORMAL_Z, PT_float);
	cImage.AddChannel(IMAGE_NORMAL_X, PT_float);
	cImage.SetSize(1, 2);
	cImage.EndChange();
	cImage.Clear();

	pcAccessor = CImageAccessorCreator::Create(&cImage, IMAGE_NORMAL_X, IMAGE_NORMAL_Y, IMAGE_NORMAL_Z, IMAGE_OPACITY, CHANNEL_ZERO);

	sDest.Full();
	bResult = pcAccessor->MakeColour(&sDest, &cColour);
	AssertBool(TRUE, bResult);

	AssertFloat(0.7f, *((float*)&((sDest).c)[0x0]), 3);
	AssertFloat(-0.6f, *((float*)&((sDest).c)[0x4]), 3);
	AssertFloat(-0.5f, *((float*)&((sDest).c)[0x8]), 3);
	AssertShortHex(0x553f, *((unsigned short*)&((sDest).c)[0xc]));

	pcAccessor->Set(0, 1, &sDest);
	pcAccessor->Kill();

	pcChannels = &cImage.mcChannels;
	AssertFloat(-0.6f, *(float*)&(pcChannels->GetData()[22]), 3);
	AssertFloat( 0.7f, *(float*)&(pcChannels->GetData()[38]), 3);
	AssertFloat(-0.5f, *(float*)&(pcChannels->GetData()[34]), 3);
	AssertShortHex(0x553f, *(unsigned short*)&(pcChannels->GetData()[27]));
}
void TestArrayPrimitiveTemplate(void)
{
	CArrayChar		aChars;
	CArrayFloat		aFloats;
	CArrayDouble	aDoubles;
	CArrayLong		aLongs;
	int				iIndex;

	BeginTests();

	aChars.Init(1);
	aChars.Add('A');
	AssertChar('A', aChars.GetValue(0));
	aChars.Kill();

	aFloats.Init(2);
	aFloats.InsertAt(5.1f, 0);
	AssertFloat(5.1f, aFloats.GetValue(0), 2);
	AssertInt(2, aFloats.AllocatedElements());
	AssertInt(1, aFloats.NumElements());
	aFloats.Kill();

	aDoubles.Init(3);
	aDoubles.Add(0.0);
	aDoubles.Add(0.1);
	aDoubles.Add(0.2);
	aDoubles.Add(0.3);
	aDoubles.Add(0.4);
	AssertTrue(aDoubles.IsSorted());
	aDoubles.InsertAt(0.5, 2);
	AssertFalse(aDoubles.IsSorted());
	aDoubles.Kill();

	aLongs.Init(4);
	aLongs.AddList(0LL, 4LL, 0x3122345482773411LL, 2LL, 1LL, 0LL);
	iIndex = aLongs.Find(0x3122345482773411LL);
	AssertInt(1, iIndex);
	aLongs.Kill();

	TestStatistics();
}
void TestImageColourAccessorFloats(void)
{
	CImageColourNormal	cNormal;
	CChannels*			pcChannels;
	CImageAccessor*		pcAccessor;
	CImage				cImage;
	SImageColour		sDest;
	BOOL				bResult;

	cNormal.Init(0.7f, 0.6f, 0.5f);
	cImage.Init();
	cImage.BeginChange();
	cImage.AddChannel(IMAGE_DIFFUSE_GREEN, PT_uchar);
	cImage.AddChannel(IMAGE_NORMAL_Y, PT_float);
	cImage.AddChannel(IMAGE_DIFFUSE_BLUE, PT_uchar);
	cImage.AddChannel(IMAGE_OPACITY, PT_short);
	cImage.AddChannel(IMAGE_DIFFUSE_RED, PT_uchar);
	cImage.AddChannel(IMAGE_MASK, PT_int);
	cImage.AddChannel(IMAGE_NORMAL_Z, PT_float);
	cImage.AddChannel(IMAGE_NORMAL_X, PT_float);
	cImage.SetSize(1, 2);
	cImage.EndChange();
	cImage.Clear();

	pcAccessor = CImageAccessorCreator::Create(&cImage, PT_float, IMAGE_NORMAL_X, IMAGE_NORMAL_Y, IMAGE_NORMAL_Z, CHANNEL_ZERO);

	sDest.Full();
	bResult = pcAccessor->MakeColour(&sDest, &cNormal);
	AssertBool(TRUE, bResult);

	AssertFloat(0.7f, *((float*)&((sDest).c)[0x0]), 3);
	AssertFloat(0.6f, *((float*)&((sDest).c)[0x4]), 3);
	AssertFloat(0.5f, *((float*)&((sDest).c)[0x8]), 3);

	pcAccessor->Set(0, 1, &sDest);
	pcAccessor->Kill();

	pcChannels = &cImage.mcChannels;
	
	AssertFloat(0.6f, *(float*)&(pcChannels->GetData()[22]), 3);
	AssertFloat(0.7f, *(float*)&(pcChannels->GetData()[38]), 3);
	AssertFloat(0.5f, *(float*)&(pcChannels->GetData()[34]), 3);
}
void TestTruncateFloat(void)
{
	AssertFloat(1.0f, TruncateFloat(1.25f, 0), 7);
	AssertFloat(13.0f, TruncateFloat(13.5493f, 0), 7);
	AssertFloat(8.0f, TruncateFloat(13.5493f, 3), 7);  //mask 2^3 = 8 = %1000  value 13 = %1011
	AssertFloat(13.53125f, TruncateFloat(13.5493f, -5), 7);
	AssertFloat(0.0f, TruncateFloat(1.0f, 1), 7);
	AssertFloat(-1.0f, TruncateFloat(-1.25f, 0), 7);
	AssertFloat(-13.0f, TruncateFloat(-13.5493f, 0), 7);
	AssertFloat(-8.0f, TruncateFloat(-13.5493f, 3), 7);
	AssertFloat(-13.53125f, TruncateFloat(-13.5493f, -5), 7);
	AssertFloat(0.8125f, TruncateFloat(0.824f, -5), 7);
	AssertFloat(0.8125f, TruncateFloat(0.817f, -5), 7);
	AssertFloat(280.39874f, TruncateFloat(280.39874f, -16), 7);
	AssertFloat(80.39874f, TruncateFloat(80.39874f, -16), 7);
	AssertFloat(1000000.0f, TruncateFloat(1000000.0, -16), 7);
}
void TestRoundFloat(void)
{
	AssertFloat(1.0f, RoundFloat(0.75f, 0), 7);
	AssertFloat(1.0f, RoundFloat(1.0f, 0), 7);
	AssertFloat(1.0f, RoundFloat(0.5f, 0), 7);
	AssertFloat(1.0f, RoundFloat(1.49f, 0), 7);
	AssertFloat(0.0f, RoundFloat(0.25f, 0), 7);
	AssertFloat(-1.0f, RoundFloat(-0.75f, 0), 7);
	AssertFloat(-1.0f, RoundFloat(-1.0f, 0), 7);
	AssertFloat(-1.0f, RoundFloat(-0.5f, 0), 7);
	AssertFloat(0.0f, RoundFloat(-0.25f, 0), 7);
	AssertFloat(2.0f, RoundFloat(2.9f, 1), 7);
	AssertFloat(2.0f, RoundFloat(1.0f, 1), 7);
}
void TestSingleChannelAccessor(void)
{
	BeginTests();
	ClassStorageInit();
	TypeConverterInit();
	UnknownsInit();

	
	CChannels					cChannels;
	unsigned char				cData[9] = "ti@YA,\n#";
	CSingleChannelAccessor		cSingle;
	char						c;
	unsigned					s;

	cChannels.Init();
	cChannels.BeginChange();
	cChannels.SetData(cData);
	cChannels.AddChannel(16, 15, 14, 13, PT_nybble);
	cChannels.AddChannel(12, 11, PT_uchar);
	cChannels.AddChannel(10, PT_ushort);
	cChannels.AddChannel(9, 8, 7, 6, PT_bit);
	cChannels.AddChannel(5, 4, PT_crumb);
	cChannels.AddChannel(3, PT_uchar);
	cChannels.SetSize(1);
	cChannels.EndChange();
	cSingle.Init(&cChannels);
	AssertFloat(0.27f, cSingle.GetConvertToFloat(16), 2);
	AssertFloat(0.47f, cSingle.GetConvertToFloat(15), 2);
	AssertFloat(0.60f, cSingle.GetConvertToFloat(14), 2);
	AssertFloat(0.40f, cSingle.GetConvertToFloat(13), 2);
	cSingle.GetNative(16, &c); AssertChar(4, c);
	cSingle.GetNative(15, &c); AssertChar(7, c);
	cSingle.GetNative(14, &c); AssertChar(9, c);
	cSingle.GetNative(13, &c); AssertChar(6, c);

	AssertFloat(0.25f, cSingle.GetConvertToFloat(12), 2);
	AssertFloat(0.35f, cSingle.GetConvertToFloat(11), 2);
	cSingle.GetNative(12, &c); AssertChar('@', c);
	cSingle.GetNative(11, &c); AssertChar('Y', c);

	cSingle.GetNative(10, &s); AssertShortHex(0x2c41, s);

	AssertFloat(0.0f, cSingle.GetConvertToFloat(9), 1);
	AssertFloat(1.0f, cSingle.GetConvertToFloat(8), 1);
	AssertFloat(0.0f, cSingle.GetConvertToFloat(7), 1);
	AssertFloat(1.0f, cSingle.GetConvertToFloat(6), 1);

	AssertFloat(0.14f, cSingle.GetConvertToFloat(3), 2);
	cSingle.GetNative(3, &c); AssertChar('#', c);

	cChannels.Kill();


	UnknownsKill();
	TypeConverterKill();
	ClassStorageKill();
	TestStatistics();
}
void TestChannelsAccessorChannelBitty(void)
{
	CChannels*					pcChannels;
	CChannelsAccessor*			pcAccessor;
	CChannelsAccessorCreator	cCreator;
	unsigned char*				pucData;
	unsigned char				aucData[3];
	float*						pfData;

	pcChannels = UMalloc(CChannels);
	pcChannels->Init();
	pcChannels->BeginChange();
	pcChannels->SetSize(1);
	pcChannels->AddChannel(CHANNEL_NAME_JACK, PT_bit);
	pcChannels->AddChannel(CHANNEL_NAME_BOB, PT_crumb);
	pcChannels->AddChannel(CHANNEL_NAME_ALICE, PT_bit);
	pcChannels->EndChange();
	pcChannels->Clear();
	AssertInt(1, pcChannels->GetByteSize());
	AssertInt(1, pcChannels->GetSize());

	cCreator.Init(pcChannels);
	cCreator.AddAccess(CHANNEL_NAME_JACK, PT_uchar);
	cCreator.AddAccess(CHANNEL_NAME_BOB, PT_uchar);
	cCreator.AddAccess(CHANNEL_NAME_ALICE, PT_uchar);
	pcAccessor = cCreator.CreateAndKill();
	AssertString("CChannelsAccessorChannelBitty", pcAccessor->ClassName());
	aucData[0] = 0xff;
	aucData[1] = 0x55;
	aucData[2] = 0xff;
	pcAccessor->Set(0, aucData);
	AssertChar(0xb, *pcChannels->GetData());  //Or maybe 0xd.  I'm not sure of the ordering
	pucData = (unsigned char*)pcAccessor->Get(0);
	AssertChar((char)0xff, pucData[0]);
	AssertChar((char)0x55, pucData[1]);
	AssertChar((char)0xff, pucData[2]);
	pcAccessor->Kill();

	pcChannels->BeginChange();
	pcChannels->SetSize(2);
	pcChannels->EndChange();
	AssertInt(1, pcChannels->GetByteSize());
	AssertInt(2, pcChannels->GetSize());

	cCreator.Init(pcChannels);
	cCreator.AddAccess(CHANNEL_NAME_JACK, PT_uchar);
	cCreator.AddAccess(CHANNEL_NAME_BOB, PT_uchar);
	cCreator.AddAccess(CHANNEL_NAME_ALICE, PT_uchar);
	pcAccessor = cCreator.CreateAndKill();
	AssertString("CChannelsAccessorChannelBitty", pcAccessor->ClassName());
	pucData = (unsigned char*)pcAccessor->Get(0);
	AssertChar((char)0xff, pucData[0]);
	AssertChar((char)0x55, pucData[1]);
	AssertChar((char)0xff, pucData[2]);

	aucData[0] = 0x00;
	aucData[1] = 0xaa;
	aucData[2] = 0xff;
	pcAccessor->Set(1, aucData);
	AssertChar(0xc, ((unsigned char)*pcChannels->GetData()) >> 4);  //Or maybe 0xd.  I'm not sure of the ordering
	pucData = (unsigned char*)pcAccessor->Get(1);
	AssertChar((char)0x00, pucData[0]);
	AssertChar((char)0xaa, pucData[1]);
	AssertChar((char)0xff, pucData[2]);
	pcAccessor->Kill();

	cCreator.Init(pcChannels);
	cCreator.AddAccess(CHANNEL_NAME_ALICE, PT_float);
	cCreator.AddAccess(CHANNEL_NAME_BOB, PT_float);
	pcAccessor = cCreator.CreateAndKill();
	AssertString("CChannelsAccessorChannelBitty", pcAccessor->ClassName());
	pfData = (float*)pcAccessor->Get(0);
	AssertFloat(1.0f, pfData[0], 2);
	AssertFloat(0.33f, pfData[1], 2);
	pfData = (float*)pcAccessor->Get(1);
	AssertFloat(1.0f, pfData[0], 2);
	AssertFloat(0.67f, pfData[1], 2);
	pcAccessor->Kill();
}
void TestEmbeddedObjectContainerDehollowfication(void)
{
	BOOL		bResult;
	CFileUtil	cFileUtil;
	char*		szClassName;
	OIndex		oiComplex;

	cFileUtil.RemoveDir("Output/EmbeddedObject");

	MemoryInit();
	ObjectsInit("Output/EmbeddedObject/");
	SetupEmbeddedObjectConstructors();

	Ptr<CRoot> pRoot = ORoot();
	Ptr<CEmbeddedComplex> pComplex = OMalloc(CEmbeddedComplex)->Init();
	oiComplex = pComplex->GetOI();

	pRoot->Add(pComplex);

	bResult = gcObjects.Flush(TRUE, TRUE);
	AssertTrue(bResult);

	ObjectsKill();
	MemoryKill();

	AssertInt(176, sizeof(CEmbeddedTest));
	AssertInt(544, sizeof(CEmbeddedContainer));
	AssertInt(1032, sizeof(CEmbeddedComplex));

	MemoryInit();
	ObjectsInit("Output/EmbeddedObject/");
	SetupEmbeddedObjectConstructors();

	pRoot = gcObjects.GetRoot();
	AssertTrue(pRoot.IsNotNull());
	pComplex = pRoot->Get(0);
	AssertTrue(pComplex.IsHollow());
	
	szClassName = pComplex->ClassName();
	AssertString("CEmbeddedComplex", szClassName);
	AssertLongLongInt(oiComplex, pComplex.GetIndex());

	AssertInt(1, pComplex->mai[0]);
	AssertInt(2, pComplex->mai[1]);
	
	AssertLongLongInt(INVALID_O_INDEX, pComplex->mcSimple.GetOI());
	AssertInt(85, pComplex->mcSimple.miAmANumber);
	AssertFloat(58.0f, pComplex->mcSimple.mfSoAmI, 0);

	AssertLongLongInt(INVALID_O_INDEX, pComplex->mcContainer.GetOI());
	AssertInt(73, pComplex->mcContainer.mi);
	AssertFloat(666.0f, pComplex->mcContainer.mf, 0);
	AssertString("And", pComplex->mcContainer.msz);

	AssertLongLongInt(INVALID_O_INDEX, pComplex->mcContainer.mcOne.GetOI());
	AssertInt(85, pComplex->mcContainer.mcOne.miAmANumber);
	AssertFloat(58.0f, pComplex->mcContainer.mcOne.mfSoAmI, 0);

	AssertLongLongInt(INVALID_O_INDEX, pComplex->mcContainer.mcTwo.GetOI());
	AssertInt(85, pComplex->mcContainer.mcTwo.miAmANumber);
	AssertFloat(58.0f, pComplex->mcContainer.mcTwo.mfSoAmI, 0);

	AssertLongLongInt(3, gcObjects.NumMemoryIndexes());

	ObjectsKill();
	MemoryKill();
}