DH 2012-11-15 01:39:56 +02:00
parent de070bf485
commit a90b5cf37a
1998 changed files with 1034301 additions and 0 deletions

267
Utilities/Array.h Normal file
View file

@ -0,0 +1,267 @@
#pragma once
template<typename T> class Array
{
u32 m_count;
T* m_array;
public:
Array()
: m_count(0)
, m_array(NULL)
{
}
~Array()
{
Clear();
}
inline bool RemoveAt(const u32 from, const u32 count = 1)
{
if(!GetCount()) return false;
const u32 to = from + count;
if(to > GetCount()) return false;
memmove(m_array + from, m_array + to, (m_count-to) * sizeof(T));
m_count -= count;
return true;
}
void InsertRoomEnd(const u32 size)
{
_InsertRoomEnd(size);
}
bool InsertRoom(const u32 pos, const u32 size)
{
if(pos >= m_count) return false;
_InsertRoomEnd(size);
memmove(m_array + pos + size, m_array + pos, sizeof(T) * (m_count - size - pos));
return true;
}
bool Insert(const u32 pos, T* data)
{
if(!InsertRoom(pos, 1)) return false;
memmove(m_array + pos, data, sizeof(T));
return true;
}
bool Insert(const u32 pos, T& data)
{
return Insert(pos, &data);
}
bool InsertCpy(const u32 pos, const T* data)
{
if(!InsertRoom(pos, 1)) return false;
memcpy(m_array + pos, data, sizeof(T));
return true;
}
bool InsertCpy(const u32 pos, const T& data)
{
return InsertCpy(pos, &data);
}
inline u32 Add(T* data)
{
_InsertRoomEnd(1);
memmove(m_array + GetCount() - 1, data, sizeof(T));
return m_count - 1;
}
inline u32 Add(T& data)
{
return Add(&data);
}
inline u32 AddCpy(const T* data)
{
_InsertRoomEnd(1);
memcpy(m_array + GetCount() - 1, data, sizeof(T));
return m_count - 1;
}
inline u32 AddCpy(const T& data)
{
return AddCpy(&data);
}
inline void Clear()
{
m_count = 0;
safe_delete(m_array);
}
inline T& Get(u32 num)
{
//if(num >= GetCount()) return *new T();
return m_array[num];
}
u32 GetCount() const { return m_count; }
void SetCount(const u32 count, bool memzero = true)
{
if(GetCount() >= count) return;
_InsertRoomEnd(count - GetCount());
if(memzero) memset(m_array + GetCount(), 0, count - GetCount());
}
void Reserve(const u32 count)
{
SetCount(GetCount() + count);
}
void AppendFrom(const Array<T>& src)
{
if(!src.GetCount()) return;
Reserve(src.GetCount());
memcpy(m_array, &src[0], GetCount() * sizeof(T));
}
void CopyFrom(const Array<T>& src)
{
Clear();
AppendFrom(src);
}
T& operator[](u32 num) const { return m_array[num]; }
protected:
void _InsertRoomEnd(const u32 size)
{
if(!size) return;
m_array = m_count ? (T*)realloc(m_array, sizeof(T) * (m_count + size)) : (T*)malloc(sizeof(T) * size);
m_count += size;
}
};
template<typename T> struct Stack : public Array<T>
{
Stack() : Array<T>()
{
}
~Stack()
{
Clear();
}
void Push(const T data) { AddCpy(data); }
T Pop()
{
const u32 pos = GetCount() - 1;
const T ret = Get(pos);
RemoveAt(pos);
return ret;
}
};
template<typename T> class ArrayF
{
u32 m_count;
T** m_array;
public:
ArrayF()
: m_count(0)
, m_array(NULL)
{
}
~ArrayF()
{
Clear();
}
inline bool RemoveFAt(const u32 from, const u32 count = 1)
{
if(from + count > m_count) return false;
memmove(&m_array[from], &m_array[from+count], (m_count-(from+count)) * sizeof(T**));
m_count -= count;
return true;
}
inline bool RemoveAt(const u32 from, const u32 count = 1)
{
if(from + count > m_count) return false;
for(uint i = from; i < from + count; ++i)
{
free(m_array[i]);
}
return RemoveFAt(from, count);
}
inline u32 Add(T& data)
{
return Add(&data);
}
inline u32 Add(T* data)
{
if(!m_array)
{
m_array = (T**)malloc(sizeof(T*));
}
else
{
m_array = (T**)realloc(m_array, sizeof(T*) * (m_count + 1));
}
m_array[m_count] = data;
return m_count++;
}
inline void ClearF()
{
if(m_count == 0) return;
m_count = 0;
m_array = NULL;
}
inline void Clear()
{
if(m_count == 0) return;
m_count = 0;
safe_delete(m_array);
}
inline T& Get(const u64 num)
{
//if(m_count <= num) *m_array[0]; //TODO
return *m_array[num];
}
inline u32 GetCount() const { return m_count; }
T& operator[](u32 num) const { return *m_array[num]; }
};

