⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 elemdbm.cpp

📁 3D Game Engine Design Source Code非常棒
💻 CPP
字号:
#include <string.h>
#include <fstream.h>
#include "elemdbm.h"

// element type registration
static int chunksize = 16;
int mgcElementDBM::maxregistered = 0;
int mgcElementDBM::registered = 0;
mgcElementDBM::ElementRecord* mgcElementDBM::record = 0;
mgcElementDBM::UnresolvedConvert* mgcElementDBM::cnvlist = 0;

// error handling
int mgcElementDBM::verbose = 0;
unsigned mgcElementDBM::error = 0;
const unsigned mgcElementDBM::allocation_failed = 0x00000001;
const unsigned mgcElementDBM::unknown_ordering  = 0x00000002;
const unsigned mgcElementDBM::exceeded_maximum  = 0x00000004;
const char* mgcElementDBM::message[3] = {
	"allocation failed",
	"unknown byte ordering",
	"exceeded maximum element types (contact eberly@cs.unc.edu)"
};

//===========================================================================
int mgcElementDBM::
CreateDataBase ()
{
	// guarantee call succeeds exactly once
	static int first_time = 1;
	if ( first_time == 0 )
		return 0;
	first_time = 0;

	// initial allocation of data base records
	maxregistered = chunksize;
	record = new ElementRecord[maxregistered];
	if ( record == 0 ) {
		Report(allocation_failed);
		return -1;
	}

	memset(record,0,maxregistered*sizeof(ElementRecord));

	for (int i = 0; i < maxregistered; i++) {
		record[i].convert_to = new EFconvert[maxregistered];
		if ( record[i].convert_to == 0 ) {
			Report(allocation_failed);
			return -1;
		}
	}

	return 1;
}
//---------------------------------------------------------------------------
void mgcElementDBM::
DestroyDataBase ()
{
	while ( cnvlist ) {
		UnresolvedConvert* front = cnvlist;
		cnvlist = cnvlist->next;
		delete front;
	}

	delete[] record;
	record = 0;
	maxregistered = 0;
	registered = 0;
}
//---------------------------------------------------------------------------
int mgcElementDBM::
AddType (const ElementRecord& er)
{
	if ( registered >= maxregistered ) { // reallocate needs to be done
    	Report(exceeded_maximum);
		return -1;
	}

	// update data base
	record[registered].addrtype    = er.addrtype;
	record[registered].description = er.description;
	record[registered].memory_size = er.memory_size;
	record[registered].packed_size = er.packed_size;
	record[registered].input       = er.input;
	record[registered].output      = er.output;
	record[registered].reverse     = er.reverse;
	record[registered].pack        = er.pack;
	record[registered].unpack      = er.unpack;

	// Update "const int Derived::type".  Typecasting addrtype circumvents
	// the "const" protection.
	*(int*)record[registered].addrtype = registered;

	// update conversions
	for (UnresolvedConvert* unr = cnvlist, *prev = 0; unr;  ) {
		int src_exists = 0, trg_exists = 0;
		for (int i = 0; i <= registered; i++) {
			if ( unr->srctype == record[i].addrtype )
				src_exists = 1;
			if ( unr->trgtype == record[i].addrtype )
				trg_exists = 1;
		}
		if ( src_exists && trg_exists ) {
			int srctype;
			if ( unr->srctype == record[registered].addrtype )
				srctype = registered;
			else
				srctype = *unr->srctype;
			int trgtype;
			if ( unr->trgtype == record[registered].addrtype )
				trgtype = registered;
			else
				trgtype = *unr->trgtype;
			record[srctype].convert_to[trgtype] = unr->convert_to;
			UnresolvedConvert* temp = unr;
			if ( prev == 0 ) {
				cnvlist = unr->next;
				unr = unr->next;
			}
			else {
				prev->next = unr->next;
				unr = unr->next;
			}
			delete temp;
		}
		else {
			prev = unr;
			unr = unr->next;
		}
	}

	return registered++;
}
//---------------------------------------------------------------------------
int mgcElementDBM::
AddConvert (const int& srctype, const int& trgtype, EFconvert f)
{
	// Both srctype and trgtype must be in data base before adding conversion
	// to the proper record.  Otherwise the conversion is put on a list of
	// unresolved conversions and (probably) added later.

	int src_exists = 0, trg_exists = 0;
	for (int i = 0; i < registered; i++) {
		if ( &srctype == record[i].addrtype )
			src_exists = 1;
		if ( &trgtype == record[i].addrtype )
			trg_exists = 1;
	}
	if ( src_exists && trg_exists )
		record[srctype].convert_to[trgtype] = f;
	else {
		// place conversion on the unresolved list
		UnresolvedConvert* unr = new UnresolvedConvert;
		if ( unr == 0 ) {
			Report(allocation_failed);
			return 0;
		}
		unr->srctype = &srctype;
		unr->trgtype = &trgtype;
		unr->convert_to = f;
		unr->next = cnvlist;
		cnvlist = unr;
	}

	return 1;
}
//---------------------------------------------------------------------------
int mgcElementDBM::
Valid (int type)
{
	return 0 <= type && type < registered;
}
//---------------------------------------------------------------------------
int mgcElementDBM::
Type (const char* description)
{
	for (int type = 0; type < registered; type++) {
		int i;
		for (i = 0; description[i]; i++)
			if ( description[i] != record[type].description[i] )
				break;
		if ( description[i] == 0 )
			return type;
	}
	return -1;
}
//---------------------------------------------------------------------------
const char* mgcElementDBM::
Description (int type)
{
	return Valid(type) ? record[type].description : 0;
}
//---------------------------------------------------------------------------
int mgcElementDBM::
MemorySize (int type)
{
	return Valid(type) ? record[type].memory_size : 0;
}
//---------------------------------------------------------------------------
int mgcElementDBM::
PackedSize (int type)
{
	return Valid(type) ? record[type].packed_size : 0;
}
//---------------------------------------------------------------------------
int mgcElementDBM::
ByteOrder ()
{
	static int byte_order = -1;

	if ( byte_order == -1 ) {  // determine memory byte order
		long deadbeef = 0xdeadbeefL;
		if ( *(unsigned char*)&deadbeef == 0xef )  // ibm pc, dec mips
			byte_order = 0;
		else if ( *(unsigned char*)&deadbeef == 0xde )  // sparc, hp-pa
			byte_order = 1;
		else  { // unknown ordering (if ever happens, need to modify code)
			byte_order = -1;
			Report(unknown_ordering);
		}
	}
	return byte_order;
}
//---------------------------------------------------------------------------
void mgcElementDBM::
Reverse2 (int quantity, void* src)
{
	unsigned char* usrc = (unsigned char*) src;
	for (
		int i0=0, i1=1;
		i0 < 2*quantity;
		i0+=2, i1+=2)
	{
		usrc[i1] ^= usrc[i0];
		usrc[i0] ^= usrc[i1];
		usrc[i1] ^= usrc[i0];
	}
}
//---------------------------------------------------------------------------
void mgcElementDBM::
Reverse4 (int quantity, void* src)
{
	unsigned char* usrc = (unsigned char*) src;
	for (
		int i0=0, i1=1, i2=2, i3=3;
		i0 < 4*quantity;
		i0+=4, i1+=4, i2+=4, i3+=4)
	{
		usrc[i3] ^= usrc[i0];
		usrc[i0] ^= usrc[i3];
		usrc[i3] ^= usrc[i0];

		usrc[i2] ^= usrc[i1];
		usrc[i1] ^= usrc[i2];
		usrc[i2] ^= usrc[i1];
	}
}
//---------------------------------------------------------------------------
void mgcElementDBM::
Reverse8 (int quantity, void* src)
{
	unsigned char* usrc = (unsigned char*) src;
	for (
		int i0=0, i1=1, i2=2, i3=3, i4=4, i5=5, i6=6, i7=7;
		i0 < 8*quantity;
		i0+=8, i1+=8, i2+=8, i3+=8, i4+=8, i5+=8, i6+=8, i7+=8 )
	{
		usrc[i7] ^= usrc[i0];
		usrc[i0] ^= usrc[i7];
		usrc[i7] ^= usrc[i0];

		usrc[i6] ^= usrc[i1];
		usrc[i1] ^= usrc[i6];
		usrc[i6] ^= usrc[i1];

		usrc[i5] ^= usrc[i2];
		usrc[i2] ^= usrc[i5];
		usrc[i5] ^= usrc[i2];

		usrc[i4] ^= usrc[i3];
		usrc[i3] ^= usrc[i4];
		usrc[i4] ^= usrc[i3];
	}
}
//---------------------------------------------------------------------------
int mgcElementDBM::
Reversible (int type)
{
	return Valid(type) && record[type].reverse;
}
//---------------------------------------------------------------------------
int mgcElementDBM::
Reverse (int quantity, int type, void* src)
{
	if ( Reversible(type) ) {
		record[type].reverse(quantity,src);
		return 1;
	}
	else
		return 0;
}
//---------------------------------------------------------------------------
int mgcElementDBM::
Packable (int type)
{
	return Valid(type) && record[type].pack;
}
//---------------------------------------------------------------------------
int mgcElementDBM::
Pack (int quantity, int type, void* src)
{
	if ( Packable(type) ) {
		record[type].pack(quantity,src);
		return 1;
	}
	else
		return 0;
}
//---------------------------------------------------------------------------
int mgcElementDBM::
Unpackable (int type)
{
	return Valid(type) && record[type].unpack;
}
//---------------------------------------------------------------------------
int mgcElementDBM::
Unpack (int quantity, int type, void* src)
{
	if ( Unpackable(type) ) {
		record[type].unpack(quantity,src);
		return 1;
	}
	else
		return 0;
}
//---------------------------------------------------------------------------
int mgcElementDBM::
Convertible (int srctype, int trgtype)
{
	return Valid(srctype) &&
		   Valid(trgtype) &&
		   record[srctype].convert_to[trgtype];
}
//---------------------------------------------------------------------------
int mgcElementDBM::
Convert (int quantity, int srctype, void* src, int trgtype, void* trg)
{
	if ( Convertible(srctype,trgtype) ) {
		record[srctype].convert_to[trgtype](quantity,src,trg);
		return 1;
	}
	else
		return 0;
}
//---------------------------------------------------------------------------
int mgcElementDBM::
Number (unsigned single_error)
{
	int result;
	for (result = -1; single_error; single_error >>= 1)
		result++;
	return result;
}
//---------------------------------------------------------------------------
void mgcElementDBM::
Report (unsigned single_error)
{
	if ( verbose )
		cout << "mgcElementDBM: " << message[Number(single_error)] << endl;
	else
		ofstream("element.err",ios::out|ios::app)
			<< "mgcElementDBM: " << message[Number(single_error)] << endl;

	error |= single_error;
}
//---------------------------------------------------------------------------
void mgcElementDBM::
Report (ostream& ostr)
{
	for (unsigned single_error = 1; single_error; single_error <<= 1)
		if ( error & single_error )
			ostr << "mgcElementDBM: " << message[Number(single_error)] << endl;

	error = 0;
}
//===========================================================================

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -