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

📄 vectorgeneric.h

📁 3D游戏开发需要用到BSP树来经行场景渲染的管理。本代码包含完整的BSP及文件生成实现
💻 H
字号:
// Do not include this file directly
#ifndef VECTOR_TRAMPOLINE
#error "vectorgeneric.h cannot be included directly"
#endif

#ifdef _DEBUG
#include <assert.h>
#endif

#include "gamesys.h"
#include "log.h"
#include <malloc.h>
#include <new>

#ifndef ALIGN
#define _aligned_free			free
#define _aligned_malloc(x,y)	malloc(x)
#define _aligned_realloc(x,y,z)	realloc(x,y)
#else
#define	CVector CAlignedVec
#endif

#define VECTOR_GRANULARITY	8 // elements
#define VECTOR_GRAN_BASE	(VECTOR_GRANULARITY-1)

// used for Save / Load
#include <stdio.h>

template <class T>
class CVector {
public:
			CVector();
			CVector(CVector& v);
			CVector(int n);
			~CVector();
	T&		operator[](int i);
	CVector&
			operator=(CVector& v);

	void	Resize(int new_size);
	void	Reserve(int new_size);
	void	Remove(int i);	// Swaps i with last. Possibly unsafe sometimes
	int		Append(CVector& vec);
	int		Append(T& element); // Only Append and TailAlloc increment num
	int		AppendNoBCheck(T& element);
	int		TailAlloc(int n);
	T&		TailAlloc();
	T*		Find(T* element);
	void	Clear();
	//void	ClearData();
	int		GetNum(); 
	void	SetNum(int n);
	T&		Tail();
	int		GetSize();
	void	Swap(CVector& l);
	T*		GetData(); // Fast access
	T&		GetElemNoBCheck(int i);
	bool	Save(FILE *fp);
	void	Load(FILE *fp, int num);
private:
	T		*data;
	int		num;  // No. elements appended
	int		size; // No. elements allocated
};

template <class T>
inline bool CVector<T>::Save(FILE *fp) {
	if(fwrite(data, sizeof(T), num, fp) != num) {
		return 1;
	}
	return 0;
};

template <class T>
inline void CVector<T>::Load(FILE *fp, int n) {
	Clear();
	Reserve(n);
	num = (int)fread(data, sizeof(T), n, fp);
};

template <class T>
CVector<T>::CVector(CVector<T>& v) {
	data = (T*)_aligned_malloc(v.num*sizeof(T), 16);
	if(data) {
		num = v.num;
		size = num;
		for(int i=0; i<num; i++) {
			new( data + i ) T(v[i]);
		}
	} else {
		num = 0;
		size = 0;
	}
}

template <class T>
inline CVector<T>::CVector(int n): data(0), num(0) {
	Reserve(n);
};

template <class T>
inline CVector<T>::CVector(): data(0), num(0), size(0) {};

template <class T>
inline CVector<T>::~CVector() {
	Clear();
}

template <class T>
inline void CVector<T>::Clear() {
	while(num)
		data[--num].~T();
	_aligned_free(data);

	data = 0;
	num = 0;
	size = 0;
}

template <class T>
inline int CVector<T>::GetSize() {
	return size;
}

template <class T>
inline int CVector<T>::GetNum() {
	return num;
}

template <class T>
inline void CVector<T>::SetNum(int n) {
	if(n > size)
		Resize(n);
	num = n;
}

template <class T>
inline T& CVector<T>::Tail() {
	return *(data + num - 1);
}

template <class T>
T& CVector<T>::operator[](int i) {
#if 0
	if(i >= size)
		Resize(i+1);
#endif
	return data[i];
}

template <class T>
T& CVector<T>::GetElemNoBCheck(int i){
		return data[i];
}

template <class T>
inline void	CVector<T>::Reserve(int new_size) {
	void *p = _aligned_malloc(new_size*sizeof(T), 16);

#ifdef _DEBUG
		assert(p);
#endif

	if(p) {
		size = new_size;
#ifdef NO_BUG_IN_PLACEMENT_NEW // data and p are sometimes different
		data = new(p) T[size];
#else
		for(int i=0; i<size; i++)
			new( (T*)p + i ) T;
		data = (T*)p;
#endif
	}
	else
		size = 0;
}

template <class T>
inline void CVector<T>::Resize(int new_size) {
#if 0
	new_size <<= 1;
#endif

	if(new_size & VECTOR_GRAN_BASE)
		new_size = ((new_size / VECTOR_GRANULARITY) + 1)*VECTOR_GRANULARITY ;

	T *p = (T*)_aligned_realloc(data, new_size*sizeof(T), 16);
#ifdef _DEBUG
		assert(p);
#endif
	//if(p) {
#if 0
		new(p+size) T[new_size - size]; // Might also be affected by the pl. new bug
#else
		for (int i=size; i<new_size; i++)
			new( (T*)p + i ) T;	// Call constructors
		data = p;
		size = new_size;
#endif
	//}
}

template <class T>
inline void CVector<T>::Swap(CVector& l) {
	T* my_data = data;
	int my_num = num;
	int my_size = size;
	data = l.data;
	num = l.num;
	size = l.size;
	l.data = my_data;
	l.num = my_num;
	l.size = my_size;
}

template <class T>
inline CVector<T>& CVector<T>::operator=(CVector<T>& v) {
	while(num)
		data[--num].~T();

	_aligned_free(data);

	data = (T*)_aligned_malloc(v.num*sizeof(T), 16);

//	data = (T*)_aligned_realloc(data, v.num*sizeof(T), 16);

	if(data) {
		num = v.num;
		size = num;
		for(int i=0; i<num; i++) {
			new( data + i ) T(v[i]);
			//data[i] = v[i];
		}
	}

	return *this;
}

template <class T>
inline T*  CVector<T>::GetData() {
	return data;
}

template <class T>
inline int CVector<T>::Append(T& element) {
	int r = num;
	if(num >= size)
		Resize(num + 1);
	data[num] = element;
	num++;
	return r;
}

template <class T>
inline int  CVector<T>::Append(CVector<T> &vec) {
	int r = num + 1;
	int new_num = num + vec.num;
	
	if(new_num > size)
		Resize(new_num);

	for(int i=0; i<vec.num; i++) {
		data[num++] = vec.data[i];
	}

	return r;
}

template <class T>
inline int CVector<T>::AppendNoBCheck(T& element) {
	int r = num;
	data[num] = element;
	num++;
	return r;
}

template <class T>
inline int CVector<T>::TailAlloc(int n) {
	int r = num;
	num += n;
	if(num > size)
		Resize(num);
	return r;
}

template <class T>
inline T& CVector<T>::TailAlloc() {
	int r = num;
	num ++;
	if(num > size)
		Resize(num);
	return data[r];
}

template <class T>
inline T* CVector<T>::Find(T* element) {
	for(int i=0; i<num; i++)
		if(data[i] == element)
			return data + i;
}

template <class T>
void CVector<T>::Remove(int i) {
	num--;
	data[i] = data[num];
}

#ifndef ALIGN

#undef _aligned_free
#undef _aligned_malloc
#undef _aligned_realloc

#else

#undef	CVector

#endif

⌨️ 快捷键说明

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