136
Utilities/IdManager.h Normal file
View file

@ -0,0 +1,136 @@
#pragma once
#include "Array.h"
typedef u32 ID_TYPE;
struct ID
{
bool m_used;
wxString m_name;
u8 m_attr;
void* m_data;
ID(bool used = false, const wxString& name = wxEmptyString, void* data = NULL, const u8 attr = 0)
: m_used(used)
, m_name(name)
, m_data(data)
, m_attr(attr)
{
}
};
class IdManager
{
ArrayF<ID> IDs;
static const u64 first_id = 1;
void Cleanup()
{
while(IDs.GetCount())
{
const u32 num = IDs.GetCount()-1;
ID& id = IDs[num];
if(id.m_used) break;
IDs.RemoveAt(num);
}
}
public:
IdManager()
{
}
~IdManager()
{
Clear();
}
static ID_TYPE GetMaxID()
{
return (ID_TYPE)-1;
}
bool CheckID(const u64 id)
{
if(id == 0 || id > (u64)NumToID(IDs.GetCount()-1) || id >= GetMaxID()) return false;
return IDs[IDToNum(id)].m_used;
}
__forceinline const ID_TYPE NumToID(const ID_TYPE num) const
{
return num + first_id;
}
__forceinline const ID_TYPE IDToNum(const ID_TYPE id) const
{
return id - first_id;
}
void Clear()
{
IDs.Clear();
}
virtual ID_TYPE GetNewID(const wxString& name = wxEmptyString, void* data = NULL, const u8 attr = 0)
{
for(uint i=0; i<IDs.GetCount(); ++i)
{
if(IDs[i].m_used) continue;
return NumToID(i);
}
const ID_TYPE pos = IDs.GetCount();
if(NumToID(pos) >= GetMaxID()) return 0;
IDs.Add(new ID(true, name, data, attr));
return NumToID(pos);
}
ID& GetIDData(const ID_TYPE _id)
{
//if(!CheckID(_id)) return IDs.Get(0); //TODO
return IDs[IDToNum(_id)];
}
bool GetFirst(ID& dst, ID_TYPE* _id = NULL)
{
u32 pos = 0;
return GetNext(pos, dst, _id);
}
bool HasID(const s64 id)
{
if(id == wxID_ANY) return IDs.GetCount() != 0;
return CheckID(id);
}
bool GetNext(u32& pos, ID& dst, ID_TYPE* _id = NULL)
{
while(pos < IDs.GetCount())
{
ID& id = IDs[pos++];
if(!id.m_used) continue;
dst = id;
if(_id) *_id = NumToID(pos - 1);
return true;
}
return false;
}
virtual bool RemoveID(const ID_TYPE _id, bool free_data = true)
{
if(!CheckID(_id)) return false;
ID& id = IDs[IDToNum(_id)];
if(!id.m_used) return false;
id.m_used = false;
id.m_attr = 0;
id.m_name.Clear();
if(free_data) free(id.m_data);
id.m_data = NULL;
if(IDToNum(_id) == IDs.GetCount()-1) Cleanup();
return true;
}
};

View file

