告知下,本代码的只提供学习,不能用于商业活动
我这边先介绍下,本代码是上线的老端游
下面是重新封装了一个所谓的list,主要还是在性能上考虑
//vector based list ( to keep a persistent id for each element and to avoid frequently new/delete operations while reordering )
template <typename TYPE>
struct vlist
{
private:
struct entry_t
{
byte4 pre, next;
TYPE data;
};
vector<entry_t> entry_vec; //the first entry is reserved to connect the first and last element of the list together
vector<byte4> free_index_vec;
public:
vlist() {clear();}
byte4 begin() {return entry_vec[0].next;}
byte4 end() {return 0;}
byte4 rbegin() {return entry_vec[0].pre;}
byte4 rend() {return 0;}
byte4 pre(byte4 where) {return entry_vec[where].pre;}
byte4 next(byte4 where) {return entry_vec[where].next;}
TYPE& value(byte4 where) {return entry_vec[where].data;}
TYPE& front() {return entry_vec[begin()].data;}
TYPE& back() {return entry_vec[rbegin()].data;}
void push_front(const TYPE& val) {return insert(begin(), val);}
void push_back(const TYPE& val) {return insert(end(), val);}
void pop_front() {return erase(begin());}
void pop_back() {return erase(rbegin());}
bool empty() {return (begin() == end());}
size_t size() {return (entry_vec.size() - 1 - free_index_vec.size());}
void insert(byte4 where, const TYPE& val);
void erase(byte4 where);
void move(byte4 from, byte4 to);
void clear();
};
template <typename TYPE>
void vlist<TYPE>::insert(byte4 where, const TYPE& val)
{
//find an empty entry
byte4 entry;
if( !free_index_vec.empty() )
{
entry = free_index_vec.back();
free_index_vec.pop_back();
}
else
{
entry = (byte4)entry_vec.size();
entry_vec.resize(entry + 1);
}
//insert
entry_vec[entry].data = val;
entry_vec[entry].pre = entry_vec[where].pre;
entry_vec[entry].next = where;
entry_vec[entry_vec[where].pre].next = entry;
entry_vec[where].pre = entry;
}
template <typename TYPE>
void vlist<TYPE>::erase(byte4 where)
{
free_index_vec.push_back(where);
entry_vec[entry_vec[where].pre].next = entry_vec[where].next;
entry_vec[entry_vec[where].next].pre = entry_vec[where].pre;
}
template <typename TYPE>
void vlist<TYPE>::move(byte4 from, byte4 to)
{
if( from != to )
{
//erase
entry_vec[entry_vec[from].pre].next = entry_vec[from].next;
entry_vec[entry_vec[from].next].pre = entry_vec[from].pre;
//insert
entry_vec[from].pre = entry_vec[to].pre;
entry_vec[from].next = to;
entry_vec[entry_vec[to].pre].next = from;
entry_vec[to].pre = from;
}
}
template <typename TYPE>
void vlist<TYPE>::clear()
{
entry_vec.clear();
entry_vec.resize(1);
entry_vec[0].pre = entry_vec[0].next = 0;
free_index_vec.clear();
}
下面是个当时器
//timer
//interface
void start_timer();
void update_time();
float now_time(); //in millisecond
//implementation
LONGLONG _ticks_per_second;
LONGLONG _base_counter;
float _t_;
void limit_current_thread_to_one_processor()
{
HANDLE hCurrentProcess = GetCurrentProcess();
// Get the processor affinity mask for this process
DWORD_PTR dwProcessAffinityMask = 0;
DWORD_PTR dwSystemAffinityMask = 0;
if( GetProcessAffinityMask( hCurrentProcess, &dwProcessAffinityMask, &dwSystemAffinityMask ) != 0 && dwProcessAffinityMask )
{
// Find the lowest processor that our process is allows to run against
DWORD_PTR dwAffinityMask = ( dwProcessAffinityMask & ((~dwProcessAffinityMask) + 1 ) );
// Set this as the processor that our thread must always run against
// This must be a subset of the process affinity mask
HANDLE hCurrentThread = GetCurrentThread();
if( INVALID_HANDLE_VALUE != hCurrentThread )
{
SetThreadAffinityMask( hCurrentThread, dwAffinityMask );
CloseHandle( hCurrentThread );
}
}
CloseHandle( hCurrentProcess );
}
//start timer
void start_timer()
{
// Limit the current thread to one processor (the current one). This ensures that timing code runs
// on only one processor, and will not suffer any ill effects from power management.
limit_current_thread_to_one_processor();
// start timer
LARGE_INTEGER frequency;
QueryPerformanceFrequency( &frequency );
_ticks_per_second = frequency.QuadPart;
LARGE_INTEGER counter;
QueryPerformanceCounter( &counter );
_base_counter = counter.QuadPart;
_t_ = 0;
}
//update time
void update_time()
{
LARGE_INTEGER counter;
QueryPerformanceCounter( &counter );
_t_ = (float)((double) ( counter.QuadPart - _base_counter ) / (double) _ticks_per_second * 1000);
}