@ -0,0 +1,98 @@
#pragma once
class MTProgressDialog : public wxDialog
{
wxGauge** m_gauge;
wxStaticText** m_msg;
wxArrayLong m_maximum;
const u8 m_cores;
static const uint layout = 16;
static const uint maxdial = 65536;
wxArrayInt m_lastupdate;
public:
MTProgressDialog(wxWindow* parent, const wxSize& size, const wxString& title,
const wxString& msg, const wxArrayLong& maximum, const u8 cores)
: wxDialog(parent, wxID_ANY, title, wxDefaultPosition)
, m_maximum(maximum)
, m_cores(cores)
{
wxBoxSizer* sizer = new wxBoxSizer(wxVERTICAL);
m_gauge = new wxGauge*[m_cores];
m_msg = new wxStaticText*[m_cores];
m_lastupdate.SetCount(cores);
for(uint i=0; i<m_cores; ++i)
{
m_lastupdate[i] = -1;
m_msg[i] = new wxStaticText(this, wxID_ANY, msg);
sizer->Add(m_msg[i], 0, wxLEFT | wxTOP, layout);
m_gauge[i] = new wxGauge(this, wxID_ANY, maxdial,
wxDefaultPosition, wxDefaultSize,
wxGA_HORIZONTAL );
sizer->Add(m_gauge[i], 0, wxLEFT | wxRIGHT | wxTOP | wxEXPAND, layout);
m_gauge[i]->SetValue(0);
sizer->AddSpacer(5);
}
SetSizerAndFit(sizer);
if(size != wxDefaultSize)
{
SetSize(size);
}
else
{
wxSize ws;
ws.x = 400;
ws.y = GetSize().y + 8;
SetSize(ws);
}
m_maximum.SetCount(m_cores);
Show();
}
__forceinline void Update(const u8 thread_id, const u64 value, const wxString& msg)
{
if(thread_id > m_cores) return;
const int curupdate = (int)(((double)value/(double)m_maximum[thread_id])*1000);
if(curupdate == m_lastupdate[thread_id]) return;
m_lastupdate[thread_id] = curupdate;
m_msg[thread_id]->SetLabel(msg);
if(value >= (u32)m_maximum[thread_id]) return;
m_gauge[thread_id]->SetValue(((double)value / (double)m_maximum[thread_id]) * maxdial);
}
const u32 GetMaxValue(const uint thread_id) const
{
if(thread_id > m_cores) return 0;
return m_maximum[thread_id];
}
void SetMaxFor(const uint thread_id, const u64 val)
{
if(thread_id > m_cores) return;
m_maximum[thread_id] = val;
m_lastupdate[thread_id] = 0;
}
virtual void Close(bool force = false)
{
m_lastupdate.Empty();
m_maximum.Empty();
wxDialog::Close(force);
}
};

29
Utilities/Thread.cpp Normal file
View file

@ -0,0 +1,29 @@
#include "stdafx.h"
#include "Thread.h"
void ThreadBase::Start()
{
if(m_executor) return;
m_executor = new ThreadExec(m_detached, this);
}
void ThreadBase::Stop(bool wait)
{
if(!m_executor) return;
ThreadExec* exec = m_executor;
m_executor = nullptr;
exec->Stop(wait);
}
bool ThreadBase::IsAlive()
{
return m_executor != nullptr;
}
bool ThreadBase::TestDestroy()
{
if(!m_executor) return true;
return m_executor->TestDestroy();
}

177
Utilities/Thread.h Normal file
View file

@ -0,0 +1,177 @@
#pragma once
#include "Array.h"
class ThreadExec;
class ThreadBase
{
protected:
wxString m_name;
bool m_detached;
protected:
ThreadBase(bool detached = true, const wxString& name = "Unknown ThreadBase")
: m_detached(detached)
, m_name(name)
, m_executor(nullptr)
{
}
public:
ThreadExec* m_executor;
virtual void Task()=0;
void Start();
void Stop(bool wait = true);
bool IsAlive();
bool TestDestroy();
};
class ThreadExec : public wxThread
{
ThreadBase* m_parent;
wxSemaphore m_wait_for_exit;
volatile bool m_alive;
public:
ThreadExec(bool detached, ThreadBase* parent)
: wxThread(detached ? wxTHREAD_DETACHED : wxTHREAD_JOINABLE)
, m_parent(parent)
, m_alive(true)
{
Create();
Run();
}
void Stop(bool wait = true)
{
if(!m_alive) return;
m_parent = nullptr;
Delete();
if(wait && m_alive) m_wait_for_exit.Wait();
}
ExitCode Entry()
{
m_parent->Task();
m_alive = false;
m_wait_for_exit.Post();
if(m_parent) m_parent->m_executor = nullptr;
return (ExitCode)0;
}
};
template<typename T> class MTPacketBuffer
{
protected:
volatile bool m_busy;
volatile u32 m_put, m_get;
Array<u8> m_buffer;
u32 m_max_buffer_size;
void CheckBusy()
{
m_busy = m_put >= m_max_buffer_size;
}
public:
MTPacketBuffer(u32 max_buffer_size)
: m_max_buffer_size(max_buffer_size)
{
Flush();
}
~MTPacketBuffer()
{
Flush();
}
void Flush()
{
m_put = m_get = 0;
m_buffer.Clear();
m_busy = false;
}
virtual void Push(const T& v) = 0;
virtual T Pop() = 0;
bool HasNewPacket() const { return m_put != m_get; }
bool IsBusy() const { return m_busy; }
};
/*
class StepThread : public ThreadBase
{
wxSemaphore m_main_sem;
wxSemaphore m_destroy_sem;
volatile bool m_exit;
protected:
StepThread(const wxString& name = "Unknown StepThread")
: ThreadBase(true, name)
, m_exit(false)
{
}
virtual ~StepThread() throw()
{
}
private:
virtual void Task()
{
m_exit = false;
while(!TestDestroy())
{
m_main_sem.Wait();
if(TestDestroy() || m_exit) break;
Step();
}
while(!TestDestroy()) Sleep(0);
if(m_destroy_sem.TryWait() != wxSEMA_NO_ERROR) m_destroy_sem.Post();
}
virtual void Step()=0;
public:
void DoStep()
{
if(IsRunning()) m_main_sem.Post();
}
void WaitForExit()
{
if(TestDestroy()) m_destroy_sem.Wait();
}
void WaitForNextStep()
{
if(!IsRunning()) return;
while(m_main_sem.TryWait() != wxSEMA_NO_ERROR) Sleep(0);
}
void Exit(bool wait = false)
{
if(!IsAlive()) return;
if(m_main_sem.TryWait() != wxSEMA_NO_ERROR)
{
m_exit = true;
m_main_sem.Post();
}
Delete();
if(wait) WaitForExit();
}
};
*/

47
Utilities/Timer.h Normal file
View file

@ -0,0 +1,47 @@
#pragma once
class Timer
{
private:
bool stopped;
double startTimeInMicroSec;
double endTimeInMicroSec;
LARGE_INTEGER frequency;
LARGE_INTEGER startCycle;
LARGE_INTEGER endCycle;
public:
Timer()
{
QueryPerformanceFrequency(&frequency);
startCycle.QuadPart = 0;
endCycle.QuadPart = 0;
stopped = false;
startTimeInMicroSec = 0;
endTimeInMicroSec = 0;
}
void Start()
{
stopped = false;
QueryPerformanceCounter(&startCycle);
}
void Stop()
{
stopped = true;
QueryPerformanceCounter(&endCycle);
}
double GetElapsedTimeInSec(){return GetElapsedTimeInMicroSec() / 1000000.0;}
double GetElapsedTimeInMilliSec(){return GetElapsedTimeInMicroSec() / 1000.0;}
double GetElapsedTimeInMicroSec()
{
if(!stopped) QueryPerformanceCounter(&endCycle);
startTimeInMicroSec = startCycle.QuadPart * (1000000.0 / frequency.QuadPart);
endTimeInMicroSec = endCycle.QuadPart * (1000000.0 / frequency.QuadPart);
return endTimeInMicroSec - startTimeInMicroSec;
}
};