first commit

This commit is contained in:
2026-06-22 11:49:35 +02:00
commit d805f2ba86
619 changed files with 126873 additions and 0 deletions

View File

@ -0,0 +1,218 @@
/* -----------------------------------------------------------------------------
GSFramework
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
----------------------------------------------------------------------------- */
#ifndef __NALLOCATOR_INTERFACE__
#define __NALLOCATOR_INTERFACE__
#include "ntypes.h"
#include <new>
namespace GS {
namespace Alloc {
// Allocator systems.
enum System
{
General,
ListItem,
StringBuffer,
Filesystem,
Metatag,
Curve,
Motion,
AnimationSource,
Vector,
Matrix,
Physics,
Item3d,
Geometry,
Material,
Texture,
Picture,
Mixer,
Sound,
Renderer,
RendererJob,
RendererTerrain,
VertexBuffer,
Global,
SystemCount
};
struct SystemDesc
{
const char *group;
const char *name;
};
/*
Allocators can be changed per system by editing the following defines.
*/
#define MemAllocListItem GS::Alloc::DefaultAllocator
#define MemAllocStringBuffer GS::Alloc::DefaultAllocator
#define MemAllocFilesystem GS::Alloc::DefaultAllocator
#define MemAllocMetatag GS::Alloc::DefaultAllocator
#define MemAllocCurve GS::Alloc::DefaultAllocator
#define MemAllocMotion GS::Alloc::DefaultAllocator
#define MemAllocAnimationSource GS::Alloc::DefaultAllocator
#define MemAllocVector GS::Alloc::DefaultAllocator
#define MemAllocMatrix GS::Alloc::DefaultAllocator
#define MemAllocPhysics GS::Alloc::DefaultAllocator
#define MemAllocItem3d GS::Alloc::DefaultAllocator
#define MemAllocGeometry GS::Alloc::DefaultAllocator
#define MemAllocMaterial GS::Alloc::DefaultAllocator
#define MemAllocTexture GS::Alloc::DefaultAllocator
#define MemAllocPicture GS::Alloc::DefaultAllocator
#define MemAllocMixer GS::Alloc::DefaultAllocator
#define MemAllocSound GS::Alloc::DefaultAllocator
#define MemAllocRenderer GS::Alloc::DefaultAllocator
#define MemAllocRendererJob GS::Alloc::DefaultAllocator
#define MemAllocRendererTerrain GS::Alloc::DefaultAllocator
#define MemAllocVertexBuffer GS::Alloc::DefaultAllocator
#if __ENABLE_ALLOCATION_STAT__
struct Header
{
size_t size;
};
struct Stat
{
uint alloc_count, alloc_avg;
uint alive_count, alive_count_peak;
size_t size, size_peak;
Stat() : alloc_count(0), alloc_avg(0), alive_count(0), alive_count_peak(0), size(0), size_peak(0) {}
};
/// Per system statistics.
extern Stat system_stat[SystemCount];
extern SystemDesc system_desc[SystemCount];
size_t GetAdjustedAllocationSize(size_t);
void *SetupAllocationStat(void *, size_t);
void *GetAllocationStat(void *, Header *&);
void UpdateStatAlloc(size_t, System);
void UpdateStatDelete(size_t, System);
#endif
/// Standard C++ allocator.
struct DefaultAllocator
{
static void *Alloc(size_t size, System sys = General);
static void Delete(void *addr, System sys = General);
};
} // Alloc
} // GS
//------------------------------------------------------------------------------
#if __ENABLE_ALLOCATION_STAT__
#define __NSTAT_WRAPALLOC(__WRAPPED_CALL, __SYSTEM)\
GS::Alloc::UpdateStatAlloc(size, __SYSTEM);\
size_t __raw_size = size;\
size = GS::Alloc::GetAdjustedAllocationSize(size);\
return GS::Alloc::SetupAllocationStat(__WRAPPED_CALL, __raw_size);
#define __NSTAT_WRAPDELETE(__WRAPPED_CALL, __SYSTEM)\
if (addr)\
{\
GS::Alloc::Header *h;\
addr = GS::Alloc::GetAllocationStat(addr, h);\
GS::Alloc::UpdateStatDelete(h->size, __SYSTEM);\
__WRAPPED_CALL;\
}
#define __NSTAT_ALLOC(__SIZE, __SYSTEM) GS::Alloc::UpdateStatAlloc(__SIZE, __SYSTEM)
#define __NSTAT_DELETE(__SIZE, __SYSTEM) GS::Alloc::UpdateStatDelete(__SIZE, __SYSTEM)
#else
#define __NSTAT_WRAPALLOC(__WRAPPED_CALL, __SYSTEM) return __WRAPPED_CALL;
#define __NSTAT_WRAPDELETE(__WRAPPED_CALL, __SYSTEM) __WRAPPED_CALL;
#define __NSTAT_ALLOC(__SIZE, __SYSTEM)
#define __NSTAT_DELETE(__SIZE, __SYSTEM)
#endif
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
#if __PLATFORM_EMSCRIPTEN__
#define NPLACEMENT_NEW(__SYSTEM)
#else
#define NPLACEMENT_NEW(__SYSTEM)\
void *operator new (size_t size)\
{ return MemAlloc##__SYSTEM::Alloc(size, GS::Alloc::__SYSTEM); }\
void operator delete(void *addr)\
{ MemAlloc##__SYSTEM::Delete(addr, GS::Alloc::__SYSTEM); }\
void *operator new [] (size_t size)\
{ return MemAlloc##__SYSTEM::Alloc(size, GS::Alloc::__SYSTEM); }\
void operator delete [] (void *addr)\
{ MemAlloc##__SYSTEM::Delete(addr, GS::Alloc::__SYSTEM); }
#endif
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void *_align_alloc(size_t, size_t);
void _align_free(void *);
template <class T> T *_align_new(size_t align)
{ return ::new (_align_alloc(sizeof(T), align)) T(); }
template <class T, typename P0> T *_align_new(P0 &p0, size_t align)
{ return ::new (_align_alloc(sizeof(T), align)) T(p0); }
template <class T> void _align_delete(T *p)
{
p->~T();
_align_free(p);
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
template <class T> void _safe_delete(T *&p)
{
delete p;
p = 0;
}
template <class T> void _safe_delete_array(T *&p)
{
delete [] p;
p = 0;
}
//------------------------------------------------------------------------------
#endif // __NALLOCATOR_INTERFACE__

View File

@ -0,0 +1,30 @@
/* -----------------------------------------------------------------------------
GSFramework
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
----------------------------------------------------------------------------- */
#ifndef __ANALYTICS__
#define __ANALYTICS__
namespace GS {
/*!
@short Analytics system interface.
@author Emmanuel Julien (ejulien@owloh.com)
*/
struct IAnalytics
{
/// Log an analytics event.
virtual void logEvent(const char *) = 0;
/// Serve a fullscreen advertisement.
virtual void serveFullscreenAd(const char *) = 0;
virtual ~IAnalytics() {}
};
} // GS
#endif // __ANALYTICS__

View File

@ -0,0 +1,35 @@
/* -----------------------------------------------------------------------------
GSFramework
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
----------------------------------------------------------------------------- */
#ifndef __NASSERT__
#define __NASSERT__
namespace GS {
namespace Assert {
/// Trigger a system assertion.
extern void Trigger(const char *source, int line, const char *condition, const char *message = 0);
} // Assert
} // GS
// Portable assert.
#ifdef _DEBUG
#define __ASSERT__(_EXP_) if (!(_EXP_)) GS::Assert::Trigger(__FILE__, __LINE__, #_EXP_)
#define __ASSERT_MSG__(_EXP_, _MSG_) if (!(_EXP_)) GS::Assert::Trigger(__FILE__, __LINE__, #_EXP_, _MSG_)
#define __ASSERT_ALWAYS__ GS::Assert::Trigger(__FILE__, __LINE__, "Unconditional")
#else
#define __ASSERT__(_EXP_)
#define __ASSERT_MSG__(_EXP_, _MSG_)
#define __ASSERT_ALWAYS__
#endif
#define __RASSERT__(_EXP_) if (!(_EXP_)) GS::Assert::Trigger(__FILE__, __LINE__, #_EXP_)
#define __RASSERT_MSG__(_EXP_, _MSG_) if (!(_EXP_)) GS::Assert::Trigger(__FILE__, __LINE__, #_EXP_, _MSG_)
#endif // __NASSERT__

View File

@ -0,0 +1,201 @@
/* -----------------------------------------------------------------------------
GSFramework
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
----------------------------------------------------------------------------- */
#ifndef __ASYNC_CALL_QUEUE__
#define __ASYNC_CALL_QUEUE__
#include "async/future.h"
#include "thread/thread.h"
#include "thread/mutex.h"
#include "container/nlist.h"
namespace GS {
namespace ASync {
/*!
@short Asynchronous call queue.
@author Emmanuel Julien (ejulien@owloh.com)
*/
class CallQueue
{
struct BaseCall
{
virtual void Execute() = 0;
virtual ~BaseCall() {}
};
Threading::Mutex queue_mutex;
List <BaseCall *> call_queue;
/// Post a call to the queue.
void Queue(BaseCall *m)
{
Threading::MutexLock lock(&queue_mutex);
call_queue.Append(m);
}
private:
// Call a member function, ignore the return value.
template <typename I, typename F> struct MemberCall : public BaseCall
{
I i; F fn;
void Execute() { (i->*fn)(); }
MemberCall(I _i, F _fn) : i(_i), fn(_fn) {}
};
template <typename I, typename F, typename A1> struct MemberCall1 : public BaseCall
{
I i; F fn; A1 a1;
void Execute() { (i->*fn)(a1); }
MemberCall1(I _i, F _fn, const A1 &_a1) : i(_i), fn(_fn), a1(_a1) {}
};
template <typename I, typename F, typename A1, typename A2> struct MemberCall2 : public BaseCall
{
I i; F fn; A1 a1; A2 a2;
void Execute() { (i->*fn)(a1, a2); }
MemberCall2(I _i, F _fn, const A1 &_a1, const A2 &_a2) : i(_i), fn(_fn), a1(_a1), a2(_a2) {}
};
template <typename I, typename F, typename A1, typename A2, typename A3> struct MemberCall3 : public BaseCall
{
I i; F fn; A1 a1; A2 a2; A3 a3;
void Execute() { (i->*fn)(a1, a2, a3); }
MemberCall3(I _i, F _fn, const A1 &_a1, const A2 &_a2, const A3 &_a3) : i(_i), fn(_fn), a1(_a1), a2(_a2), a3(_a3) {}
};
template <typename I, typename F, typename A1, typename A2, typename A3, typename A4> struct MemberCall4 : public BaseCall
{
I i; F fn; A1 a1; A2 a2; A3 a3; A4 a4;
void Execute() { (i->*fn)(a1, a2, a3, a4); }
MemberCall4(I _i, F _fn, const A1 &_a1, const A2 &_a2, const A3 &_a3, const A4 &_a4) : i(_i), fn(_fn), a1(_a1), a2(_a2), a3(_a3), a4(_a4) {}
};
public:
template <typename I, typename F> void QueueMemberCall(I i, F fn)
{ Queue(new MemberCall <I, F> (i, fn)); }
template <typename I, typename F, typename A1> void QueueMemberCall(I i, F fn, const A1 &a1)
{ Queue(new MemberCall1 <I, F, A1> (i, fn, a1)); }
template <typename I, typename F, typename A1, typename A2> void QueueMemberCall(I i, F fn, const A1 &a1, const A2 &a2)
{ Queue(new MemberCall2 <I, F, A1, A2> (i, fn, a1, a2)); }
template <typename I, typename F, typename A1, typename A2, typename A3> void QueueMemberCall(I i, F fn, const A1 &a1, const A2 &a2, const A3 &a3)
{ Queue(new MemberCall3 <I, F, A1, A2, A3> (i, fn, a1, a2, a3)); }
template <typename I, typename F, typename A1, typename A2, typename A3, typename A4> void QueueMemberCall(I i, F fn, const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4)
{ Queue(new MemberCall4 <I, F, A1, A2, A3, A4> (i, fn, a1, a2, a3, a4)); }
private:
// Generic return value calls.
template <typename R, typename I, typename F> struct RValMemberCall : public BaseCall
{
Future <R> &future; I i; F fn;
void Execute() { future.Set((i->*fn)()); }
RValMemberCall(Future <R> &_future, I _i, F _fn) : future(_future), i(_i), fn(_fn) {}
};
template <typename R, typename I, typename F, typename A1> struct RValMemberCall1 : public BaseCall
{
Future <R> &future; I i; F fn; A1 a1;
void Execute() { future.Set((i->*fn)(a1)); }
RValMemberCall1(Future <R> &_future, I _i, F _fn, const A1 &_a1) : future(_future), i(_i), fn(_fn), a1(_a1) {}
};
template <typename R, typename I, typename F, typename A1, typename A2> struct RValMemberCall2 : public BaseCall
{
Future <R> &future; I i; F fn; A1 a1; A2 a2;
void Execute() { future.Set((i->*fn)(a1, a2)); }
RValMemberCall2(Future <R> &_future, I _i, F _fn, const A1 &_a1, const A2 &_a2) : future(_future), i(_i), fn(_fn), a1(_a1), a2(_a2) {}
};
template <typename R, typename I, typename F, typename A1, typename A2, typename A3> struct RValMemberCall3 : public BaseCall
{
Future <R> &future; I i; F fn; A1 a1; A2 a2; A3 a3;
void Execute() { future.Set((i->*fn)(a1, a2, a3)); }
RValMemberCall3(Future <R> &_future, I _i, F _fn, const A1 &_a1, const A2 &_a2, const A3 &_a3) : future(_future), i(_i), fn(_fn), a1(_a1), a2(_a2), a3(_a3) {}
};
template <typename R, typename I, typename F, typename A1, typename A2, typename A3, typename A4> struct RValMemberCall4 : public BaseCall
{
Future <R> &future; I i; F fn; A1 a1; A2 a2; A3 a3; A4 a4;
void Execute() { future.Set((i->*fn)(a1, a2, a3, a4)); }
RValMemberCall4(Future <R> &_future, I _i, F _fn, const A1 &_a1, const A2 &_a2, const A3 &_a3, const A4 &_a4) : future(_future), i(_i), fn(_fn), a1(_a1), a2(_a2), a3(_a3), a4(_a4) {}
};
// No return value specialized calls.
template <typename I, typename F> struct RValMemberCall <void, I, F> : public BaseCall
{
Future <void> &future; I i; F fn;
void Execute() { (i->*fn)(); future.Set(); }
RValMemberCall(Future <void> &_future, I _i, F _fn) : future(_future), i(_i), fn(_fn) {}
};
template <typename I, typename F, typename A1> struct RValMemberCall1 <void, I, F, A1> : public BaseCall
{
Future <void> &future; I i; F fn; A1 a1;
void Execute() { (i->*fn)(a1); future.Set(); }
RValMemberCall1(Future <void> &_future, I _i, F _fn, const A1 &_a1) : future(_future), i(_i), fn(_fn), a1(_a1) {}
};
template <typename I, typename F, typename A1, typename A2> struct RValMemberCall2 <void, I, F, A1, A2> : public BaseCall
{
Future <void> &future; I i; F fn; A1 a1; A2 a2;
void Execute() { (i->*fn)(a1, a2); future.Set(); }
RValMemberCall2(Future <void> &_future, I _i, F _fn, const A1 &_a1, const A2 &_a2) : future(_future), i(_i), fn(_fn), a1(_a1), a2(_a2) {}
};
template <typename I, typename F, typename A1, typename A2, typename A3> struct RValMemberCall3 <void, I, F, A1, A2, A3> : public BaseCall
{
Future <void> &future; I i; F fn; A1 a1; A2 a2; A3 a3;
void Execute() { (i->*fn)(a1, a2, a3); future.Set(); }
RValMemberCall3(Future <void> &_future, I _i, F _fn, const A1 &_a1, const A2 &_a2, const A3 &_a3) : future(_future), i(_i), fn(_fn), a1(_a1), a2(_a2), a3(_a3) {}
};
template <typename I, typename F, typename A1, typename A2, typename A3, typename A4> struct RValMemberCall4 <void, I, F, A1, A2, A3, A4> : public BaseCall
{
Future <void> &future; I i; F fn; A1 a1; A2 a2; A3 a3; A4 a4;
void Execute() { (i->*fn)(a1, a2, a3, a4); future.Set(); }
RValMemberCall4(Future <void> &_future, I _i, F _fn, const A1 &_a1, const A2 &_a2, const A3 &_a3, const A4 &_a4) : future(_future), i(_i), fn(_fn), a1(_a1), a2(_a2), a3(_a3), a4(_a4) {}
};
public:
/// Queue a member call, return the value in a future.
template <typename R, typename I, typename F> void QueueMemberCall(Future <R> &f, I i, F fn)
{ Queue(new RValMemberCall <R, I, F> (f, i, fn)); }
template <typename R, typename I, typename F, typename A1> void QueueMemberCall(Future <R> &f, I i, F fn, const A1 &a1)
{ Queue(new RValMemberCall1 <R, I, F, A1> (f, i, fn, a1)); }
template <typename R, typename I, typename F, typename A1, typename A2> void QueueMemberCall(Future <R> &f, I i, F fn, const A1 &a1, const A2 &a2)
{ Queue(new RValMemberCall2 <R, I, F, A1, A2> (f, i, fn, a1, a2)); }
template <typename R, typename I, typename F, typename A1, typename A2, typename A3> void QueueMemberCall(Future <R> &f, I i, F fn, const A1 &a1, const A2 &a2, const A3 &a3)
{ Queue(new RValMemberCall3 <R, I, F, A1, A2, A3> (f, i, fn, a1, a2, a3)); }
template <typename R, typename I, typename F, typename A1, typename A2, typename A3, typename A4> void QueueMemberCall(Future <R> &f, I i, F fn, const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4)
{ Queue(new RValMemberCall4 <R, I, F, A1, A2, A3, A4> (f, i, fn, a1, a2, a3, a4)); }
public:
bool Execute()
{
BaseCall *c = NULL;
{
Threading::MutexLock lock(&queue_mutex);
if (call_queue.GetCount() == 0)
return false;
c = call_queue[0];
call_queue.RemoveAt(0);
}
if (c)
{
c->Execute();
delete c;
}
return asbool(c);
}
void ExecuteAll()
{
while (Execute() == true) {}
}
};
} // ASync
} // GS
#endif // __ASYNC_CALL_QUEUE__

View File

@ -0,0 +1,84 @@
/* -----------------------------------------------------------------------------
GSFramework
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
----------------------------------------------------------------------------- */
#ifndef __ASYNC_CALL_QUEUE_THREAD__
#define __ASYNC_CALL_QUEUE_THREAD__
#include "async/async_call_queue.h"
#include "thread/thread_event.h"
namespace GS {
namespace Threading {
/*!
@short A worker thread whose sole purpose is to process its async call queue.
@author Emmanuel Julien (ejulien@owloh.com)
*/
class ASyncCallQueueThread : public Thread
{
Atomic32 acqt_running;
Event queue_event;
ASync::CallQueue call_queue;
public:
virtual void OnIdle() {}
virtual void Execute()
{
for (acqt_running.Set(1); acqt_running.Get() != 2; )
{
call_queue.ExecuteAll();
OnIdle();
queue_event.Wait();
}
acqt_running.Set(0);
}
void Stop()
{
if (acqt_running.Get() != 0)
{
acqt_running.Set(2);
queue_event.Trigger();
while (acqt_running.Get() != 0); // spinlock
}
}
template <typename I, typename F> void QueueMemberCall(I i, F fn)
{ call_queue.QueueMemberCall(i, fn); queue_event.Trigger(); }
template <typename I, typename F, typename A1> void QueueMemberCall(I i, F fn, const A1 &a1)
{ call_queue.QueueMemberCall(i, fn, a1); queue_event.Trigger(); }
template <typename I, typename F, typename A1, typename A2> void QueueMemberCall(I i, F fn, const A1 &a1, const A2 &a2)
{ call_queue.QueueMemberCall(i, fn, a1, a2); queue_event.Trigger(); }
template <typename I, typename F, typename A1, typename A2, typename A3> void QueueMemberCall(I i, F fn, const A1 &a1, const A2 &a2, const A3 &a3)
{ call_queue.QueueMemberCall(i, fn, a1, a2, a3); queue_event.Trigger(); }
template <typename I, typename F, typename A1, typename A2, typename A3, typename A4> void QueueMemberCall(I i, F fn, const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4)
{ call_queue.QueueMemberCall(i, fn, a1, a2, a3, a4); queue_event.Trigger(); }
/// Queue a member call, return the value in a future.
template <typename R, typename I, typename F> void QueueMemberCall(ASync::Future <R> &f, I i, F fn)
{ call_queue.QueueMemberCall(f, i, fn); queue_event.Trigger(); }
template <typename R, typename I, typename F, typename A1> void QueueMemberCall(ASync::Future <R> &f, I i, F fn, const A1 &a1)
{ call_queue.QueueMemberCall(f, i, fn, a1); queue_event.Trigger(); }
template <typename R, typename I, typename F, typename A1, typename A2> void QueueMemberCall(ASync::Future <R> &f, I i, F fn, const A1 &a1, const A2 &a2)
{ call_queue.QueueMemberCall(f, i, fn, a1, a2); queue_event.Trigger(); }
template <typename R, typename I, typename F, typename A1, typename A2, typename A3> void QueueMemberCall(ASync::Future <R> &f, I i, F fn, const A1 &a1, const A2 &a2, const A3 &a3)
{ call_queue.QueueMemberCall(f, i, fn, a1, a2, a3); queue_event.Trigger(); }
template <typename R, typename I, typename F, typename A1, typename A2, typename A3, typename A4> void QueueMemberCall(ASync::Future <R> &f, I i, F fn, const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4)
{ call_queue.QueueMemberCall(f, i, fn, a1, a2, a3, a4); queue_event.Trigger(); }
virtual ~ASyncCallQueueThread()
{ Stop(); }
};
} // Threading
} // GS
#endif // __ASYNC_CALL_QUEUE_THREAD__

View File

@ -0,0 +1,67 @@
/* -----------------------------------------------------------------------------
GSFramework
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
----------------------------------------------------------------------------- */
#ifndef __NFUTURE__
#define __NFUTURE__
#include "thread/atomic_value.h"
#include "memory/nshared_ptr.h"
namespace GS {
namespace ASync {
/*
@short Future.
@author Emmanuel Julien (ejulien@nworks.fr)
*/
template <class T> class Future
{
T value;
Threading::Atomic32 set;
public:
bool IsSet() const
{ return set.Get() == 1; }
void Set(const T &_value)
{
value = _value;
set.Set(1);
}
void Wait()
{ while (!IsSet()); }
T &Get()
{
Wait();
return value;
}
};
//
template <> class Future <void>
{
Threading::Atomic32 set;
public:
bool IsSet() const
{ return set.Get() == 1; }
void Set()
{ set.Set(1); }
void Wait()
{ while (!IsSet()); }
};
} // ASync
} // GS
#endif // __NFUTURE__

View File

@ -0,0 +1,131 @@
/* -----------------------------------------------------------------------------
GSFramework
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
----------------------------------------------------------------------------- */
#ifndef __JOB_SYSTEM__
#define __JOB_SYSTEM__
#define __USE_LOCK_FREE_JOB_QUEUE__ 1
#include "thread/thread_event.h"
#include "thread/thread.h"
#include "thread/mutex.h"
#include "container/nlist.h"
#if __USE_LOCK_FREE_JOB_QUEUE__
#include "container/mpmc_bounded_queue.h"
#else
#include "container/nstack.h"
#endif
#include "container/narray.h"
#include "memory/nauto_ptr.h"
#include "nstring/nstring.h"
#include "time/ntime.h"
namespace GS {
namespace ASync {
class JobManager;
//
class JobWorkerThread : public Threading::Thread
{
protected:
JobManager &manager;
Threading::Atomic32 running;
uint worker_id;
public:
/// Get worker id.
int GetWorkerId() const { return worker_id; }
/// Worker loop.
virtual void Execute();
/// Stop worker thread.
void Stop();
/// Is the worker thread running.
bool IsRunning() const;
JobWorkerThread(JobManager &m, uint id) : manager(m), worker_id(id) {}
};
/// Parallel job.
struct Job
{
String name;
Time time_start, time_end;
Threading::Atomic32 done;
/// Execute job.
virtual void Execute(uint worker_id) = 0;
Job(const char *_name) : name(_name), done(1) {}
virtual ~Job() {}
};
/// Job group.
class JobGroup
{
friend class JobManager;
AutoPtr <Threading::Mutex> job_list_mutex;
List <Job *> job_list;
public:
JobGroup();
};
//
class JobManager
{
friend class JobWorkerThread;
protected:
Array <JobWorkerThread *> pool;
#if __USE_LOCK_FREE_JOB_QUEUE__
mpmc_bounded_queue <Job *> pending_queue;
#else
AutoPtr <Mutex> pending_queue_mutex;
Stack <Job *> pending_queue;
#endif
public:
Threading::Event job_queued_event;
/// Wait for a job to complete.
bool JoinJob(Job *, bool blocking = true);
/// Wait for a job group to complete.
bool JoinGroup(JobGroup *, bool blocking = true);
/// Execute a pending job on the caller thread.
bool ExecutePendingJob(uint worker_id);
bool EnqueueJob(Job * = 0, JobGroup * = 0);
/// Get the number of worker.
uint GetWorkerPoolSize() const;
/// Create the job worker thread pool.
bool CreateJobThreadPool(uint count = 0);
/// Free the job worker thread pool.
void FreeJobThreadPool();
JobManager();
~JobManager();
};
} // ASync
} // GS
#endif // __JOB_SYSTEM__

View File

@ -0,0 +1,55 @@
/* -----------------------------------------------------------------------------
GSFramework
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
----------------------------------------------------------------------------- */
#ifndef __JOB_PERF__
#define __JOB_PERF__
#include "async/job.h"
namespace GS {
namespace ASync {
//
struct JobPerf
{
Time slice_duration;
Time tasks_duration;
void Reset()
{
slice_duration.setSec(0);
tasks_duration.setSec(0);
}
};
//
template <class Container> void CollectJobsPerf(const Container &jobs, uint count, JobPerf &perf)
{
if (count == 0)
return;
Time slice_start = jobs[0]->time_start, slice_end = jobs[0]->time_end;
perf.tasks_duration += jobs[0]->time_end - jobs[0]->time_start;
for (uint n = 1; n < count; ++n)
{
slice_start = Types::Min(jobs[n]->time_start, slice_start);
slice_end = Types::Max(jobs[n]->time_end, slice_end);
perf.tasks_duration += jobs[n]->time_end - jobs[n]->time_start;
}
perf.slice_duration += slice_end - slice_start;
};
} // ASync
} // GS
#endif // __JOB_PERF__

View File

@ -0,0 +1,40 @@
/* -----------------------------------------------------------------------------
GSFramework
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
----------------------------------------------------------------------------- */
#ifndef __NTASKLOOP__
#define __NTASKLOOP__
//------------------------------------------------------------------------------
#define StartTaskLoop(_CONDITION, _TIMEOUT)\
{\
using namespace GS;\
\
int ref_clock = Platform::Get().GetClock();\
bool timeout = false;\
\
while (_CONDITION)\
{\
if ((Platform::Get().GetClock() - ref_clock) >= _TIMEOUT)\
{\
timeout = true;\
break;\
}
#define EndTaskLoop } }
#define EndTaskLoopOnTimeout(_ON_TIMEOUT)\
}\
\
if (timeout)\
{\
_ON_TIMEOUT\
}\
}
//------------------------------------------------------------------------------
#endif // __NTASKLOOP__

View File

@ -0,0 +1,37 @@
/* -----------------------------------------------------------------------------
GSFramework
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
----------------------------------------------------------------------------- */
#ifndef __BILLING__
#define __BILLING__
namespace GS {
/*!
@short Billing system abstract interface.
@author Emmanuel Julien (ejulien@owloh.com)
*/
struct IBilling
{
// Process a billing event.
virtual void onBillingEvent(const char *event, const char *item) = 0;
/// Returns true if the platform supports billing.
virtual bool isBillingServiceSupported() = 0;
/// Request a new purchase.
virtual bool requestPurchase(const char *) = 0;
/// Confirm a purchase.
virtual bool confirmPurchase(const char *) = 0;
/// Restore managed purchase states.
virtual bool restorePurchases() = 0;
virtual ~IBilling() {}
};
} // GS
#endif // __BILLING__

View File

@ -0,0 +1,57 @@
/* -----------------------------------------------------------------------------
GSFramework
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
----------------------------------------------------------------------------- */
#ifndef __CONTAINER_SORT__
#define __CONTAINER_SORT__
namespace GS {
class ContainerSort
{
template <typename T, typename L> static inline void Swap(L &t, int i, int j)
{
if (i != j)
{ T swap = t[j]; t[j] = t[i]; t[i] = swap; }
}
template <typename T, typename L, typename C> static int QuickSortPartition(L &t, C compare, int first, int last, int pivot)
{
Swap <T, L> (t, pivot, last);
int j = first;
for (int i = first; i < last; ++i)
if (compare(t[i], t[last]) > 0)
{
Swap <T, L> (t, i, j);
++j;
}
Swap <T, L> (t, j, last);
return j;
}
template <typename T, typename L, typename C> static void QuickSortStep(L &t, C compare, int first, int last)
{
if (first < last)
{
int pivot = (first + last) / 2;
pivot = QuickSortPartition <T, L, C> (t, compare, first, last, pivot);
QuickSortStep <T, L, C> (t, compare, first, pivot - 1);
QuickSortStep <T, L, C> (t, compare, pivot + 1, last);
}
}
public:
/// Quick-sort a container in-place.
template <typename T, typename L, typename C> static void QuickSort(L &t, C compare)
{ QuickSortStep <T, L, C> (t, compare, 0, t.GetCount() - 1); }
};
} // GS
#endif // __CONTAINER_SORT__

View File

@ -0,0 +1,136 @@
/*
Copyright (c) 2010-2011 Dmitry Vyukov. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY DMITRY VYUKOV "AS IS" AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
EVENT SHALL DMITRY VYUKOV OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
The views and conclusions contained in the software and documentation are
those of the authors and should not be interpreted as representing official
policies, either expressed or implied, of Dmitry Vyukov.
*/
#ifndef __MPMC_BOUNDED_QUEUE__
#define __MPMC_BOUNDED_QUEUE__
#include "thread/atomic_value.h"
// Adapted from https://sites.google.com/site/1024cores/home/lock-free-algorithms/queues/bounded-mpmc-queue
template<typename T> class mpmc_bounded_queue
{
struct cell_t
{
GS::Threading::Atomic32 sequence_;
T data_;
};
static size_t const cacheline_size = 64;
typedef char cacheline_pad_t[cacheline_size];
cacheline_pad_t pad0_;
cell_t * const buffer_;
size_t const buffer_mask_;
cacheline_pad_t pad1_;
GS::Threading::Atomic32 enqueue_pos_;
cacheline_pad_t pad2_;
GS::Threading::Atomic32 dequeue_pos_;
cacheline_pad_t pad3_;
void operator = (mpmc_bounded_queue const&);
mpmc_bounded_queue(mpmc_bounded_queue const&);
public:
bool enqueue(T const &data)
{
cell_t *cell;
int pos = enqueue_pos_.Get();
for (;;)
{
cell = &buffer_[pos & buffer_mask_];
size_t seq = cell->sequence_.Get();
intptr_t dif = (intptr_t)seq - (intptr_t)pos;
if (dif == 0)
{
if (enqueue_pos_.Cas(pos, pos + 1) == pos)
break;
}
else if (dif < 0)
return false;
else
pos = enqueue_pos_.Get();
}
cell->data_ = data;
cell->sequence_.Set(pos + 1);
return true;
}
bool dequeue(T &data)
{
cell_t *cell;
int pos = dequeue_pos_.Get();
for (;;)
{
cell = &buffer_[pos & buffer_mask_];
size_t seq = cell->sequence_.Get();
intptr_t dif = (intptr_t)seq - (intptr_t)(pos + 1);
if (dif == 0)
{
if (dequeue_pos_.Cas(pos, pos + 1) == pos)
break;
}
else if (dif < 0)
return false;
else
pos = dequeue_pos_.Get();
}
data = cell->data_;
cell->sequence_.Set(pos + buffer_mask_ + 1);
return true;
}
mpmc_bounded_queue(size_t buffer_size) : buffer_(new cell_t [buffer_size]), buffer_mask_(buffer_size - 1)
{
for (size_t i = 0; i != buffer_size; i += 1)
buffer_[i].sequence_.Set(i);
enqueue_pos_.Set(0);
dequeue_pos_.Set(0);
}
~mpmc_bounded_queue()
{
delete [] buffer_;
}
};
#endif // __MPMC_BOUNDED_QUEUE__

View File

@ -0,0 +1,215 @@
/* -----------------------------------------------------------------------------
GSFramework
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
----------------------------------------------------------------------------- */
#ifndef __NARRAY__
#define __NARRAY__
#include "alloc/ialloc.h"
#include "memory/memory.h"
#include "assert/nassert.h"
namespace GS {
/*!
@short Managed array.
@author Emmanuel Julien (ejulien@gsworks.fr)
*/
template <class T> class Array
{
uint count;
T *data;
#if __ENABLE_ALLOCATION_STAT__
Alloc::System system;
#endif
public:
inline operator T *() const
{ return data; }
inline T *c_ptr() const
{ return data; }
inline T &operator [] (int n) const
{ return data[n]; }
inline T &operator [] (uint n) const
{ return data[n]; }
void operator = (Array <T> &o) ///< Transfer assignation.
{ Transfer(o); }
inline T *Start() const
{ return data; }
inline T *End() const
{ return &data[count]; }
inline bool IsValid() const
{ return data ? true : false; }
inline bool IsNull() const
{ return data ? false : true; }
/// Return the number of elements of type T in the buffer.
inline uint GetCount() const
{ return count; }
/// Return the buffer size in bytes.
inline size_t GetSize() const
{ return count * sizeof(T); }
void Free()
{
if (data)
__NSTAT_DELETE(count * sizeof(T), system);
// _safe_delete_array(data);
delete[] data;
data = 0;
count = 0;
}
/// Reallocate buffer elements.
bool Reallocate(uint new_count)
{
if (new_count == count)
return true;
if (T *new_data = new T[new_count])
{
__NSTAT_ALLOC(new_count * sizeof(T), system);
Memory::Copy(new_data, data, GetSize());
if (data)
__NSTAT_DELETE(count * sizeof(T), system);
// _safe_delete_array(data);
delete[] data;
data = 0;
data = new_data;
count = new_count;
}
else
return false;
return true;
}
/// Allocate buffer elements.
bool Allocate(uint _count)
{
/// @note We could add a small tolerance here to potentially reduce fragmentation?
if (_count == count)
return true;
Free();
if (_count && ((data = new T[_count]) == 0))
return false;
__NSTAT_ALLOC(_count * sizeof(T), system);
count = _count;
return true;
}
/// Relinquish ownership of the managed memory block.
T *Detach()
{
T *r = data;
data = 0;
count = 0;
return r;
}
/// Take ownership of a managed memory block.
void Attach(uint _count, T *_data)
{
Free();
count = _count;
data = _data;
}
/// Transfer data buffer.
void Transfer(Array <T> &b)
{
Free();
count = b.GetCount();
data = b.Detach();
#if __ENABLE_ALLOCATION_STAT__
__NSTAT_DELETE(count * sizeof(T), b.system);
__NSTAT_ALLOC(count * sizeof(T), system);
#endif
}
/// Clone data buffer.
bool Clone(const Array <T> &b)
{
Free();
if (!Allocate(b.GetCount()))
return false;
for (uint n = 0; n < GetCount(); ++n)
data[n] = b[n];
return true;
}
/// Fill data buffer.
void Fill(const T &v, uint from = 0, uint to = 0)
{
if (to <= 0)
to = count + to;
__ASSERT__(from <= count);
__ASSERT__(to <= count);
for (uint n = from; n < to; ++n)
data[n] = v;
}
/// Swap two data buffer.
static void Swap(Array <T> &a, Array <T> &b)
{
uint count_a = a.GetCount(), count_b = b.GetCount();
T *data_a = a.Detach(), *data_b = b.Detach();
a.Attach(count_b, data_b);
b.Attach(count_a, data_a);
}
Array(uint _count, Alloc::System sys = Alloc::General)
{
data = 0; count = 0;
#if __ENABLE_ALLOCATION_STAT__
system = sys;
#endif
Allocate(_count);
}
Array(uint _count, const T *_data, Alloc::System sys = Alloc::General)
{
data = 0; count = 0;
#if __ENABLE_ALLOCATION_STAT__
system = sys;
#endif
if (Allocate(_count))
Memory::Copy(data, _data, sizeof(T) * _count);
}
Array(const Array <T> &array, Alloc::System sys = Alloc::General) ///< Copy constructor.
{
data = 0; count = 0;
#if __ENABLE_ALLOCATION_STAT__
system = sys;
#endif
Allocate(array.GetCount());
Memory::Copy(data, array.c_ptr(), array.GetSize());
}
Array(Alloc::System sys = Alloc::General)
{
data = 0; count = 0;
#if __ENABLE_ALLOCATION_STAT__
system = sys;
#endif
}
~Array()
{ Free(); }
};
} // GS
#endif // __NARRAY__

View File

@ -0,0 +1,268 @@
/* -----------------------------------------------------------------------------
GSFramework
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
----------------------------------------------------------------------------- */
#ifndef __NARRAYLIST__
#define __NARRAYLIST__
#include "container/narray.h"
#include "log/log.h"
namespace GS {
/*!
@short Array list.
A flexible structure with faster access time (both linear and random) and
tighter memory usage than lists.
Especially suited for small types such as pointers.
@author Emmanuel Julien (ejulien@gsworks.fr)
*/
template <class T> class ArrayList
{
Array <T> array;
Array <uint> usage_map;
uint usage; ///< Array usage.
uint grow_step;
//----------------------------------------------------------------------
inline bool Grow()
{
if (int(usage) >= int(array.GetCount() - 1))
return Resize(array.GetCount() + grow_step);
return true;
}
inline bool Shrink()
{
if (((int)array.GetCount() - 1) > (int)grow_step)
if ((int)usage < ((int)array.GetCount() - 1 - (int)grow_step))
return Resize(array.GetCount() - grow_step);
return true;
}
//----------------------------------------------------------------------
public:
//----------------------------------------------------------------------
class Iterator
{
const ArrayList <T> &list;
uint i;
public:
inline void Reset(uint from = 0) { i = from; }
inline bool IsOver() const { return i < list.GetCount() ? false : true; }
inline void operator++() { ++i; }
inline T &Object() { return list[i]; }
inline T ObjectPtr() { return list[i]; }
Iterator(const ArrayList <T> &_list, uint from = 0) : list(_list), i(from) {}
};
//----------------------------------------------------------------------
//----------------------------------------------------------------------
inline uint GetCount() const
{ return usage; }
inline T &ObjectAt(int n) const
{ return array[usage_map[n]]; }
inline T &ObjectAt(uint n) const
{ return array[usage_map[n]]; }
inline T &operator [] (int n) const
{ return array[usage_map[n]]; }
inline T &operator [] (uint n) const
{ return array[usage_map[n]]; }
inline void SetGrowStep(uint step)
{ grow_step = step; }
//----------------------------------------------------------------------
//----------------------------------------------------------------------
/// Insert a new value in the list.
virtual bool Insert(const T &v, uint at)
{
Grow();
// Claim entry...
uint claimed = usage_map[usage];
// ...and shift usage map.
for (int n = (int)usage - 1; n >= (int)at; --n)
usage_map[n + 1] = usage_map[n];
usage_map[at] = claimed;
usage++;
array[claimed] = v;
array[usage_map[usage]] = 0; // enforce terminator
return true;
}
/// Add a new value to the end of the list.
bool Add(const T &v)
{
return Insert(v, usage);
}
/// Return the index at which a value is first found in the list.
int IndexOf(const T &v, uint from = 0)
{
for (uint i = from; i < usage; ++i)
if (array[usage_map[i]] == v)
return i;
return -1;
}
/// Remove an entry from the list.
virtual bool RemoveAt(uint i)
{
if (usage == 0)
return false;
// Reclaim entry...
uint reclaimed = usage_map[i];
// ...and shift usage map.
for (uint n = i + 1; n < usage; ++n)
usage_map[n - 1] = usage_map[n];
usage_map[usage - 1] = reclaimed;
usage--;
array[reclaimed] = 0; // enforce terminator
Shrink();
return true;
}
bool Remove(const T &v)
{
int i = IndexOf(v);
return i != -1 ? RemoveAt(i) : false;
}
//----------------------------------------------------------------------
//----------------------------------------------------------------------
ArrayList <T> &operator = (const T &v)
{
if (this != &v)
{
Clear();
for (uint n = 0; n < v.GetCount(); ++n)
Add(v[n]);
}
return *this;
}
ArrayList <T> &operator << (const T &v)
{
Add(v);
return *this;
}
//----------------------------------------------------------------------
//----------------------------------------------------------------------
bool Resize(uint new_size)
{
if ((int)new_size == (int)array.GetCount() - 1)
return true;
Array <T> _array(new_size + 1);
if (_array.IsNull())
__ERR__(__LOG_E__ << "Failed to allocate new array.\n", false)
for (uint n = 0; n < usage; ++n)
_array[n] = array[usage_map[n]];
array.Transfer(_array);
if (!usage_map.Allocate(new_size + 1))
__ERR__(__LOG_E__ << "Failed to allocate array bookkeeping structures.\n", false)
for (uint n = 0; n < (new_size + 1); ++n)
usage_map[n] = n;
array[usage_map[usage]] = 0; // enforce terminator
return true;
}
/*!
@short Clear the container.
Pass false to prevent the internal structures from being released,
the array list will keep its current capacity and only its usage map
will be reset.
*/
virtual void Clear(bool free_internals = true)
{
usage = 0;
if (free_internals)
Resize(0);
else
{
for (uint n = 0; n < array.GetCount(); ++n)
usage_map[n] = n;
array[0] = 0; // enforce terminator
}
}
//----------------------------------------------------------------------
ArrayList(uint initial_size = 0, uint step = 64) : usage(0), grow_step(step) { Resize(initial_size); }
virtual ~ArrayList() {}
};
/*
@short Shared object array list.
@author Emmanuel Julien (ejulien@gsworks.fr)
*/
template <class T> struct SharedArrayList : public ArrayList <T>
{
virtual bool Insert(const T &v, uint at)
{
v->AddRef();
return ArrayList <T> ::Insert(v, at);
}
virtual bool RemoveAt(uint i)
{
(*this)[i]->RemoveRef();
return ArrayList <T> :: RemoveAt(i);
}
virtual void Clear(bool free_internals = true)
{
for (uint n = 0; n < this->GetCount(); ++n)
(*this)[n]->RemoveRef();
return ArrayList <T> ::Clear(free_internals);
}
virtual ~SharedArrayList()
{ Clear(); }
};
//------------------------------------------------------------------------------
// Delete all list entries.
#define ArrayListDeleteAllPtr(T, L) { for (uint __n = 0; __n < (L).GetCount(); ++__n) delete (L)[__n]; (L).Clear(); }
// Iterate over a list of pointers.
#define ArrayListForeachPtr(T, V, L) \
for (ArrayList <T> ::Iterator iterator(L); T V = iterator.ObjectPtr(); ++iterator)
// Iterate over a list of objects.
#define ArrayListForeach(T, V, L) \
for (ArrayList <T> ::Iterator V(L); V.IsOver() == false; ++V)
/// Find item by using a template identification class.
template <typename T, typename F, typename P> T ArrayListFindEx(const ArrayList <T> &list, F filter, const P &what)
{
for (uint __n = 0; __n < list.GetCount(); ++__n)
if (filter(list[__n], what))
return list[__n];
return 0;
}
//------------------------------------------------------------------------------
} // GS
#endif // __NARRAYLIST__

View File

@ -0,0 +1,604 @@
/* -----------------------------------------------------------------------------
GSFramework
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
----------------------------------------------------------------------------- */
#ifndef __NLIST__
#define __NLIST__
#include "alloc/ialloc.h"
#include "assert/nassert.h"
namespace GS {
/*
@short List.
@author Emmanuel Julien (ejulien@gsworks.fr)
*/
template <class T> class List
{
public:
//----------------------------------------------------------------------
class Item
{
friend class List <T>;
T o;
Item *p, *n;
public:
NPLACEMENT_NEW(ListItem)
/// Return the previous list link.
inline Item *Previous() const { return p; }
/// Return the next list link.
inline Item *Next() const { return n; }
/// Retrieve a reference to the item object.
inline T &Object() { return o; }
Item(const T &obj)
{
o = obj;
p = n = 0;
}
};
//----------------------------------------------------------------------
//----------------------------------------------------------------------
class Iterator
{
Item *c, *n;
public:
inline void operator++()
{
if ((c = c ? n : 0) != 0)
n = c->n;
}
inline bool IsOver() const { return c ? false : true; }
inline Item *Next() const { return n; }
inline Item *GetItem() const { return c; }
inline T &Object() { return c->Object(); }
/// Only use when using a pointer type.
inline T ObjectPtr() { return c ? c->Object() : 0; }
void Reset(Item *start = 0)
{
c = start;
n = c ? c->Next() : 0;
}
Iterator(Item *start = 0)
{ Reset(start); }
};
//----------------------------------------------------------------------
protected:
uint count;
Item *root, *last;
public:
/// Get item count in list.
inline uint GetCount() const { return count; }
/// Get root item.
inline Item *GetRoot() const { return root; }
/// Get last item.
inline Item *GetLast() const { return last; }
/// Clone list.
void Clone(List <T> &clone_list) const
{
clone_list.Clear();
for (Item *_i = root; _i; _i = _i->Next())
clone_list.Add(_i->Object());
}
/// Get item from position.
Item *ItemAt(uint n) const
{
if (n > count)
return 0;
Item *p = root;
while (n--)
p = p->n;
return p;
}
inline T &ObjectAt(uint n) const
{ return ItemAt(n)->Object(); }
inline T &operator[] (uint n) const
{ return ItemAt(n)->Object(); }
/// Get index of a given item.
int Index(const T &o) const
{
int pos = 0;
for (Item *p = root; p; p = p->n)
{
if (p->Object() == o)
return pos;
pos++;
}
return -1;
}
/// Check whether a given item belongs to this list or not.
bool Belongs(Item *i) const
{
for (Item *s = root; s; s = s->n)
if (s == i)
return true;
return false;
}
/// Insert item after a given reference item (defaults to last).
virtual Item *Append(const T &o, Item *rfr = 0)
{
Item *i = new Item(o);
if (!i)
return 0;
if (!rfr)
{
i->p = last;
if (last)
last->n = i;
else
root = i;
last = i;
}
else
{
if (rfr->n)
rfr->n->p = i;
i->n = rfr->n;
rfr->n = i;
i->p = rfr;
if (last == rfr) // Update last.
last = i;
}
count++;
return i;
}
/// Insert item before a given reference item (defaults to root).
virtual Item *Prepend(const T &o, Item *rfr = 0)
{
Item *i = new Item(o);
if (!i)
return 0;
if (!rfr)
{
i->n = root;
if (root)
root->p = i;
else
last = i;
root = i;
}
else
{
if (rfr->p)
rfr->p->n = i;
i->p = rfr->p;
rfr->p = i;
i->n = rfr;
if (root == rfr) // Update root.
root = i;
}
count++;
return i;
}
/// Insert a value at a given position.
Item *Insert(const T &v, uint at)
{
Item *rfr = ItemAt(at);
return rfr ? Prepend(v, rfr) : 0;
}
/// Add item to list.
Item *Add(const T &o, bool append, bool allow_duplicate)
{
if (!allow_duplicate)
if (Item *i = Find(o))
return i;
return append ? Append(o) : Prepend(o);
}
/// Add item to list.
Item *Add(const T &o)
{ return Append(o); }
/// Add item to list.
List <T> &operator << (const T &o)
{
Add(o);
return *this;
}
/// Find item by reference to object.
Item *Find(const T &o) const
{
for (Item *p = root; p; p = p->n)
if (p->Object() == o)
return p;
return 0;
}
/// Find item by object value.
Item *FindByValue(const T &o) const
{
for (Item *p = root; p; p = p->n)
if (*p->Object() == *o)
return p;
return 0;
}
/*!
@short Subtract two given lists by object value.
@warning The resulting list holds pointers to the original objects.
*/
static List <T> *SubtractByValue(const List <T> &what, const List <T> &from)
{
List <T> *list = new List <T>;
if (list)
for (Item *f_p = from.root; f_p; f_p = f_p->n)
if (!what.FindByValue(f_p->Object()))
list->Add(f_p->Object());
return list;
}
/*!
@short Subtract two given lists by object address.
@warning The resulting list holds pointers to the original objects.
*/
static List <T> *SubtractByAddress(const List <T> &what, const List <T> &from)
{
List <T> *list = new List <T>;
if (list)
for (Item *f_p = from.root; f_p; f_p = f_p->n)
if (!what.Find(f_p->Object()))
list->Add(f_p->Object());
return list;
}
/// Filter out linked-list item function.
template <typename F> void FilterOut(F filter)
{
for (Item *c = GetRoot(); c; )
{
Item *n = c->Next();
if (filter(c->Object()))
Remove(c);
c = n;
}
}
/// Build a new list from select items.
template <typename F, typename P> uint Select(List <T> &out, F filter, const P &filter_param) const
{
out.Clear();
for (Item *c = GetRoot(); c; )
if (filter(c->Object(), filter_param))
out.Add(c->Object());
return out.GetCount();
}
/// Sort linked-list function.
template <typename C> void Sort(C compare)
{
for (bool swapped = true; swapped; )
{
swapped = false;
for (Item *c = GetRoot(); c; )
{
Item *n = c->Next();
if (!n)
break;
if (compare(c->Object(), n->Object()) < 0)
{
swapped = true;
c->n = n->n;
n->n = c;
n->p = c->p;
c->p = n;
if (n->p)
n->p->n = n;
else root = n;
if (c->n)
c->n->p = c;
else last = c;
}
else
c = n;
}
}
}
/// Merge sort linked-list function.
template <typename C> void MergeSort(C compare)
{
Item *list = root, *tail = 0;
if (!list)
return;
for (int insize = 1; ; insize *= 2)
{
Item *p = list;
list = 0;
tail = 0;
int merge_count = 0; // Count number of merges we do in this pass.
while (p)
{
merge_count++;
// Step along from p.
Item *q = p;
int psize = 0;
for ( ; q && (psize < insize); ++psize)
q = q->Next();
// If q hasn't fallen off end, we have two lists to merge.
int qsize = insize;
// Now we have two lists, merge them.
while (psize > 0 || (qsize > 0 && q))
{
Item *e;
if (!psize) // p is empty, e must come from q.
{ e = q; q = q->Next(); qsize--; }
else if (!qsize || !q) // q is empty, e must come from p.
{ e = p; p = p->Next(); psize--; }
else if (compare(p->Object(), q->Object()) <= 0) // First element of p is lower (or same), e must come from p.
{ e = p; p = p->Next(); psize--; }
else // First element of q is lower; e must come from q.
{ e = q; q = q->Next(); qsize--; }
// Add the next element to the merged list.
if (tail)
tail->n = e;
else list = e;
e->p = tail;
tail = e;
}
// Now p has stepped `insize' places along, and q has too.
p = q;
}
tail->n = 0;
// If we have done only one merge, we're done.
if (merge_count <= 1)
break;
}
root = list;
last = tail;
}
/// Extract object from list.
Item *ExtractItem(const T &o)
{
Item*i = Find(o);
return i ? ExtractItem(i) : 0;
}
/// Extract item from list.
Item *ExtractItem(Item *i)
{
if (!i)
return 0;
__ASSERT__(Belongs(i));
if (i->p)
i->p->n = i->n;
else
{
if (i->n)
i->n->p = 0;
root = i->n;
}
if (i->n)
i->n->p = i->p;
else
{
if (i->p)
i->p->n = 0;
last = i->p;
}
i->p = i->n = 0;
--count;
return i;
}
/// Extract item at position.
Item *ExtractAt(uint n)
{
Item *i = ItemAt(n);
return i ? ExtractItem(i) : 0;
}
/// Remove item from list.
virtual bool Remove(Item *i)
{
if (ExtractItem(i) == 0)
return false;
delete i;
return true;
}
/// Remove item from list.
virtual bool Remove(const T &o)
{
return Remove(Find(o));
}
/// Remove item at position.
bool RemoveAt(uint n)
{
Item *i = ItemAt(n);
return i ? Remove(i) : false;
}
/// Remove all items from the list.
virtual void Clear()
{
for (Item *p = root, *n; p; p = n)
{
n = p->n;
delete p;
}
count = 0;
root = last = 0;
}
List()
{
count = 0;
root = last = 0;
}
virtual ~List()
{ Clear(); }
};
/*
@short Auto linked-list.
@author Emmanuel Julien (ejulien@gsworks.fr)
*/
template <class T> struct AutoList : public List <T>
{
virtual bool Remove(class List <T> ::Item *i)
{
T o = i->Object();
if (!List <T> ::Remove(i))
return false;
delete o;
return true;
}
virtual bool Remove(const T &o)
{
class List <T> ::Item *i = this->Find(o);
return i ? this->Remove(i) : false;
}
virtual void Clear()
{
for (class List <T> ::Item *p = this->root; p; p = p->Next())
delete p->Object();
List <T> ::Clear();
}
virtual ~AutoList()
{ this->Clear(); }
};
/*
@short Shared object linked-list.
@author Emmanuel Julien (ejulien@gsworks.fr)
*/
template <class T> struct SharedList : public List <T>
{
virtual class List <T> ::Item *Append(const T &o, class List <T> ::Item *rfr = 0)
{
class List <T> ::Item *i = List <T> ::Append(o, rfr);
if (i)
o->AddRef();
return i;
}
virtual class List <T> ::Item *Prepend(const T &o, class List <T> ::Item *rfr = 0)
{
class List <T> ::Item *i = List <T> ::Prepend(o, rfr);
if (i)
o->AddRef();
return i;
}
virtual bool Remove(class List <T> ::Item *i)
{
T o = i->Object();
if (!List <T> ::Remove(i))
return false;
o->RemoveRef();
return true;
}
virtual bool Remove(const T &o)
{
class List <T> ::Item *i = this->Find(o);
return i ? this->Remove(i) : false;
}
virtual void Clear()
{
for (class List <T> ::Item *p = this->root; p; p = p->Next())
p->Object()->RemoveRef();
List <T> ::Clear();
}
virtual ~SharedList()
{ Clear(); }
};
//------------------------------------------------------------------------------
// Delete all list entries.
#define ListDeleteAllPtr(T, L) { class GS::List <T> ::Item *t; while ((t = (L).GetRoot()) != 0) { T _o = t->Object(); (L).Remove(t); delete(_o); } }
// Iterate over a list of pointers.
#define ListForeachPtr(T, V, L) \
for (class GS::List <T> ::Iterator iterator((L).GetRoot()); T V = iterator.ObjectPtr(); ++iterator)
// Iterate over a list of objects.
#define ListForeach(T, V, L) \
for (class GS::List <T> ::Iterator V((L).GetRoot()); V.IsOver() == false; ++V)
/// Find item by using a template identification class.
template <typename T, typename F, typename P> T ListFindEx(const List <T> &list, F filter, const P &what)
{
for (class List <T> ::Item *p = list.GetRoot(); p; p = p->Next())
if (filter(p->Object(), what))
return p->Object();
return 0;
}
/// Remove all items with a reference count of 1 from a shared list.
template <class T> uint PurgeSharedList(SharedList <T *> &list)
{
uint c = list.GetCount();
ListForeachPtr(T *, t, list)
if (t->GetRefCount() == 1)
list.Remove(iterator.GetItem());
return c - list.GetCount();
}
//------------------------------------------------------------------------------
} // GS
#endif // __NLIST__

View File

@ -0,0 +1,68 @@
/*------------------------------------------------------------------------------
GSFramework
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
----------------------------------------------------------------------------- */
#ifndef __NMAP__
#define __NMAP__
#include "container/nlist.h"
#include "memory/nauto_ptr.h"
namespace GS {
//
template <class KType, class VType> struct Pair
{
KType key;
VType value;
Pair(const KType _key, const VType _value) : key(_key), value(_value) {}
};
/*!
@short Very naive map.
@todo Red-black tree.
@author Emmanuel Julien (ejulien@nworks.fr)
*/
template <class KType, class VType> class Map
{
AutoList <Pair <KType, VType> *> pairs;
public:
Pair <KType, VType> *Get(const KType &key) const
{
for (typename List <Pair <KType, VType> *> ::Item *p = pairs.GetRoot(); p; p = p->Next())
if (p->Object()->key == key)
return p->Object();
return 0;
}
uint GetCount() const
{ return pairs.GetCount(); }
bool HasKey(const KType &key) const
{ return asbool(Get(key)); }
VType &operator [] (const KType &key) const
{ return Get(key)->value; }
Pair <KType, VType> *Add(const KType &key, const VType &value)
{
AutoPtr <Pair <KType, VType> > pair(new Pair <KType, VType> (key, value));
return pair.IsValid() && pairs.Add(pair) ? pair.Detach() : 0;
}
bool Delete(Pair <KType, VType> *pair)
{ return pairs.Remove(pair); }
bool Delete(const KType &key)
{ return Delete(Get(key)); }
};
} // GS
#endif // __NMAP__

View File

@ -0,0 +1,150 @@
/* -----------------------------------------------------------------------------
GSFramework
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
----------------------------------------------------------------------------- */
#ifndef __NSTACK__
#define __NSTACK__
#include "container/narray.h"
namespace GS {
/*!
@short Simple value stack.
@author Emmanuel Julien (ejulien@owloh.com)
*/
template <class T> class Stack
{
protected:
Array <T> data;
uint usage;
uint grow_step;
public:
inline const T &operator [] (int n) const
{ return data[n]; }
inline const T &Top() const
{ return data[usage - 1]; }
//----------------------------------------------------------------------
T *Detach()
{
usage = 0;
return data.Detach();
}
virtual void Transfer(Stack <T> &from)
{
usage = from.GetCount();
data.Transfer(from.data);
}
//----------------------------------------------------------------------
//----------------------------------------------------------------------
/// Push a value on top of the stack.
virtual bool Push(const T &v)
{
if (usage == data.GetCount())
if (!data.Reallocate(usage + 64))
return false;
data[usage++] = v;
return true;
}
/// Pop a value from the stack.
virtual void Pop()
{
if (usage > 0)
--usage;
}
inline bool Add(const T &v)
{ return Push(v); }
inline Stack <T> &operator << (const T &v)
{
Add(v);
return *this;
}
//----------------------------------------------------------------------
//----------------------------------------------------------------------
inline uint GetCount() const
{ return usage; }
inline void SetGrowStep(uint step)
{ grow_step = step; }
virtual void Clear(bool free_internals = true)
{
if (free_internals)
data.Free();
usage = 0;
}
//----------------------------------------------------------------------
//----------------------------------------------------------------------
inline int Index(const T &v) const
{
for (uint n = 0; n < usage; ++n)
if (data[n] == v)
return n;
return -1;
}
//----------------------------------------------------------------------
Stack(uint size = 0, uint step = 64) : usage(0), grow_step(step) { data.Allocate(size); }
virtual ~Stack() {}
};
/// Auto-stack.
template <class T> struct AutoStack : public Stack <T>
{
//----------------------------------------------------------------------
virtual void Transfer(Stack <T> &from)
{
for (uint n = 0; n < this->usage; ++n)
delete this->data[n];
Stack <T> ::Transfer(from);
}
//----------------------------------------------------------------------
//----------------------------------------------------------------------
virtual void Pop()
{
if (this->usage > 0)
delete this->data[--this->usage];
}
virtual void Clear(bool free_internals = true)
{
for (uint n = 0; n < this->usage; ++n)
delete this->data[n];
Stack <T> ::Clear(free_internals);
}
//----------------------------------------------------------------------
//----------------------------------------------------------------------
/*!
@short Drop all pointers managed by this stack, does not free the storage.
The dropped pointers are expected to have been taken care of as this
container will completely forget about them.
*/
void DropContentOwnership()
{
for (uint n = 0; n < this->usage; ++n)
this->data[n] = 0;
this->usage = 0;
}
//----------------------------------------------------------------------
AutoStack(uint size = 0, uint step = 64) : Stack <T> (size, step) {}
virtual ~AutoStack() { Clear(); }
};
} // GS
#endif // __NSTACK__

View File

@ -0,0 +1,161 @@
/*
*/
#ifndef __TMPL_PAIRLIST__
#define __TMPL_PAIRLIST__
#include "data/array_list.h"
#include "platform_config.h"
//
template <class PAIR, class TYPE> class ntPairList;
/*
@short Pair item.
@author Emmanuel Julien (ejulien@gsworks.fr)
*/
template <class TYPE> class ntPairItem : public nArrayEntry
{
protected:
int hash;
public:
TYPE *a, *b; ///< Object pair.
void *pair_data; ///< Pair associated data block.
/// Compute pair hash value.
static int ComputeHash(TYPE *_a, TYPE *_b)
{
int hash = (((uintptr_t)_a) & 0xf0f0f0f0) | (((uintptr_t)_b) & 0x0f0f0f0f);
hash = (hash + 0x7ed55d16) + (hash << 12);
hash = (hash ^ 0xc761c23c) ^ (hash >> 19);
hash = (hash + 0x165667b1) + (hash << 5);
hash = (hash + 0xd3a2646c) ^ (hash << 9);
hash = (hash + 0xfd7046c5) + (hash << 3);
hash = (hash ^ 0xb55a4f09) ^ (hash >> 16);
return hash;
}
/// Get pair hash.
int Hash() const { return hash; }
ntPairItem(TYPE *_a, TYPE *_b)
{
a = _a; b = _b;
hash = ComputeHash(a, b);
}
};
/*
*/
struct ntPairListPool
{
uint bucket,
entry;
void Reset()
{ bucket = entry = 0; }
ntPairListPool()
{ Reset(); }
};
/*
@short Pair list.
@author Emmanuel Julien (ejulien@gsworks.fr)
*/
template <class PAIR, class TYPE> class ntPairList
{
#define PairListBucketCount 64
#define OrderPairItems(_A_, _B_) { if (_A_ > _B_) { TYPE *t = _A_; _A_ = _B_; _B_ = t; } }
protected:
uint count;
nArrayList bucket[PairListBucketCount];
public:
/// Get item count in list.
uint GetCount() const
{ return count; }
/// Pool list.
PAIR *Pool(ntPairListPool &pool) const
{
while (pool.bucket < PairListBucketCount)
{
if (pool.entry < bucket[pool.bucket].GetCount())
break;
pool.entry = 0;
pool.bucket++;
}
if (pool.bucket == PairListBucketCount)
return 0;
return (PAIR *)bucket[pool.bucket][pool.entry++];
}
/// Add a pair.
PAIR *Add(TYPE *a, TYPE *b)
{
OrderPairItems(a, b);
PAIR *pair = new PAIR(a, b);
if (pair && !bucket[pair->Hash() & (PairListBucketCount - 1)].Add(pair))
_safe_delete(pair);
else
count++;
return pair;
}
/// Find a pair.
PAIR *Find(TYPE *a, TYPE *b)
{
OrderPairItems(a, b);
int hash = PAIR::ComputeHash(a, b);
nArrayList &h_bucket = bucket[hash & (PairListBucketCount - 1)];
for (uint n = 0; n < h_bucket.GetCount(); ++n)
{
PAIR *pair = (PAIR *)h_bucket[n];
if ((pair->a == a) && (pair->b == b))
return pair;
}
return 0;
}
/// Remove pair.
bool Remove(PAIR *pair)
{
if (bucket[pair->Hash() & (PairListBucketCount - 1)].Delete(pair))
{
count--;
return false;
}
return true;
}
/// Delete all pair.
void DeleteAll(bool freedata = true)
{
for (int n = 0; n < PairListBucketCount; ++n)
bucket[n].DeleteAll(freedata);
count = 0;
}
ntPairList()
{ count = 0; }
};
#endif // __TMPL_PAIRLIST__

View File

@ -0,0 +1,62 @@
/* -----------------------------------------------------------------------------
GSFramework
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
----------------------------------------------------------------------------- */
#ifndef __SMARTMEDIANAVG__
#define __SMARTMEDIANAVG__
#include "sort/sort.h"
namespace GS {
//
template <class T, int Size = 16, int SafeGuard = 4> class SmartMedianAverage
{
T history[Size];
int count;
public:
void LogValue(T v)
{
if (count < Size)
count++; // fill up
else
for (int n = 1; n < Size; ++n) // scroll
history[n - 1] = history[n];
history[count - 1] = v;
}
T GetMedian() const
{
if (count == 0)
return 0;
if (count < Size)
return history[0]; // unfiltered
// Sort current histogram values.
typename Sort <T, int> ::Entry entries[Size];
for (int n = 0; n < Size; ++n)
entries[n].v = history[n];
Sort <T, int> ::QuickSort(Size, entries);
// Compute average of the safe values.
T avg = 0;
for (int n = (Size / SafeGuard); n < (Size - Size / SafeGuard); ++n)
avg += entries[n].v;
return avg / (Size - (Size / SafeGuard) * 2);
}
void Reset() { count = 0; }
SmartMedianAverage() : count(0) {}
};
} // GS
#endif // __SMARTMEDIANAVG__

View File

@ -0,0 +1,85 @@
/* -----------------------------------------------------------------------------
GSFramework
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
----------------------------------------------------------------------------- */
#ifndef __NIODATASTORE__
#define __NIODATASTORE__
#include "filesystem/io_handle.h"
#include "container/nlist.h"
#include "nstring/nstring.h"
#include "thread/mutex.h"
#include "unit/nunit.h"
namespace GS {
namespace IO {
/*!
@short Data store.
*/
class DataStore
{
Threading::Mutex mutex;
SharedPtr <Base> io;
size_t limit;
uint id_seed;
String GetNewId();
public:
struct Entry
{
String id;
size_t size;
String user;
Entry() : size(0) {}
};
private:
AutoList <Entry *> entries;
Entry *GetEntry(const String &id) const;
public:
Base *GetIO() const { return io.c_ptr(); }
const AutoList <Entry *> &GetEntries() const { return entries; }
/// Reserve space on the store, an empty id is returned if the store is full.
virtual String Reserve(size_t size);
/// Free a store alias.
virtual bool Free(const String &id);
/// Store data on a reserved id.
bool Store(const String &id, const void *data, size_t size, const char *user_data = 0);
/// Get entry size.
size_t GetEntrySize(const String &id) const;
/// Get the current store size.
size_t GetStoreSize() const;
/// Get the store free space size.
size_t GetFreeStore() const;
/// Restore store content from the storage fs.
bool Load(const char *path = "store.db");
/// Save store content to the storage fs.
bool Save(const char *path = "store.db");
DataStore(Base *storage, size_t storage_limit = Units::MB(32)) : io(storage), limit(storage_limit), id_seed(0) {}
};
} // IO
} // GS
#endif // __NIODATASTORE__

View File

@ -0,0 +1,73 @@
/* -----------------------------------------------------------------------------
GSFramework
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
----------------------------------------------------------------------------- */
#ifndef __NFILESYSTEM__
#define __NFILESYSTEM__
#include "container/nlist.h"
#include "filesystem/io_base.h"
#include "nstring/nstring.h"
#include "memory/nauto_ptr.h"
namespace GS {
namespace IO {
class Handle;
struct Base;
//
struct MountPoint
{
String mount_point;
SharedPtr <Base> io_sys;
MountPoint(const char *mount, Base *io) : mount_point(mount), io_sys(io) {}
};
/*!
@short I/O system.
@author Emmanuel Julien (ejulien@nworks.fr)
*/
class Filesystem
{
AutoList <MountPoint *> mount_list;
SharedList <Base *> root_mount;
public:
String MapToAbsolute(const char *) const;
String StripRootPath(const char *) const;
bool Mount(Base *, const char *mount_point = 0);
void Unmount(const char *);
void Unmount(Base *);
void UnmountAll();
Base *GetIOSystem(const char *mount_point) const;
const char *GetMountPoint(const Base *) const;
Handle *Open(const char *, Mode = ModeRead) const;
void Close(Handle *) const;
bool MkDir(const char *) const;
bool Exists(const char *) const;
bool Delete(const char *) const;
size_t FileSize(const char *) const;
bool FileLoad(const char *, Array <char> &, bool verbose = true) const;
bool FileSave(const char *, const Array <char> &) const;
bool FileCopy(const char *src, const char *dst) const;
bool FileMove(const char *src, const char *dst) const;
~Filesystem() { UnmountAll(); }
};
} // IO
} // GS
#endif // __NFILESYSTEM__

View File

@ -0,0 +1,173 @@
/* -----------------------------------------------------------------------------
GSFramework
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
----------------------------------------------------------------------------- */
#ifndef __FTPLIB__
#define __FTPLIB__
#if __PLATFORM_WINDOWS__
#include <winsock.h>
#endif
#include "ntypes.h"
/// FTP connection.
struct FtpConnection
{
enum Direction
{
Upload = 0,
Download
};
int handle;
bool ready;
char *buffer;
int buffer_usage;
Direction direction;
void FreeBuffer();
bool AllocateBuffer();
FtpConnection();
~FtpConnection()
{ FreeBuffer(); }
};
/*
@short FTP Library.
*/
class FtpLibrary
{
public:
enum ConnectionMode
{
ConnectionPORT = 0,
ConnectionPASV
};
enum TransferMode
{
TransferASCII = 'A',
TransferBinary = 'I'
};
enum AccessType
{
AccessDir = 0,
AccessDirVerbose,
AccessFileRead,
AccessFileWrite,
AccessFileReadAppend,
AccessFileWriteAppend
};
enum State
{
FtpError = 0,
FtpOk,
FtpSocketTimeout
};
protected:
char response[256];
FtpConnection master_connection;
ConnectionMode connection_mode;
size_t offset;
bool correctpasv;
/// Check server PASV support.
bool CheckPASVResponse(unsigned char *v);
/// Read and verify a response from the server.
bool CheckResponse(char c);
/// Wait for the socket to receive or flush data.
State WaitSocket(FtpConnection *socket);
/// Read a line of text.
State ReadASCII(char *buf, int max, FtpConnection *socket, int &line_length);
/// Write a line of text.
State WriteASCII(char *buf, int length, FtpConnection *socket, int &wrote_length);
/// Send a command and wait for expected response.
bool FtpSendCmd(const char *cmd, char expresp);
/// Accept connection from server.
bool FtpAcceptConnection(FtpConnection *connection);
/// Create a PORT connection for data transfer.
FtpConnection *CreatePORTConnection(TransferMode mode, FtpConnection::Direction direction, char *connection_command);
/// Create a PASV connection for data transfer.
FtpConnection *CreatePASVConnection(TransferMode mode, FtpConnection::Direction direction, char *connection_command);
/// Create a connection for data transfer.
FtpConnection *CreateConnection(const char *path, AccessType type, TransferMode mode);
/// Close connection.
bool CloseConnection(FtpConnection *connection);
/// Generic data transfer function.
State DataTransfer(const char *local_path, const char *remote_path, AccessType type, TransferMode mode);
/// Read data from a connection.
State ReadBinary(void *buffer, int max, FtpConnection *connection, int &length);
/// Write data to a connection.
State WriteBinary(void *buffer, int length, FtpConnection *connection);
public:
/// Set data connection transfer mode.
void SetDataConnectionMode(ConnectionMode mode)
{ connection_mode = mode; }
/// Get last server response received.
const char *GetLastResponse() const
{ return response; }
/// Connect to a remote server.
bool Connect(const char *host);
/// Upload file to server.
State Upload(const char *local_path, const char *remote_path, TransferMode mode = TransferBinary, int offset = 0);
/// Download file from server.
State Download(const char *local_path, const char *remote_path, TransferMode mode = TransferBinary, int offset = 0);
/// Quit server, close connection.
bool Quit();
/// Change directory.
bool ChangeDirectory(const char *path);
/// Up directory.
bool UpDirectory();
/// Delete remote file.
bool DeleteFile(const char *path);
/// Get remote file size.
int GetFileSize(const char *path, TransferMode mode = TransferBinary);
/// Download directory listing to a local file.
bool Nlst(const char *outputfile, const char *path);
/// Login remote server.
bool Login(const char *user, const char *password);
/*
Callback functions.
*/
virtual bool IdleCallback()
{ return true; }
virtual void SendCommandCallback(const char * /*command*/)
{}
virtual bool DataReadCallback(const FtpConnection * /*connection*/)
{ return true; }
virtual bool DataWriteCallback(const FtpConnection * /*connection*/)
{ return true; }
FtpLibrary();
virtual ~FtpLibrary();
};
#endif // __FTPLIB__

View File

@ -0,0 +1,66 @@
/* -----------------------------------------------------------------------------
GSFramework
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
----------------------------------------------------------------------------- */
#ifndef __NIOALIAS__
#define __NIOALIAS__
#include <stdio.h>
#include "nstring/nstring.h"
#include "container/nmap.h"
namespace GS {
namespace IO {
class Handle;
/*!
@short Alias proxy I/O.
A simple proxy I/O to provide filename aliasing to another I/O system.
@author Emmanuel Julien (ejulien@nworks.fr)
*/
class Alias : public Base
{
SharedPtr <Base> iofs;
public:
//----------------------------------------------------------------------
Map <String, String> alias_map;
String ResolveAlias(const char *path) const
{
Pair <String, String> *alias = alias_map.Get(path);
return alias ? alias->value : path;
}
//----------------------------------------------------------------------
virtual Handle *Open(const char *path, Mode mode = IORead)
{ return iofs->Open(ResolveAlias(path), mode); }
virtual void Close(Handle *h)
{ iofs->Close(h); }
virtual bool Delete(const char *path)
{ return iofs->Delete(ResolveAlias(path)); }
virtual size_t Tell(Handle *h)
{ return iofs->Tell(h); }
virtual size_t Seek(Handle *h, ptrdiff_t offset, SeekRef seek_ref = SeekCurrent)
{ return iofs->Seek(h, offset, seek_ref); }
virtual size_t Read(Handle *h, void *p, size_t size)
{ return iofs->Read(h, p, size); }
virtual size_t Write(Handle *h, const void *p, size_t size)
{ return iofs->Write(h, p, size); }
Alias(Base *io) : iofs(io) {}
};
} // IO
} // GS
#endif // __NIOALIAS__

View File

@ -0,0 +1,80 @@
/* -----------------------------------------------------------------------------
GSFramework
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
----------------------------------------------------------------------------- */
#ifndef __NIOBASE__
#define __NIOBASE__
#include <stddef.h>
#include "filesystem/io_mode.h"
#include "memory/nshared_ptr.h"
#include "container/narray.h"
#include "alloc/ialloc.h"
namespace GS {
class String;
namespace IO {
class Handle;
/*!
@short I/O base.
@author Emmanuel Julien (ejulien@nworks.fr)
*/
struct Base : public SharedObject
{
NPLACEMENT_NEW(Filesystem)
enum SeekRef
{
SeekStart = 0,
SeekCurrent,
SeekEnd
};
enum Caps
{
IsCaseSensitive = (1 << 0),
CanRead = (1 << 1),
CanWrite = (1 << 2),
CanSeek = (1 << 3),
CanDelete = (1 << 4),
CanMkDir = (1 << 5)
};
bool FileLoad(const char *uri, Array <char> &buffer);
bool FileSave(const char *uri, const Array <char> &buffer);
String FileHash(const char *uri);
virtual bool Exists(const char *);
virtual String Hash(const char *);
virtual String MapToAbsolute(const char *uri) const;
virtual String MapToRelative(const char *path) const;
virtual uint GetCaps() const = 0;
virtual Handle *Open(const char *, Mode = ModeRead) = 0;
virtual void Close(Handle *) = 0;
virtual bool Delete(const char *) = 0;
virtual size_t Tell(Handle *) = 0;
virtual size_t Seek(Handle *, ptrdiff_t offset, SeekRef = SeekCurrent) = 0;
virtual size_t Read(Handle *, void *, size_t) = 0;
virtual size_t Write(Handle *, const void *, size_t) = 0;
virtual bool MkDir(const char *) = 0;
};
} // IO
} // GS
#endif // __NIOBASE__

View File

@ -0,0 +1,87 @@
/* -----------------------------------------------------------------------------
GSFramework
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
----------------------------------------------------------------------------- */
#ifndef __NIOBUFFER__
#define __NIOBUFFER__
#include "filesystem/io_handle.h"
#include "nstring/nstring.h"
#include "memory/nauto_ptr.h"
#include "container/narray.h"
#include "unit/nunit.h"
namespace GS {
namespace IO {
//
struct IOBuffer
{
Array <char> buffer;
size_t start_pos;
size_t usage;
IOBuffer() : start_pos(0), usage(0) {}
};
//
class BufferHandle : public Handle
{
friend class Buffer;
AutoPtr <Handle> handle;
size_t size; // file size on wrapped fs
size_t pos; // position in source handle
IOBuffer read_buffer;
public:
virtual size_t GetSize() { return size; }
BufferHandle(Base *io, Handle *h) : Handle(io), handle(h), size(0), pos(0) {}
};
/*!
@short Buffered I/O filesystem wrapper.
Implements a transparent read/write buffer on top of another filesystem.
@author Emmanuel Julien (ejulien@nworks.fr)
*/
class Buffer : public Base
{
SharedPtr <Base> io;
size_t read_buffer_size,
write_buffer_size;
public:
virtual uint GetCaps() const;
virtual Handle *Open(const char *, Mode = ModeRead);
virtual void Close(Handle *);
virtual String Hash(const char *);
virtual bool Delete(const char *);
virtual size_t Tell(Handle *);
virtual size_t Seek(Handle *, ptrdiff_t offset, SeekRef = SeekCurrent);
virtual size_t Read(Handle *, void *, size_t);
virtual size_t Write(Handle *, const void *, size_t);
virtual bool MkDir(const char *);
Buffer(Base *base, size_t read_buffer_size = Units::KB(4), size_t write_buffer_size = Units::KB(4));
};
} // IO
} // GS
#endif // __NIOBUFFER__

View File

@ -0,0 +1,109 @@
/* -----------------------------------------------------------------------------
GSFramework
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
----------------------------------------------------------------------------- */
#ifndef __NIOCACHE__
#define __NIOCACHE__
#include "filesystem/data_store.h"
#include "filesystem/io_handle.h"
#include "memory/nauto_ptr.h"
#include "container/nlist.h"
#include "nstring/nstring.h"
#include "time/ntime.h"
#include "unit/nunit.h"
namespace GS {
namespace IO {
//
class CacheHandle : public Handle
{
friend class Cache;
protected:
String path;
AutoPtr <Handle> handle;
public:
CacheHandle(Base *io, const char *p, Handle *h) : Handle(io), path(p), handle(h) {}
~CacheHandle();
};
/*!
@short Cached I/O filesystem wrapper.
Implements a transparent file cache on top of another filesystem.
@author Emmanuel Julien (ejulien@nworks.fr)
*/
class Cache : public Base
{
SharedPtr <Base> io;
DataStore store;
public:
struct Entry
{
String path, id;
String hash;
uint refc;
size_t size;
Time last_use;
Entry() : refc(0), size(0) {}
};
private:
Threading::Mutex mutex;
size_t cache_size;
AutoList <Entry *> entries;
int ComputeEntryRecyclingScore(const Entry *) const;
String ReserveOnStore(size_t size);
Entry *GetCacheEntry(const char *path) const;
Entry *CreateCacheEntry(const char *path);
bool UpdateCacheEntry(Entry *entry, Array <char> *preloaded_data = 0);
bool DeleteCacheEntry(Entry *entry);
public:
virtual uint GetCaps() const;
virtual Handle *Open(const char *, Mode = ModeRead);
virtual void Close(Handle *);
virtual bool Delete(const char *);
virtual size_t Tell(Handle *);
virtual size_t Seek(Handle *, ptrdiff_t offset, SeekRef = SeekCurrent);
virtual size_t Read(Handle *, void *, size_t);
virtual size_t Write(Handle *, const void *, size_t);
virtual bool MkDir(const char *);
/// Test if a given path is in cache.
bool IsInCache(const char *path) const { return asbool(GetCacheEntry(path)); }
/// Reload cache state from its store.
bool SynchronizeWithStore(const char *store_path = "store.db");
Cache(Base *base, Base *store, size_t cache_size = Units::MB(32));
};
} // IO
} // GS
#endif // __NIOCACHE__

View File

@ -0,0 +1,70 @@
/* -----------------------------------------------------------------------------
GSFramework
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
----------------------------------------------------------------------------- */
#ifndef __NIOCFILE__
#define __NIOCFILE__
#include <stdio.h>
#include "filesystem/io_handle.h"
#include "nstring/nstring.h"
namespace GS {
namespace IO {
//
class CFileHandle : public Handle
{
friend class CFile;
FILE *file;
CFileHandle(Base *);
public:
~CFileHandle();
};
/*!
@short C-File I/O.
@author Emmanuel Julien (ejulien@nworks.fr)
*/
class CFile : public Base
{
String root;
public:
void SetRootPath(const char *);
virtual String MapToAbsolute(const char *) const;
virtual String MapToRelative(const char *) const;
virtual uint GetCaps() const;
virtual Handle *Open(const char *, Mode = ModeRead);
virtual void Close(Handle *);
virtual bool Delete(const char *);
virtual size_t Tell(Handle *);
virtual size_t Seek(Handle *, ptrdiff_t offset, SeekRef = SeekCurrent);
virtual size_t Read(Handle *, void *, size_t);
virtual size_t Write(Handle *, const void *, size_t);
virtual bool MkDir(const char *);
CFile(const char *root_path = 0);
};
} // IO
} // GS
#endif // __NIOCFILE__

View File

@ -0,0 +1,73 @@
/* -----------------------------------------------------------------------------
GSFramework
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
----------------------------------------------------------------------------- */
#ifndef __NIOCRYPTO__
#define __NIOCRYPTO__
#include "filesystem/io_memory.h"
#include "memory/nauto_ptr.h"
namespace GS {
namespace IO {
//
class CryptoHandle : public Handle
{
friend class Crypto;
AutoPtr <Handle> cached_h;
String path;
Mode io_mode;
CryptoHandle(Base *, Handle *, const char *, Mode);
public:
~CryptoHandle();
};
/*!
@short I/O Crypto proxy.
@author Emmanuel Julien (ejulien@nworks.fr)
*/
class Crypto : public Base
{
String key;
SharedPtr <Base> wrapped_io;
SharedPtr <Memory> cache_io;
void Encrypt(Array <char> &);
void Decrypt(Array <char> &);
public:
virtual uint GetCaps() const;
virtual Handle *Open(const char *, Mode = ModeRead);
virtual void Close(Handle *);
virtual bool Delete(const char *);
virtual size_t Tell(Handle *);
virtual size_t Seek(Handle *, ptrdiff_t offset, SeekRef = SeekCurrent);
virtual size_t Read(Handle *, void *, size_t);
virtual size_t Write(Handle *, const void *, size_t);
virtual bool MkDir(const char *);
Crypto(Base *, const char *key);
};
} // IO
} // GS
#endif // __NIOCRYPTO__

View File

@ -0,0 +1,77 @@
/* -----------------------------------------------------------------------------
GSFramework
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
----------------------------------------------------------------------------- */
#ifndef __NIODISPATCH__
#define __NIODISPATCH__
#include <stdio.h>
#include "filesystem/io_handle.h"
#include "memory/nauto_ptr.h"
#include "container/nlist.h"
#include "nstring/nstring.h"
namespace GS {
namespace IO {
//
class DispatcherHandle : public Handle
{
friend class Dispatcher;
AutoPtr <Handle> handle;
DispatcherHandle(Base *, Handle *);
public:
~DispatcherHandle();
};
/*!
@short Dispatcher I/O.
@author Emmanuel Julien (ejulien@nworks.fr)
*/
class Dispatcher : public Base
{
struct DispatchFS
{
String prefix;
SharedPtr <Base> fs;
};
SharedList <Base *> roots;
AutoList <DispatchFS *> mounts;
Base *Dispatch(String &, Mode);
public:
bool AddDispatch(Base *, const char *prefix = 0);
virtual uint GetCaps() const;
virtual Handle *Open(const char *, Mode = ModeRead);
virtual void Close(Handle *);
virtual String Hash(const char *);
virtual bool Delete(const char *);
virtual size_t Tell(Handle *);
virtual size_t Seek(Handle *, ptrdiff_t offset, SeekRef = SeekCurrent);
virtual size_t Read(Handle *, void *, size_t);
virtual size_t Write(Handle *, const void *, size_t);
virtual bool MkDir(const char *);
};
} // IO
} // GS
#endif // __NIODISPATCH__

View File

@ -0,0 +1,71 @@
/* -----------------------------------------------------------------------------
GSFramework
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
----------------------------------------------------------------------------- */
#ifndef __NIOHANDLE__
#define __NIOHANDLE__
#include "filesystem/io_base.h"
#include "memory/nweak_ptr.h"
namespace GS {
namespace IO {
//
class Handle
{
WeakPtr <Base> io_sys;
public:
NPLACEMENT_NEW(Filesystem)
virtual size_t GetSize();
virtual size_t Rewind();
virtual bool IsEOF();
virtual size_t Tell();
virtual size_t Seek(ptrdiff_t, Base::SeekRef = Base::SeekCurrent);
virtual size_t Read(void *, size_t);
virtual size_t Write(const void *, size_t);
template <class T> Handle &operator << (const T &v)
{
io_sys->Write(this, &v, sizeof(T));
return *this;
}
template <class T> Handle &operator >> (T &v)
{
io_sys->Read(this, &v, sizeof(T));
return *this;
}
Handle &operator << (const char *);
Handle &operator << (char *);
template <class T> bool Write(const T &v)
{ return asbool(io_sys->Write(this, &v, sizeof(T))); }
template <class T> T Read()
{
T v;
io_sys->Read(this, &v, sizeof(T));
return v;
}
Base *GetIOSystem() const
{ return io_sys.c_ptr(); }
Handle(Base *);
virtual ~Handle();
};
} // IO
} // GS
#endif // __NIOHANDLE__

View File

@ -0,0 +1,50 @@
/* -----------------------------------------------------------------------------
GSFramework
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
----------------------------------------------------------------------------- */
#ifndef __NIOHANDLE_ENDIAN__
#define __NIOHANDLE_ENDIAN__
#include "filesystem/io_handle.h"
#include "memory/endian.h"
namespace GS {
namespace IO {
/// IO Handle endian wrapper.
class HandleEndian
{
AutoPtr <Handle> h;
Endian::Config config;
public:
bool IsNull() const { return h.IsNull(); }
bool IsValid() const { return h.IsValid(); }
Handle &GetIOHandle() const { return *h; }
template <class T> const HandleEndian &operator << (const T &v)
{
*h << Endian::ToHost(v, config);
return *this;
}
template <class T> const HandleEndian &operator >> (T &v)
{
*h >> v;
Endian::ToHost(&v, sizeof(T), config);
return *this;
}
HandleEndian(Handle *in_h, Endian::Config in_config = Endian::Little) : h(in_h), config(in_config) {}
};
} // IO
} // GS
#endif // __NIOHANDLE_ENDIAN__

View File

@ -0,0 +1,42 @@
/* -----------------------------------------------------------------------------
GSFramework
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
----------------------------------------------------------------------------- */
#ifndef __NIOHANDLESEGMENT__
#define __NIOHANDLESEGMENT__
#include "filesystem/io_handle.h"
#include "memory/nauto_ptr.h"
namespace GS {
namespace IO {
//
class HandleSegment : public Handle
{
Handle *handle;
size_t offset, size;
size_t cursor;
public:
virtual size_t GetSize();
virtual size_t Tell();
virtual size_t Seek(ptrdiff_t, Base::SeekRef = Base::SeekCurrent);
virtual size_t Read(void *, size_t);
virtual size_t Write(const void *, size_t);
HandleSegment(Handle *h, size_t o, size_t s) : Handle(0), handle(h), offset(o), size(s), cursor(0) {}
};
} // IO
} // GS
#endif // __NIOHANDLESEGMENT__

View File

@ -0,0 +1,86 @@
/* -----------------------------------------------------------------------------
GSFramework
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
----------------------------------------------------------------------------- */
#ifndef __NIOMEMORY__
#define __NIOMEMORY__
#include "filesystem/io_handle.h"
#include "container/nlist.h"
#include "nstring/nstring.h"
namespace GS {
namespace IO {
//
class MemoryFile
{
friend class Memory;
String uri;
Array <char> data;
size_t size; //< Might be != data.GetSize()
MemoryFile(const char *_uri = 0) : uri(_uri), size(0) {}
public:
const String &GetUri() const { return uri; }
const Array <char> &GetData() const { return data; }
size_t GetSize() const { return size; }
};
//
class MemoryHandle : public Handle
{
friend class Memory;
MemoryFile *file;
size_t cursor;
Mode mode;
MemoryHandle(Base *, MemoryFile *, Mode = ModeRead);
public:
~MemoryHandle();
};
/*!
@short Memory I/O.
@author Emmanuel Julien (ejulien@nworks.fr)
*/
class Memory : public Base
{
AutoList <MemoryFile *> fat;
public:
/// Return the system file allocation table.
const List <MemoryFile *> &GetFat() const { return fat; }
virtual uint GetCaps() const;
virtual Handle *Open(const char *, Mode = ModeRead);
virtual void Close(Handle *);
virtual bool Delete(const char *);
virtual size_t Tell(Handle *);
virtual size_t Seek(Handle *, ptrdiff_t offset, SeekRef = SeekCurrent);
virtual size_t Read(Handle *, void *, size_t);
virtual size_t Write(Handle *, const void *, size_t);
virtual bool MkDir(const char *) { return false; }
};
} // IO
} // GS
#endif // __NIOMEMORY__

View File

@ -0,0 +1,25 @@
/* -----------------------------------------------------------------------------
GSFramework
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
----------------------------------------------------------------------------- */
#ifndef __NIOMODE__
#define __NIOMODE__
namespace GS {
namespace IO {
enum Mode
{
ModeNone = 0,
ModeRead,
ModeWrite
};
} // IO
} // GS
#endif // __NIOMODE__

114
include/platform/hash/md5.h Normal file
View File

@ -0,0 +1,114 @@
/*
Copyright (C) 1999, 2002 Aladdin Enterprises. All rights reserved.
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
L. Peter Deutsch
ghost@aladdin.com
*/
/* $Id: md5.h,v 1.4 2002/04/13 19:20:28 lpd Exp $ */
/*
Independent implementation of MD5 (RFC 1321).
This code implements the MD5 Algorithm defined in RFC 1321, whose
text is available at
http://www.ietf.org/rfc/rfc1321.txt
The code is derived from the text of the RFC, including the test suite
(section A.5) but excluding the rest of Appendix A. It does not include
any code or documentation that is identified in the RFC as being
copyrighted.
The original and principal author of md5.h is L. Peter Deutsch
<ghost@aladdin.com>. Other authors are noted in the change history
that follows (in reverse chronological order):
2002-04-13 lpd Removed support for non-ANSI compilers; removed
references to Ghostscript; clarified derivation from RFC 1321;
now handles byte order either statically or dynamically.
1999-11-04 lpd Edited comments slightly for automatic TOC extraction.
1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5);
added conditionalization for C++ compilation from Martin
Purschke <purschke@bnl.gov>.
1999-05-03 lpd Original version.
*/
/* -----------------------------------------------------------------------------
GSFramework
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
----------------------------------------------------------------------------- */
#ifndef __NMD5__
#define __NMD5__
namespace GS {
namespace MD5 {
/*
This package supports both compile-time and run-time determination of CPU
byte order. If ARCH_IS_BIG_ENDIAN is defined as 0, the code will be
compiled to run only on little-endian CPUs; if ARCH_IS_BIG_ENDIAN is
defined as non-zero, the code will be compiled to run only on big-endian
CPUs; if ARCH_IS_BIG_ENDIAN is not defined, the code will be compiled to
run on either big- or little-endian CPUs, but will run slightly less
efficiently on either one than if ARCH_IS_BIG_ENDIAN is defined.
*/
typedef unsigned char md5_byte_t; // 8-bit byte
typedef unsigned int md5_word_t; // 32-bit word
/*
@short MD5 digest.
*/
class Digest
{
md5_word_t count[2], ///< Message length in bits, lsw first.
abcd[4]; ///< Digest buffer.
md5_byte_t buf[64]; ///< Accumulate block.
/// Process.
void Process(const md5_byte_t *data /*[64]*/);
public:
void Reset();
/// Append data to the message.
void Append(const md5_byte_t *data, int nbytes);
/// Finish the message and return the digest.
void Finish(md5_byte_t digest[16]);
Digest() { Reset(); }
};
/*!
@short Convert a digest to string.
@note The string is not NULL terminated by this function.
*/
void DigestToString(const md5_byte_t digest[16], char *s);
} // MD5
} // GS
#endif // __NMD5__

View File

@ -0,0 +1,27 @@
/* -----------------------------------------------------------------------------
GSFramework
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
----------------------------------------------------------------------------- */
#ifndef __NSHA1__
#define __NSHA1__
namespace GS {
class String;
template <class T> class Array;
namespace SHA1 {
void ComputeHash(const String &source, Array <unsigned char> &hash);
String ComputeHexa(const String &source);
void ComputeHash(const Array <char> &data, Array <unsigned char> &hash);
String ComputeHexa(const Array <char> &data);
} // SHA1
} // GS
#endif // __NSHA1__

View File

@ -0,0 +1,49 @@
/*
Copyright (c) 2011, Micael Hildenborg
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of Micael Hildenborg nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY Micael Hildenborg ''AS IS'' AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL Micael Hildenborg BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef SHA1_DEFINED
#define SHA1_DEFINED
namespace sha1
{
/**
@param src points to any kind of data to be hashed.
@param bytelength the number of bytes to hash from the src pointer.
@param hash should point to a buffer of at least 20 bytes of size for storing the sha1 result in.
*/
void calc(const void* src, const int bytelength, unsigned char* hash);
/**
@param hash is 20 bytes of sha1 hash. This is the same data that is the result from the calc function.
@param hexstring should point to a buffer of at least 41 bytes of size for storing the hexadecimal representation of the hash. A zero will be written at position 40, so the buffer will be a valid zero ended string.
*/
void toHexString(const unsigned char* hash, char* hexstring);
} // namespace sha1
#endif // SHA1_DEFINED

View File

@ -0,0 +1,47 @@
/* -----------------------------------------------------------------------------
GSFramework
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
----------------------------------------------------------------------------- */
#ifndef __HTTPINTERFACE__
#define __HTTPINTERFACE__
#include "container/narray.h"
namespace GS {
namespace HTTP {
/*!
@short HTTP interface.
@author Emmanuel Julien (ejulien@owloh.com)
*/
struct IHTTP
{
/// Process a request return value.
virtual void OnRequestComplete(int ticket_id, const Array <char> &data) = 0;
/// Process a request error.
virtual void OnRequestError(int ticket_id) = 0;
/*!
@short Post an asynchronous HTTP request.
This function posts an asynchronous HTTP request and returns a ticket
id to the caller. When task result is available the OnRequestComplete
or OnRequestError handler functions will be called.
*/
virtual int Post(const char *url, const char *post) = 0;
/// Process pending event dispatch in the caller thread.
virtual void Update() = 0;
virtual ~IHTTP() {}
};
} // HTTP
} // GS
#endif // __HTTPINTERFACE__

View File

@ -0,0 +1,136 @@
/* -----------------------------------------------------------------------------
GSFramework
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
----------------------------------------------------------------------------- */
#ifndef __INPUT_DEVICE__
#define __INPUT_DEVICE__
#include "ntypes.h"
#include "memory/nshared_ptr.h"
namespace GS {
namespace Input {
/*
@short Input device.
@author Emmanuel Julien (ejulien@nworks.fr)
*/
class Device : public SharedObject
{
public:
enum Type
{
Type_Any = 0, Type_Keyboard, Type_Mouse, Type_Pad, Type_Touch
};
// Binary value.
enum KeyCode
{
Key_None = 0,
// Keyboard.
Key_LShift, Key_RShift, Key_LCtrl, Key_RCtrl, Key_LAlt, Key_RAlt, Key_LWin, Key_RWin,
Key_Tab, Key_CapsLock, Key_Space, Key_Backspace, Key_Insert, Key_Suppr, Key_Home, Key_End, Key_PageUp, Key_PageDown,
Key_Up, Key_Down, Key_Left, Key_Right,
Key_Escape,
Key_F1, Key_F2, Key_F3, Key_F4, Key_F5, Key_F6, Key_F7, Key_F8, Key_F9, Key_F10, Key_F11, Key_F12,
Key_PrintScreen, Key_ScrollLock, Key_Pause, Key_NumLock, Key_Return,
Key_Numpad0, Key_Numpad1, Key_Numpad2, Key_Numpad3, Key_Numpad4, Key_Numpad5, Key_Numpad6, Key_Numpad7, Key_Numpad8, Key_Numpad9,
Key_Add, Key_Sub, Key_Mul, Key_Div, Key_Enter,
Key_A, Key_B, Key_C, Key_D, Key_E, Key_F, Key_G, Key_H, Key_I, Key_J, Key_K, Key_L, Key_M, Key_N, Key_O, Key_P, Key_Q, Key_R, Key_S, Key_T, Key_U, Key_V, Key_W, Key_X, Key_Y, Key_Z,
// Mouse/pad.
Key_Button0, Key_Button1, Key_Button2, Key_Button3, Key_Button4, Key_Button5, Key_Button6, Key_Button7, Key_Button8, Key_Button9,
Key_Button10, Key_Button11, Key_Button12, Key_Button13, Key_Button14, Key_Button15, Key_Button16, Key_Button17, Key_Button18, Key_Button19,
Key_Button20, Key_Button21, Key_Button22, Key_Button23, Key_Button24, Key_Button25, Key_Button26, Key_Button27, Key_Button28, Key_Button29,
Key_Button30, Key_Button31, Key_Button32, Key_Button33, Key_Button34, Key_Button35, Key_Button36, Key_Button37, Key_Button38, Key_Button39,
Key_Button40, Key_Button41, Key_Button42, Key_Button43, Key_Button44, Key_Button45, Key_Button46, Key_Button47, Key_Button48, Key_Button49,
Key_Button50, Key_Button51, Key_Button52, Key_Button53, Key_Button54, Key_Button55, Key_Button56, Key_Button57, Key_Button58, Key_Button59,
Key_Button60, Key_Button61, Key_Button62, Key_Button63, Key_Button64, Key_Button65, Key_Button66, Key_Button67, Key_Button68, Key_Button69,
Key_Button70, Key_Button71, Key_Button72, Key_Button73, Key_Button74, Key_Button75, Key_Button76, Key_Button77, Key_Button78, Key_Button79,
Key_Button80, Key_Button81, Key_Button82, Key_Button83, Key_Button84, Key_Button85, Key_Button86, Key_Button87, Key_Button88, Key_Button89,
Key_Button90, Key_Button91, Key_Button92, Key_Button93, Key_Button94, Key_Button95, Key_Button96, Key_Button97, Key_Button98, Key_Button99,
Key_Button100, Key_Button101, Key_Button102, Key_Button103, Key_Button104, Key_Button105, Key_Button106, Key_Button107, Key_Button108, Key_Button109,
Key_Button110, Key_Button111, Key_Button112, Key_Button113, Key_Button114, Key_Button115, Key_Button116, Key_Button117, Key_Button118, Key_Button119,
Key_Button120, Key_Button121, Key_Button122, Key_Button123, Key_Button124, Key_Button125, Key_Button126, Key_Button127,
Key_Back, Key_Start, Key_Select, Key_L1, Key_L2, Key_L3, Key_R1, Key_R2, Key_R3,
Key_Cross_Up, Key_Cross_Down, Key_Cross_Left, Key_Cross_Right,
Key_Last
};
// Ranged-value.
enum InputCode
{
Input_None = 0,
Input_AxisX, Input_AxisY, Input_AxisZ, Input_AxisS, Input_AxisT, Input_AxisR,
Input_RotX, Input_RotY, Input_RotZ, Input_RotS, Input_RotT, Input_RotR,
Input_Button0, Input_Button1, Input_Button2, Input_Button3, Input_Button4, Input_Button5, Input_Button6, Input_Button7, Input_Button8, Input_Button9, Input_Button10, Input_Button11, Input_Button12, Input_Button13, Input_Button14, Input_Button15
};
// Input semantics.
enum InputSemantic
{
// Mouse semantics.
Semantic_LeftMouseButton, Semantic_RightMouseButton, Semantic_MiddleMouseButton,
Semantic_MouseAxisX, Semantic_MouseAxisY, Semantic_MouseWheel,
// Touch semantic.
Semantic_TouchPressure, Semantic_TouchAxisX, Semantic_TouchAxisY,
// Pad semantics.
Semantic_StartButton, Semantic_SelectButton
};
enum Effect
{
Vibrate, VibrateLeft, VibrateRight,
ConstantForce
};
/// Get device type.
virtual Type GetType() const = 0;
/// Get device name.
virtual const char *GetName() const = 0;
/// Pool state and refresh values.
virtual void Update() = 0;
/// Is device valid.
virtual bool IsValid() const { return true; }
/// Get input from semantic.
virtual InputCode GetInputFromSemantic(InputSemantic) { return Input_None; }
/// Test a key state.
virtual bool IsDown(KeyCode) const { return false; }
/// Test a key state during the previous update.
virtual bool WasDown(KeyCode) const { return false; }
/// Get input range.
virtual bool GetInputRange(InputCode, float &min, float &max) const { return false; }
/// Get input value.
virtual float GetValue(InputCode) const { return 0; }
/// Get input value during last update.
virtual float GetLastValue(InputCode) const { return 0; }
/// Set input value, return true if the device supports setting this value.
virtual bool SetValue(InputCode, float) { return false; }
/// Set device effect.
virtual void SetEffect(Effect effect, float v) {}
bool WasPressed(KeyCode key) const
{ return !WasDown(key) && IsDown(key); }
};
} // Input
} // GS
#endif // __INPUT_DEVICE__

View File

@ -0,0 +1,45 @@
/* -----------------------------------------------------------------------------
GSFramework
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
----------------------------------------------------------------------------- */
#ifndef __KEYBOARD_INPUT__
#define __KEYBOARD_INPUT__
#include "input/input_device.h"
namespace GS {
namespace Input {
/*
@short Keyboard input device.
@author Emmanuel Julien (ejulien@nworks.fr)
*/
class Keyboard : public Device
{
protected:
bool is_down[Key_Last],
was_down[Key_Last];
public:
virtual Type GetType() const { return Type_Keyboard; }
virtual const char *GetName() const { return "Keyboard"; }
virtual void Update() = 0;
virtual bool IsDown(KeyCode k) const { return is_down[k]; }
virtual bool WasDown(KeyCode k) const { return was_down[k]; }
Keyboard();
};
} // Input
} // GS
#endif // __KEYBOARD_INPUT__

View File

@ -0,0 +1,56 @@
/* -----------------------------------------------------------------------------
GSFramework
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
----------------------------------------------------------------------------- */
#ifndef __INPUT_MOUSE__
#define __INPUT_MOUSE__
#include "input/input_device.h"
namespace GS {
namespace Input {
/*
@short Mouse input device.
@author Emmanuel Julien (ejulien@nworks.fr)
*/
class Mouse : public Device
{
protected:
struct State
{
float x, y, wheel, hwheel;
bool left_button, right_button, middle_button;
};
State state,
last_state;
public:
virtual Type GetType() const { return Type_Mouse; }
virtual const char *GetName() const { return "mouse"; }
virtual void Update() = 0;
virtual bool IsDown(KeyCode) const;
virtual bool WasDown(KeyCode) const;
virtual bool GetInputRange(InputCode, float &min, float &max) const;
virtual float GetValue(InputCode) const;
virtual float GetLastValue(InputCode) const;
Mouse();
};
} // Input
} // GS
#endif // __INPUT_MOUSE__

View File

@ -0,0 +1,45 @@
/* -----------------------------------------------------------------------------
GSFramework
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
----------------------------------------------------------------------------- */
#ifndef __INPUT_NULL_DEVICE__
#define __INPUT_NULL_DEVICE__
#include "input/input_device.h"
namespace GS {
namespace Input {
/*
@short Null input device.
@author Emmanuel Julien (ejulien@nworks.fr)
*/
class NullDevice : public Device
{
public:
virtual Type GetType() const
{ return Type_Any; }
virtual const char *GetName() const
{ return "Null"; }
virtual void Update() {}
virtual bool IsDown(KeyCode) const { return false; }
virtual bool WasDown(KeyCode) const { return false; }
virtual bool GetInputRange(InputCode, float &min, float &max) const { return false; }
virtual float GetValue(InputCode) const { return 0; }
virtual float GetLastValue(InputCode) const { return 0; }
};
} // Input
} // GS
#endif // __INPUT_NULL_DEVICE__

View File

@ -0,0 +1,51 @@
/* -----------------------------------------------------------------------------
GSFramework
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
----------------------------------------------------------------------------- */
#ifndef __INPUT_SYSTEM__
#define __INPUT_SYSTEM__
#include "input/input_device.h"
#include "nstring/nstring.h"
#include "container/nlist.h"
namespace GS {
namespace Input {
/*
@short Input system.
@author Emmanuel Julien (ejulien@nworks.fr)
*/
struct System
{
/// Return true if the input system is active.
virtual bool IsActive() { return true; }
virtual void Update() = 0;
/// Return the current display handle.
virtual void *GetHandle() const { return 0; }
/// Set display handle.
virtual void SetHandle(void *) {}
/// Return a list of devices available on this system.
virtual bool GetDeviceList(StringList &, Device::Type = Device::Type_Any) const { return true; }
/// Return a list of guid devices available on this system.
virtual bool GetDeviceGuidList(StringList &, Device::Type = Device::Type_Any) const { return true; }
/// Get a device from its name.
virtual Device *GetDevice(const char *name) = 0;
virtual Device *GetDeviceFromGuid(const char *name) {return NULL;};
virtual ~System() {}
};
} // Input
} // GS
#endif // __INPUT_SYSTEM__

View File

@ -0,0 +1,59 @@
/* -----------------------------------------------------------------------------
GSFramework
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
----------------------------------------------------------------------------- */
#ifndef __INPUT_TOUCH__
#define __INPUT_TOUCH__
#include "input/input_device.h"
namespace GS {
namespace Input {
/*
@short Touch input device.
@author Emmanuel Julien (ejulien@nworks.fr)
*/
class TouchDevice : public Device
{
protected:
struct State
{
float x, y;
bool button;
};
int index;
State state, last_state, pending_state;
public:
virtual Type GetType() const;
virtual const char *GetName() const;
virtual void Update();
virtual bool IsDown(KeyCode) const;
virtual bool WasDown(KeyCode) const;
virtual bool GetInputRange(InputCode, float &min, float &max) const;
virtual float GetValue(InputCode) const;
virtual float GetLastValue(InputCode) const;
void SetIndex(int);
void RegisterTouchEvent(float x, float y, float weight);
TouchDevice(int index = -1);
};
} // Input
} // GS
#endif // __INPUT_TOUCH__

View File

@ -0,0 +1,30 @@
/* -----------------------------------------------------------------------------
GSFramework
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
----------------------------------------------------------------------------- */
#ifndef __LICENSING__
#define __LICENSING__
namespace GS {
/*!
@short License system interface.
@author Emmanuel Julien (ejulien@owloh.com)
*/
struct ILicensing
{
// Event handler for the license system.
virtual void onLicensingEvent(const char *) = 0;
/// Request an update of the application license.
virtual bool updateLicence(const char *) = 0;
virtual ~ILicensing() {}
};
} // GS
#endif // __LICENSING__

View File

@ -0,0 +1,37 @@
/* -----------------------------------------------------------------------------
GSFramework
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
----------------------------------------------------------------------------- */
#ifndef __NCOUNTRY__
#define __NCOUNTRY__
#include "nstring/nstring.h"
namespace GS {
namespace Locale {
struct Info
{
String continent, region, country, fips, iso2, iso3;
int iso;
String internet;
};
// FIPS 10-4: American National Standard Codes for the Representation of Names of Countries, Dependencies, and Areas of Special Sovereignty for Information Interchange.
const Info *GetFIPSCountry(const char *);
// ISO 3166: Two-character.
const Info *GetISO2Country(const char *);
// ISO 3166: Three-character.
const Info *GetISO3Country(const char *);
// ISO 3166: Three-digit.
const Info *GetISOCountry(int);
} // Locale
} // GS
#endif // __NCOUNTRY__

View File

@ -0,0 +1,38 @@
/* -----------------------------------------------------------------------------
GSFramework
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
----------------------------------------------------------------------------- */
#ifndef __NFILELOG__
#define __NFILELOG__
#include "nstring/nstring.h"
#include "log/log.h"
namespace GS {
/*!
@short File log.
@author Emmanuel Julien (ejulien@gsworks.fr)
*/
class FileLog : public Log
{
String path;
bool do_timestamp;
bool initial_write;
public:
virtual void NewLog(const char *log, char entry_level = EngineLogStandard);
FileLog(const char *path, bool do_timestamp = false);
};
} // GS
#endif // __NFILELOG__

137
include/platform/log/log.h Normal file
View File

@ -0,0 +1,137 @@
/* -----------------------------------------------------------------------------
GSFramework
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
----------------------------------------------------------------------------- */
#ifndef __NLOG__
#define __NLOG__
#include "ntypes.h"
#include "memory/singleton.h"
#include "memory/nauto_ptr.h"
namespace GS {
class String;
namespace Threading { class Mutex; }
/*!
Define the maximum log line length.
*/
#define LOG_LINE_MAX_LEN 8192
/*!
@short Log.
The log subsystem provides several log levels to enable activation and
deactivation of a whole log level.
The following log streams are available to log to the different levels:
* __LOG_H__: Header (eg: __LOG_H__ << "Physics entry point.\n")
* __LOG_W__: Warning
* __LOG_E__: Error
* __LOG_E__: Non-maskable
Standard logs may be output to the __LOG__ stream.
@author Emmanuel Julien (ejulien@gsworks.fr)
*/
class Log
{
protected:
Threading::Mutex *mutex;
#if __PLATFORM_LOG_SUPPORT__
char full_a[LOG_LINE_MAX_LEN], full_b[LOG_LINE_MAX_LEN];
char *a, *b;
#endif
#define EngineLogNone 0 ///< Log no log ouput
#define EngineLogStandard 1
#define EngineLogHeader 2
#define EngineLogWarning 4
#define EngineLogError 8
#define EngineLogVerbose 16
#define EngineLogScript 32
#define EngineLogAll ~0
uint log_level;
public:
/// Set the log level.
void SetLogLevel(uint level = EngineLogAll)
{ log_level = level; }
/// Get the current log level.
uint GetLogLevel() const
{ return log_level; }
/// Get the log mutex.
Threading::Mutex &GetMutex()
{ return *mutex; }
Log &operator << (const char);
Log &operator << (const short);
Log &operator << (const int);
Log &operator << (const uchar);
Log &operator << (const ushort);
Log &operator << (const uint);
#if __PLATFORM_IOS__
Log &operator << (const size_t);
#endif
Log &operator << (const float);
Log &operator << (const bool);
Log &operator << (const void *);
Log &operator << (const char *);
Log &operator << (const String &);
void LogProcessed();
/// Implement to receive new log lines.
virtual void NewLog(const char *log, char entry_level = EngineLogStandard);
Log();
virtual ~Log();
};
/// Log system.
class LogSystem : public Singleton <LogSystem>
{
Log *log;
public:
/// Set the log object.
void SetLog(Log *log = 0);
/// Get the current log object.
Log &GetLog();
LogSystem();
};
//------------------------------------------------------------------------------
#define __LOG__ GS::LogSystem::Get().GetLog() // Standard
#define __LOG_H__ __LOG__ << "[H] " // Header
#define __LOG_CAM__ __LOG__ << "[WEBCAM] " // Header
#if 0
#define __LOG_W__ __LOG__ << "[*] " << __FUNCTION__ << " (" << __FILE__ << ":" << __LINE__ << ") " // Warning
#define __LOG_E__ __LOG__ << "[!] " << __FUNCTION__ << " (" << __FILE__ << ":" << __LINE__ << ") " // Error
#else
#define __LOG_W__ __LOG__ << "[*] "
#define __LOG_E__ __LOG__ << "[!] "
#endif
#define __LOG_V__ __LOG__ << "[V] " // Verbose
#define __LOG_F__ __LOG__ << __FUNCTION__ << ": "
#define __LOG_FUNC__ __LOG_V__ << __FUNCTION__ << "\n";
//------------------------------------------------------------------------------
} // GS
#endif // __NLOG__

View File

@ -0,0 +1,26 @@
/* -----------------------------------------------------------------------------
GSFramework
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
----------------------------------------------------------------------------- */
#ifndef __NLOGSCOPE__
#define __NLOGSCOPE__
namespace GS {
class LogScope
{
const char *exit;
public:
LogScope(const char *enter, const char *exit);
~LogScope();
};
} // GS
#endif // __NFILELOG__

View File

@ -0,0 +1,78 @@
/* -----------------------------------------------------------------------------
GSFramework
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
----------------------------------------------------------------------------- */
#ifndef __NMATH__
#define __NMATH__
#include "unit/nunit.h"
/*
@short Math namespace.
@author Emmanuel Julien (ejulien@gsworks.fr)
*/
namespace GS {
namespace Math {
static const float Pi = 3.1415926535f;
/// Euler angles rotation order.
enum rOrder
{
rOrder_ZYX = 0,
rOrder_YZX,
rOrder_ZXY,
rOrder_XZY,
rOrder_YXZ,
rOrder_XYZ,
rOrder_XY,
rOrder_Default = rOrder_YXZ // Y then X then Z.
};
enum Axis
{
AxisX, // Do not modify X, Y and Z order.
AxisY,
AxisZ,
AxisNone
};
void Init();
/// Return the reverse rotation order from a given input order.
rOrder ReverserRotationOrder(rOrder r);
float Sqrt(float v);
float TestEqual(float a, float b, float e = 0.000001f);
bool EqualZero(float v, float e = 0.000001f);
float Pow(float v, float exp);
float Ceil(float);
float Floor(float);
float Mod(float);
float RangeAdjust(float v, float old_min, float old_max, float new_min, float new_max);
float Quantize(float v, float q);
float Sin(float);
float ASin(float);
float Cos(float);
float ACos(float);
float Tan(float);
float ATan(float);
bool IsFinite(float);
} // Math
} // GS
#endif // __NMATH__

View File

@ -0,0 +1,49 @@
/* -----------------------------------------------------------------------------
GSFramework
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
----------------------------------------------------------------------------- */
#ifndef __NRANGE__
#define __NRANGE__
#include "math/nrange.h"
namespace GS {
/*!
@short Range.
@author Emmanuel Julien (ejulien@gsworks.fr)
*/
template <class T> struct Range
{
T start, end;
T valueRange() const { return end - start; }
bool inRange(const T &v) const { return (start < end) ? ((v >= start) && (v < end)) : ((v >= end) && (v < start)); }
void sort() { if (start > end) { T t = start; start = end; end = t; } }
static Range Intersection(const Range <T> &a, const Range <T> &b)
{
if ((a.end < b.start) || (a.start > b.end))
return Range <T> ();
return Range(a.start > b.start ? a.start : b.start, a.end < b.end ? a.end : b.end);
}
static Range Union(const Range &a, const Range &b)
{ return Range(a.start < b.start ? a.start : b.start, a.end > b.end ? a.end : b.end); }
void Set(const T &s, const T &e) { start = s; end = e; }
template <class N> Range <N> convert() const
{ return Range <N> (N(start), N(end)); }
Range(const T &s, const T &e) : start(s), end(e) {}
Range() : start(0), end(0) {}
};
} // GS
#endif // __NRANGE__

View File

@ -0,0 +1,60 @@
/* -----------------------------------------------------------------------------
GSFramework
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
----------------------------------------------------------------------------- */
#ifndef __NBITFIELD__
#define __NBITFIELD__
#include "ntypes.h"
namespace GS {
class BitField
{
uint v;
public:
BitField &operator &= (uint b) { v &= b; return *this; }
BitField &operator |= (uint b) { v |= b; return *this; }
BitField &operator = (uint b) { v = b; return *this; }
BitField &operator &= (const BitField &b) { v &= b.v; return *this; }
BitField &operator |= (const BitField &b) { v |= b.v; return *this; }
BitField &operator = (const BitField &b) { v = b.v; return *this; }
bool operator == (const BitField &b) const { return v == b.v; }
bool operator != (const BitField &b) const { return v != b.v; }
inline uint Get() const
{
return v;
}
inline uint Set(uint b)
{
v |= b;
return v;
}
inline uint Remove(uint b)
{
v &= ~b;
return v;
}
inline uint Raise(uint b, bool raise = true)
{
return raise ? Set(b) : Remove(b);
}
inline bool IsSet(uint b) const { return asbool(v & b); }
BitField() : v(0) {}
};
}
#endif // __NBITFIELD__

View File

@ -0,0 +1,52 @@
/* -----------------------------------------------------------------------------
GSFramework
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
----------------------------------------------------------------------------- */
#ifndef __NENDIAN__
#define __NENDIAN__
#include "ntypes.h"
namespace GS {
namespace Endian {
enum Config
{
Undefined = 0,
Big,
Little,
Motorola = Big,
Intel = Little
};
/// Swap bytes in memory.
void SwapBytes(void *, size_t);
/// Return the current host memory configuration.
Config GetHostConfiguration();
/// Convert a memory block to the host configuration.
void *ToHost(void *, size_t, Config = Big);
/// Convert a value to the host configuration.
template <class T> T ToHost(const T &v, Config cfg = Big)
{
if (GetHostConfiguration() == cfg)
return v;
T host_value = v;
SwapBytes(&host_value, sizeof(T));
return host_value;
}
} // Endian
} // GS
#endif //__NENDIAN__

View File

@ -0,0 +1,36 @@
/* -----------------------------------------------------------------------------
GSFramework
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
----------------------------------------------------------------------------- */
#ifndef __NMEMORY__
#define __NMEMORY__
#include "ntypes.h"
namespace GS {
namespace Memory {
/// Return smallest number of bits that can be used to represent a value.
uchar GetBitCount(int);
/// Return the position in bit of the first non-zero bit.
uchar GetShiftCount(int);
/// Return the number of bit set in a given value.
uchar CountSetBit(int);
void WriteBit(uchar *, uint offset_in_bit, uint bit_count, uint value);
uint ReadBit(uchar *, uint offset_in_bit, uint bit_count);
bool Compare(const void *, const void *, size_t);
void Copy(void *, const void *, size_t);
void Set(void *, char, size_t);
void Fill(void *, const char *pattern, size_t);
} // Memory
} // GS
#endif // __NMEMORY__

View File

@ -0,0 +1,78 @@
/* -----------------------------------------------------------------------------
GSFramework
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
----------------------------------------------------------------------------- */
#ifndef __NAUTO_PTR__
#define __NAUTO_PTR__
#include "alloc/ialloc.h"
#include "billing/billing.h"
namespace GS {
/*!
@short Auto pointer.
@author Emmanuel Julien (ejulien@gsworks.fr)
*/
template <class T> class AutoPtr
{
private:
T *o;
public:
inline operator T*() const
{ return o; }
inline T *c_ptr() const
{ return o; }
inline bool IsNull() const { return o ? false : true; }
inline bool IsValid() const { return o ? true : false; }
T *operator = (T *p)
{
if (o != p)
{
delete(o);
o = p;
}
return o;
}
inline T &operator[] (size_t n) { return o[n]; }
inline bool operator == (const T *p) const
{ return o == p; }
inline bool operator != (const T *p) const
{ return o != p; }
inline T *operator -> () const
{ return o; }
inline T &operator * () const
{ return *o; }
inline T *Detach()
{
T *p = o;
o = 0;
return p;
}
explicit AutoPtr(T *p = 0) : o(p)
{}
~AutoPtr()
{
delete(o);
o = 0;
}
};
} // GS
#endif // __NAUTO_PTR__

View File

@ -0,0 +1,150 @@
/* -----------------------------------------------------------------------------
GSFramework
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
----------------------------------------------------------------------------- */
#ifndef __NSHARED_PTR__
#define __NSHARED_PTR__
#include "thread/atomic_value.h"
namespace GS {
/// Weak reference to a shared object.
class WeakRef
{
friend class SharedObject;
bool is_valid;
Threading::Atomic32 refc;
WeakRef() : is_valid(true) {}
public:
bool IsValid() const { return is_valid; }
int GetRefCount() const { return refc.Get(); }
void AddRef() { refc.Inc(); }
void RemoveRef()
{
if ((refc.Dec() == 0) && !is_valid)
delete this;
}
};
/*!
@short Reference counted object.
@author Emmanuel Julien (ejulien@gsworks.fr)
*/
class SharedObject
{
Threading::Atomic32 refc;
WeakRef *weak_ref;
protected:
virtual ~SharedObject()
{
if (weak_ref)
{
if (weak_ref->refc.Get() == 0)
delete weak_ref;
else
weak_ref->is_valid = false;
}
}
public:
WeakRef *GetWeakRef()
{
if (!weak_ref)
weak_ref = new WeakRef; // TODO have a specialized, fixed pool allocator for these.
return weak_ref;
}
int GetRefCount() const { return refc.Get(); }
void AddRef() { refc.Inc(); }
void RemoveRef()
{
if (refc.Dec() == 0)
{
if (weak_ref)
weak_ref->is_valid = false;
delete this;
}
}
SharedObject() : weak_ref(0) {}
};
/*!
@short Strong smart pointer to a reference counted object.
@author Emmanuel Julien (ejulien@gsworks.fr)
*/
template <class T> class SharedPtr
{
T *rc_o;
public:
inline operator T *() const { return rc_o; }
inline T *c_ptr() const { return rc_o; }
inline bool IsNull() const { return rc_o ? false : true; }
inline bool IsValid() const { return rc_o ? true : false; }
void Init()
{
if (rc_o)
rc_o->AddRef();
}
inline bool operator == (const T *p) const { return rc_o == p; }
inline bool operator != (const T *p) const { return rc_o != p; }
inline bool operator == (T *p) const { return rc_o == p; }
inline bool operator != (T *p) const { return rc_o != p; }
inline bool operator == (const SharedPtr &p) const { return rc_o == p.rc_o; }
inline bool operator != (const SharedPtr &p) const { return rc_o != p.rc_o; }
T *operator = (T *p)
{
if (rc_o != p)
{
if (rc_o)
rc_o->RemoveRef();
rc_o = p;
Init();
}
return p;
}
SharedPtr <T> &operator = (const SharedPtr &p)
{
*this = p.c_ptr();
return *this;
}
inline T *operator -> () const { return rc_o; }
inline T &operator * () const { return *rc_o; }
explicit SharedPtr(T *p) : rc_o(p) { Init(); }
SharedPtr(const SharedPtr &p) : rc_o(p.rc_o) { Init(); }
SharedPtr() : rc_o(0) {}
~SharedPtr()
{
if (rc_o)
rc_o->RemoveRef();
}
};
} // GS
#endif // __NSHARED_PTR__

View File

@ -0,0 +1,101 @@
/* -----------------------------------------------------------------------------
GSFramework
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
----------------------------------------------------------------------------- */
#ifndef __NWEAK_PTR__
#define __NWEAK_PTR__
#include "memory/nshared_ptr.h"
namespace GS {
/*!
@short Weak pointer to a reference counted object.
@author Emmanuel Julien (ejulien@gsworks.fr)
*/
template <class T> class WeakPtr
{
private:
T *rc_o;
WeakRef *wref;
public:
T *c_ptr() const { return wref && wref->IsValid() ? rc_o : 0; }
bool IsValid() const { return wref && wref->IsValid() ? true : false; }
bool IsNull() const { return !IsValid(); }
/// Lock pointed object to a strong pointer.
bool Lock(SharedPtr <T> &p)
{
if (IsNull())
return false;
p = rc_o;
return true;
}
SharedPtr <T> Lock() const { return SharedPtr <T> (IsValid() ? rc_o : 0); }
void Init()
{
if (!rc_o)
wref = 0;
else
{
wref = rc_o->GetWeakRef();
wref->AddRef();
}
}
inline bool operator == (const T *p) const
{ return rc_o == p; }
inline bool operator != (const T *p) const
{ return rc_o != p; }
inline bool operator == (T *p) const
{ return rc_o == p; }
inline bool operator != (T *p) const
{ return rc_o != p; }
inline bool operator == (const WeakPtr &p) const
{ return rc_o == p.rc_o; }
inline bool operator != (const WeakPtr &p) const
{ return rc_o != p.rc_o; }
WeakPtr <T> &operator = (const WeakPtr &p)
{
if (rc_o != p.rc_o)
{
WeakRef *old_wref = wref;
rc_o = p.rc_o;
Init();
if (old_wref)
old_wref->RemoveRef();
}
return *this;
}
inline T *operator -> () const
{ return rc_o; }
inline T &operator * () const
{ return *rc_o; }
WeakPtr(T *p = 0) : rc_o(p) { Init(); }
WeakPtr(const WeakPtr &p) : rc_o(p.rc_o) { Init(); }
WeakPtr(const SharedPtr <T> &p) : rc_o(p.c_ptr()) { Init(); }
~WeakPtr()
{
if (wref)
wref->RemoveRef();
}
};
} // GS
#endif // __NWEAK_PTR__

View File

@ -0,0 +1,80 @@
/* -----------------------------------------------------------------------------
GSFramework
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
----------------------------------------------------------------------------- */
#ifndef __NRINGBUFFER__
#define __NRINGBUFFER__
#include "container/narray.h"
namespace GS {
/*
@short Ring buffer.
@author Emmanuel Julien (ejulien@gsworks.fr)
*/
template <class T> class RingBuffer
{
Array <T> buffer;
uint put, get, usage;
public:
/// Get the maximum number of element in buffer.
uint GetCount() const
{ return buffer.GetCount(); }
/// Number of T left to put in the buffer.
uint GetFree() const
{ return buffer.GetCount() - usage; }
/// Number of T available to get from the buffer.
uint GetUsage() const
{ return usage; }
/// Increment the put pointer, returns true when successful.
bool Produce()
{
if (usage == buffer.GetCount())
return false;
put = (put + 1) % buffer.GetCount();
usage++;
return true;
}
/// Increment the get pointer, returns true when successful.
bool Consume()
{
if (usage == 0)
return false;
get = (get + 1) % buffer.GetCount();
usage--;
return true;
}
/// Retrieve the object at the current get pointer.
T &CurrentGet()
{ return buffer[get]; }
/// Retrieve the object at the current put pointer.
T &CurrentPut()
{ return buffer[put]; }
bool Allocate(uint count)
{
put = get = usage = 0;
return buffer.Allocate(count);
}
RingBuffer() : put(0), get(0), usage(0) {}
};
} // GS
#endif // __NRINGBUFFER__

View File

@ -0,0 +1,28 @@
/* -----------------------------------------------------------------------------
GSFramework
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
----------------------------------------------------------------------------- */
#ifndef __SINGLETON__
#define __SINGLETON__
namespace GS {
template <class T> class Singleton
{
static T *i;
public:
static T &Get() { return *i; }
static void Set(T *s) { i = s; }
static void Free() { delete i; i = nullptr; }
};
}
#endif // __SINGLETON__

View File

@ -0,0 +1,48 @@
/* -----------------------------------------------------------------------------
GSFramework
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
----------------------------------------------------------------------------- */
#ifndef __MESSAGING__
#define __MESSAGING__
#include "container/nlist.h"
namespace GS {
namespace Messaging {
/*!
@short Low-level message broadcasting system.
@author Emmanuel Julien (ejulien@nworks.fr)
*/
template <class Message, class Listener, class From, class Parm = void *> class Broadcaster
{
protected:
/// Message listener list.
List <Listener *> listener_list;
public:
bool RegisterMessageListener(Listener *listener)
{ return listener_list.Add(listener) ? true : false; }
bool UnregisterMessageListener(Listener *listener)
{ return listener_list.Remove(listener); }
virtual void BroadcastMessage(const Message &msg, const From &from, const Parm &parm)
{
ListForeachPtr(Listener *, listener, listener_list)
listener->ProcessMessage(msg, from, parm);
}
virtual ~Broadcaster() {}
};
} // Messaging
} // GS
#endif // __MESSAGING__

View File

@ -0,0 +1,73 @@
/* -----------------------------------------------------------------------------
GSFramework
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
----------------------------------------------------------------------------- */
#ifndef __GSCONFIG__
#define __GSCONFIG__
/// Define to disable all debug/tracking code.
#ifndef __ENGINE_RETAIL__
#define __ENGINE_RETAIL__ 0
#endif
//------------------------------------------------------------------------------
// Engine configuration.
//------------------------------------------------------------------------------
/// Enable logging system support.
#define __PLATFORM_LOG_SUPPORT__ 1
/*!
@short Maximum UV channel count.
This value has no limitation, however try to keep it in a reasonable
range to avoid wasting memory and preserve compatibility.
@note The lowest acceptable value is 1. (Default: 3)
*/
#define __UV_PER_GEOMETRY__ 3
/*!
@short Bone/vertex limit.
*/
#define __PV_BONE_LIMIT__ 4
/*!
@short Bone/list limit.
*/
#define __PL_BONE_LIMIT__ 48
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
// Debug configuration.
//------------------------------------------------------------------------------
#if __ENGINE_RETAIL__
/*
Deactivate unneeded subsystems for a retail build.
*/
#undef __PLATFORM_LOG_SUPPORT__
#define __PLATFORM_LOG_SUPPORT__ 0
#else // __ENGINE_RETAIL__
/*!
@short Define to enable per allocation statistics.
@note All allocations are inflated by a monitoring header.
The allocators are adapted to fit the increased allocations
so that their behavior will not change.
@note A 2 bytes long magic word is added to the end of each allocation
and checked for overrun on release.
*/
#define __ENABLE_ALLOCATION_STAT__ 0
/// Define to enable end of allocation overwrite detection.
#define __ENABLE_ALLOCATION_GUARD__ 0
/// Enable the small block allocator system (ialloc.cpp).
#define __ENABLE_GLOBAL_SBA__ 0
#endif // __ENGINE_RETAIL__
//------------------------------------------------------------------------------
#endif // __GSCONFIG__

View File

@ -0,0 +1,74 @@
/* -----------------------------------------------------------------------------
GSFramework
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
----------------------------------------------------------------------------- */
#ifndef __NETWORK_INTERFACE__
#define __NETWORK_INTERFACE__
#include "container/narray.h"
#include "ntypes.h"
namespace GS {
class String;
namespace Network {
//
struct INetwork
{
enum Timeout
{
TimeoutDefault = 0,
TimeoutLong,
TimeoutVeryLong
};
virtual bool SendString(void *peer, const String &);
virtual bool BroadcastString(const String &);
struct Statistics
{
size_t sent_data;
size_t received_data;
};
virtual void GetStatistics(Statistics &) = 0;
virtual int GetPeerPacketLossRatio(void *peer) = 0;
virtual void OnPeerConnection(void *peer) = 0;
virtual void OnPacketReceived(void *peer, const void *data, size_t size) = 0;
virtual void OnConnectionClosed(void *peer) = 0;
/*!
@name Communication interface.
@{
*/
virtual void UpdateHost() = 0;
virtual bool Send(void *peer, const void *data, size_t size) = 0;
virtual bool Broadcast(const void *data, size_t size) = 0;
/// @}
virtual bool IsOpen() const = 0;
virtual bool GetHostAddress(String &address) = 0;
virtual bool GetPeerAddress(void *peer, String &address) = 0;
virtual void SetPeerTimeout(void *peer, Timeout = TimeoutDefault) = 0;
virtual bool OpenServer(const char *address, int port) = 0;
virtual bool OpenClient(const char *address, int port) = 0;
virtual void Disconnect(void *peer) = 0;
virtual void Close() = 0;
virtual ~INetwork() {}
};
} // Network
} // GS
#endif // __NETWORK_INTERFACE__

View File

@ -0,0 +1,310 @@
/* -----------------------------------------------------------------------------
GSFramework
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
----------------------------------------------------------------------------- */
#ifndef __NSTRING__
#define __NSTRING__
#include <cstring>
#include "container/narray.h"
namespace GS {
template <class T> class List;
template <class T> class Array;
/*!
@short String class.
Strings are internally stored as UTF-8.
@author Emmanuel Julien (ejulien@gsworks.fr)
*/
class String
{
Array <char> _p;
mutable uint hash;
int len;
void Touch();
public:
enum CaseSensitivity
{
CaseSensitive = 0,
CaseInsensitive
};
enum EOLConvention
{
EOLUnix = 0,
EOLWindows
};
/*!
@short Compare string object with a C string
Optionally accept a hash value for the input string.
@return True if strings match.
*/
bool equals(const char *s, const uint hash = 0) const;
bool operator == (const String &) const;
bool operator != (const String &) const;
bool operator == (const char *) const;
bool operator != (const char *) const;
/// Format a string.
static String Format(const char *format, ...);
String operator + (const char *) const;
String operator + (const String &) const;
void operator += (const char *);
void operator += (const String &);
void operator += (float);
void operator += (double);
void operator += (int);
void operator += (uint);
void operator += (bool);
String &operator = (const String &);
String &operator = (const char *);
void Set(const char *s, const char *e = 0);
String &operator << (const String &);
String &operator << (const char *);
String &operator << (float);
String &operator << (double);
String &operator << (int);
String &operator << (uint);
String &operator << (bool);
/// String hash value.
uint Hash() const;
/// String length.
uint Len() const;
/// String size in bytes.
size_t Size() const;
/// Is empty.
inline bool IsEmpty() const { return (!_p || !len) ? true : false; }
/// Normalize the string end of line.
void NormalizeEOL(EOLConvention = EOLUnix);
/// Return a normalized version of this string.
String NormalizedEOL(EOLConvention = EOLUnix) const;
/*!
@name File system tool set.
@{
*/
/// Is absolute path.
bool IsAbsolutePath() const;
String BeautifyFileName(bool allow_spaces = true) const;
String CleanFilePath() const;
String CutFilePath() const;
String CutFileName() const;
String CutFileExtension() const;
String GetFilePath() const;
String GetFileName() const;
String GetFileNameAndExtension() const;
String GetFileExtension() const;
/// Return this filename with another file extension.
String GetSwappedExtension(const char *) const;
void FileCutPath();
void FileSwapExtension(const char *);
void FileCutPathAndExtension();
void FileCutExtension();
void FileCutName();
/// Get extension.
static String FileGetExtension(const char *path);
/// Convert backslash to slash, merge redundant slash.
bool FileCleanName();
/// @}
/// Return as utf-8 ASCII C string.
inline operator const char *() const { return _p; }
/// Return as utf-8 ASCII C string.
inline const char *c_str() const { return _p; }
inline char *str() const { return _p; }
/// Return a pointer to the end of the string.
inline const char *eos() const { return _p + Len(); }
/*!
@name Unicode tool set.
@{
*/
/// Convert an utf-8 character to utf-32, returns the number of consumed bytes.
static size_t Utf8toUtf32(const uchar *utf8, uint *utf32);
/// Get utf-8 character size in byte.
static size_t GetUtf8CharSize(const uchar *utf8);
/// Create a string from a UCS-2 buffer.
static String FromUcs2(const ushort *);
/// Return as utf-8
inline const char *toUtf8() const { return _p; }
/// Return string as UCS-2 (utf-16 compatible up to code point 0xffff).
Array <ushort> toUcs2() const;
/// Return string as utf-32.
Array <uint> toUtf32() const;
/// @}
/// Remove all occurrences of a given character from the string.
String TrimChar(char);
/// ASCII to float.
inline float Float(bool support_comma = true) const { return atof(_p, _p + Len(), support_comma); }
/// ASCII to integer.
inline int Integer() const { return atoi(_p); }
/// ASCII header less, 0x or h prefixed hexadecimal to integer.
inline int Hex() const { return atoh(_p); }
/// Split string against a separator string.
template <class C> uint Split(const char *separator, C &container, const char skip = 0) const
{
const char *s = c_str();
if (!s)
return 0;
size_t ls = strlen(separator);
for (const char *n = s; s[0]; s = n)
{
// Check the skip char.
if (skip && (n[0] == skip))
for (++n; n[0] && (n[0] != skip); ++n)
;
// Seek the next separator occurrence.
while (n[0] && (strncmp(n, separator, ls) != 0))
++n;
// Append sub-string.
if (skip)
container.Add(String(s, n).TrimChar(skip));
else
container.Add(String(s, n));
if (!n[0])
break;
n += ls;
}
return container.GetCount();
}
/// Get a slice of the string starting at s ending at e.
String Slice(uint s, uint e) const;
bool Compare(const char *, CaseSensitivity = CaseSensitive) const;
/// Test if the string starts with another string.
bool StartsWith(const char *, CaseSensitivity = CaseSensitive) const;
/// Test if the string ends with another string.
bool EndsWith(const char *, CaseSensitivity = CaseSensitive) const;
/// Test if the string contains another string.
bool Contains(const char *, CaseSensitivity = CaseSensitive) const;
String Upper() const;
String Lower() const;
/// Get the n leftmost characters from the string.
String Left(uint n) const;
/// Get the n rightmost characters from the string.
String Right(uint n) const;
/// Get 'n' characters starting at p from the string.
String Mid(uint p, int n = -1) const;
/// Return the index of a specific character in string, starting at p.
size_t IndexOf(char c, uint p = 0) const;
/// Return the address of a substring in string, starting at p.
char *FindString(const char *c, uint p = 0, CaseSensitivity = CaseSensitive) const;
bool Replace(const char *what, const char *by, CaseSensitivity cs = CaseSensitive);
bool ReplaceAll(const char *what, const char *by, bool match_whole_word = false);
bool ReplaceAll(const char **what, const char **by, bool match_whole_word = false);
static const char *LocatePattern(const char *s, const char *format, const char **e = 0);
bool Extract(const char *format, List <String> &arg);
typedef String RewriteFunc(const char *pattern, List <String> &arg);
static String RewritePatternAll(const char *p, const char *pattern, RewriteFunc &rewrite_func);
/*!
@short C string library.
@{
*/
/// Compare two strings, returns -1 if b < a, 0 if a == b, 1 if b > a.
static int Compare(const String &a, const String &b);
/*!
@short Returns the address where a given character can be found.
Returns the address where a given character can be found inside the
memory block starting at 'from' and ending at 'to'.
*/
static char *strfindchar(const char *from, const char c, const char *to = 0);
/*!
@short Compare the shortest C string with the other C string.
Returns false if matching. (eg: 'fore' and 'foremost' do match).
*/
static bool strccmp(const char *, const char *);
/// Compute string hash value.
static uint strhash(const char *);
/// Compute string length.
static size_t strlen(const char *);
/// Remove path.
static void rmpath(char *);
/// Remove extension.
static void rmext(char *);
/// Remove path and extension.
static void rmpathext(char *);
/// Remove filename.
static void rmname(char *);
/// Integer to ASCII.
static char *itoa(int);
/// ASCII to float.
static float atof(const char *s, const char *e = 0, bool support_comma = true);
/// ASCII to integer.
static int atoi(const char *s);
/// ASCII header-less, 0x or h prefixed hexadecimal to integer.
static int atoh(const char *s);
/// @}
//-------------------------------------------------------------------
/*!
@short Reserve space on the string for a number of characters.
@note An extra byte will be allocated to store the string terminator.
*/
bool Allocate(uint size);
void Clear();
String(const char *s) : _p(Alloc::StringBuffer) { Clear(); *this = s; }
String(const String &b) : _p(Alloc::StringBuffer) { Clear(); *this = b.c_str(); }
String(const char *s, const char *e) : _p(Alloc::StringBuffer) { Clear(); Set(s, e); }
String(const char *s, size_t l) : _p(Alloc::StringBuffer) { Clear(); Set(s, s + l); }
String() : _p(Alloc::StringBuffer) { Clear(); }
~String() { Clear(); }
};
typedef List <String> StringList;
} // GS
#endif // __NSTRING__

113
include/platform/ntypes.h Normal file
View File

@ -0,0 +1,113 @@
/* -----------------------------------------------------------------------------
GSFramework
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
----------------------------------------------------------------------------- */
#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>
#ifndef __NTYPES__
#define __NTYPES__
#include "nconfig.h"
#if __PLATFORM_ANDROID_NDK__ || __PLATFORM_IOS__ || __PLATFORM_POSIX__
#include <stddef.h>
#include <stdint.h>
#endif
/*!
@short __float32 is expected to be 4 byte float.
Platform with no such type will need to port code dependent on this type.
*/
typedef float __float32;
typedef unsigned char uchar;
typedef signed char schar;
typedef unsigned short ushort;
typedef unsigned int uint;
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
namespace GS {
namespace Types {
template <class T> T inline Abs(T v) { return v < 0 ? -v : v; }
template <class T> T inline Min(T a, T b) { return a < b ? a : b; }
template <class T> T inline Max(T a, T b) { return a > b ? a : b; }
template <class T> T inline Clamp(T v, T min = 0, T max = 1) { return v < min ? min : (v > max ? max : v); }
template <class T> T inline Wrap(T v, T range_start, T range_end)
{
const T dt = range_end - range_start + 1;
while (v < range_start)
v += dt;
while (v > range_end)
v -= dt;
return v;
}
template <class T> void inline swap(T &a, T&b) { T t = b; b = a; a = t; }
uint getPOT(uint v);
bool isPOT(uint v);
} // Types
} // GS
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
#if defined(__PLATFORM_WINDOWS__)
#define GSEXPORT __declspec(dllexport)
#define GSRESTRICT __restrict
#else
#define GSRESTRICT
#endif
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
// Helper macros.
//------------------------------------------------------------------------------
#if __PLATFORM_LOG_SUPPORT__
#define __ERR__(err_exp, ret_exp) { (err_exp); return (ret_exp); }
#define __ERRRAW__(err_exp) { (err_exp); return; }
#else
#define __ERR__(err_exp, ret_exp) { return (ret_exp); }
#define __ERRRAW__(err_exp) { return; }
#endif
#define nUnused(__P__)
#ifndef NULL
#define NULL 0
#endif
#ifndef forever
#define forever for(;;)
#endif
#define asbool(v) ((v) ? true : false)
template <class T> inline bool _cached_value_test_and_synch(T &cached, const T &value)
{ bool r = cached != value; cached = value; return r; }
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
// Disable unwanted warnings.
//------------------------------------------------------------------------------
#if _MSC_VER
// int to float.
#pragma warning(disable : 4100)
// CRT.
#pragma warning(disable : 4996)
// empty controlled statement found.
#pragma warning(disable : 4390)
#endif
//------------------------------------------------------------------------------
#endif // __NTYPES__

128
include/platform/platform.h Normal file
View File

@ -0,0 +1,128 @@
/* -----------------------------------------------------------------------------
GSFramework
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
----------------------------------------------------------------------------- */
#ifndef __PLATFORM__
#define __PLATFORM__
#include "memory/nauto_ptr.h"
#include "memory/singleton.h"
#include "filesystem/filesystem.h"
#include "input/input_system.h"
#include "async/job.h"
#include "signal/signal.h"
#include "licensing/licensing.h"
#include "analytics/analytics.h"
#include "billing/billing.h"
#include "time/ntime.h"
namespace GS {
struct ISharedLib;
/*!
@short Platform interface.
@author Emmanuel Julien (ejulien@owloh.com)
*/
class Platform : public Singleton <Platform>
{
bool initialized;
public:
/// Initialize platform.
virtual void Initialize();
AutoPtr <ASync::JobManager> job_manager;
AutoPtr <IO::Filesystem> io;
AutoPtr <IBilling> billing;
AutoPtr <IAnalytics> analytics;
AutoPtr <ILicensing> licensing;
AutoPtr <Input::System> input_system;
// Platform signals.
struct Signals
{
Signal <void> renderer_output_closed;
};
Signals signal;
/// Return the platform name.
virtual String GetName() const = 0;
/// Return the device name the platform is running on.
virtual String GetDeviceName() const = 0;
/// Get the platform locale as an ISO3166 code.
virtual String GetLocale() = 0;
/// Return the number of logical thread available.
virtual int GetSystemThreadCount() { return 1; }
/// Return the number of physical processor core available.
virtual int GetSystemCoreCount() { return 1; }
/// Open a given URL using the platform integrated browser.
virtual bool OpenURL(const char *) { return false; }
/// Open the application page.
virtual bool OpenAppPage() { return false; }
/// Send to background.
virtual bool SendToBackground(bool kill = false) { return false; }
/// Return the current user directory.
virtual bool GetUserDir(String &, const char *user = 0) { return false; }
/// Output a program trace to the platform log.
virtual void Trace(const char *trace, const char *source, int line);
/*!
@name Application
@{
*/
static String app_dir;
virtual String GetAppPluginPath(const char *) const;
/// @}
/*!
@name Timer subsystem.
@{
*/
/// Get the platform clock.
virtual Time GetTime() = 0;
/// Return the system clock frequency.
virtual int GetClockFrequency() = 0;
/// Return the current clock.
virtual int GetClock() = 0;
/// Sleep platform for 'n' milliseconds.
virtual void Sleep(uint ms) = 0;
int GetStartClock() const;
Time GetStartTime() const;
/// System clock unit macros.
int GetSecond(int t) { return t * GetClockFrequency(); }
int GetMinute(int t) { return t * 60 * GetClockFrequency(); }
/// @}
/// Load a shared library.
virtual ISharedLib *LoadSharedLibrary(const char *) { return 0; }
Platform();
virtual ~Platform() {}
};
} // GS
#ifdef _DEBUG
#define __NTRACE(T) { GS::Platform::Get().Trace(T, __FILE__, __LINE__); }
#else
#define __NTRACE(T) ;
#endif
#endif // __PLATFORM__

View File

@ -0,0 +1,40 @@
/* -----------------------------------------------------------------------------
GSFramework
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
----------------------------------------------------------------------------- */
#ifndef __KERNEL_CONFIG__
#define __KERNEL_CONFIG__
#include "assert/nassert.h"
#if __PLATFORM_WINDOWS__
#define strupr _strupr
#define strlwr _strlwr
#elif __PLATFORM_POSIX__
#include <stdint.h>
#include <alloca.h>
#define _snprintf snprintf
#elif __PLATFORM_NINTENDO_WII__
#include <revolution.h>
using namespace std;
#define _snprintf snprintf
#elif SN_TARGET_PS3
#define _snprintf snprintf
#endif
#endif // __KERNEL_CONFIG__

View File

@ -0,0 +1,55 @@
/* -----------------------------------------------------------------------------
GSFramework
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
----------------------------------------------------------------------------- */
#ifndef __NRAND__
#define __NRAND__
#include "ntypes.h"
namespace GS {
namespace Random {
#ifndef RAND_MAX
#define RAND_MAX 0x7fff
#endif
/*!
@short A random number generator class.
@note The maximum precision of this generator is fixed to 16bit integer.
This means that you cannot get, even with floats, more than 65536
different values. But this generator has, of course, no query
limit.
@author Emmanuel Julien (ejulien@gsworks.fr)
*/
/// Set the starting seed of the random number generator.
void Seed(uint s);
/// Return an integer random number in the range [0;r] (default [0;RAND_MAX].
uint Rand(uint r = RAND_MAX);
/// Return a float random value in the range [0;r] (default [0;1]).
float FRand(float r = 1.0f);
/// Return a float random value un the range [lo, hi] (default [-1, 1]).
float FRRand(float lo = -1, float hi = 1);
/*!
@short Pseudo-unique random number generator.
A random number generator that tries to feed a different number
than what was returned at the previous call.
This class is a wrapper for Rand().
@note The number 'might' still be the same.
*/
uint CRand(uint r = RAND_MAX);
} // Random
} // GS
#endif // __NRAND__

View File

@ -0,0 +1,44 @@
/* -----------------------------------------------------------------------------
GSFramework
Copyright 2001-2011 Emmanuel Julien. All Rights Reserved.
----------------------------------------------------------------------------- */
#ifndef __NREFL_OBJECT__
#define __NREFL_OBJECT__
#include <stddef.h>
#include "reflection/nenum_string.h"
namespace GS {
namespace Reflection {
struct Property
{
enum PropType
{
InvalidProp,
BoolProp,
CharProp,
ShortProp,
IntProp,
FloatProp,
StringProp,
EnumProp
};
PropType type;
const char *name;
size_t offset_of;
Enum::Dict *enum_dict;
};
} // Reflection
} // GS
#endif // __NREFL_OBJECT__

View File

@ -0,0 +1,30 @@
/* -----------------------------------------------------------------------------
GSFramework
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
----------------------------------------------------------------------------- */
#ifndef __NENUM_STRING__
#define __NENUM_STRING__
namespace GS {
namespace Reflection {
struct Enum
{
struct Dict
{
int enum_v;
const char *string_v;
};
static const char *toString(int, Dict *);
static int fromString(const char *, Dict *);
};
} // Reflection
} // GS
#endif // __NENUM_STRING__

View File

@ -0,0 +1,32 @@
/* -----------------------------------------------------------------------------
GSFramework
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
----------------------------------------------------------------------------- */
#ifndef __NSHAREDLIB__
#define __NSHAREDLIB__
#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>
namespace GS {
/*!
@short Shared library interface.
@author Emmanuel Julien (ejulien@owloh.com)
*/
struct ISharedLib
{
/// Lookup for a function exported by the shared library.
virtual void *GetFunctionPointer(const char *s) = 0;
virtual ~ISharedLib() {}
};
} // GS
#endif // __NSHAREDLIB__

View File

@ -0,0 +1,175 @@
/* -----------------------------------------------------------------------------
GSFramework
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
----------------------------------------------------------------------------- */
#ifndef __SIGNAL__
#define __SIGNAL__
#include "container/nlist.h"
namespace GS {
//
template <typename T> class Signal
{
/// Base signal listener.
struct IListener
{
virtual void Call(T) = 0;
virtual bool BelongsToInstance(void *) const = 0;
virtual bool IsFunction(void (*)(T)) const = 0;
virtual ~IListener() {}
};
AutoList <IListener *> listeners;
/// Pointer to member listener.
template <class O, typename T1> struct InstanceListener : public IListener
{
O *i;
void (O::*f)(T1);
void Call(T1 t) { (i->*f)(t); }
bool BelongsToInstance(void *p) const { return asbool(p == (void *)i); }
bool IsFunction(void (*)(T1)) const { return false; }
InstanceListener(O *_i, void (O::*_f)(T1)) : i(_i), f(_f) {}
};
/// Global/static function listener.
template <typename T1> struct FunctionListener : public IListener
{
void (*f)(T1);
void Call(T1 t) { (*f)(t); }
bool BelongsToInstance(void *) const { return false; }
bool IsFunction(void (*_f)(T1)) const { return f == _f; }
FunctionListener(void (*_f)(T1)) : f(_f) {}
};
public:
/// Return the number of listener on this signal.
uint GetListenerCount() const { return listeners.GetCount(); }
/// Subscribe an instance member function to call when the event is triggered.
template <class O> void Connect(O *i, void (O::*f)(T))
{ listeners.Add(new InstanceListener <O, T> (i, f)); }
/// Remove the subscription of all handlers associated with a specific class instance.
template <class O> void Disconnect(O *i)
{
ListForeachPtr(IListener *, l, this->listeners)
if (l->BelongsToInstance((void *)i))
listeners.Remove(l);
}
/// Subscribe a function to call when the event is triggered.
void Connect(void (*f)(T))
{ listeners.Add(new FunctionListener <T> (f)); }
/// Remove a function subscription.
void Disconnect(void (*f)(T))
{
ListForeachPtr(IListener *, l, this->listeners)
if (l->IsFunction(f))
listeners.Remove(l);
}
/// Emit the signal, notifies all listeners.
void Emit(T t) const
{
ListForeachPtr(IListener *, l, listeners)
l->Call(t);
}
};
// Specialization for void type. Note: I gave up on factoring code => compiler vendor/extension hell.
template <> class Signal <void>
{
/// Base signal listener.
struct IListener
{
virtual void Call() = 0;
virtual bool BelongsToInstance(void *) const = 0;
virtual bool IsFunction(void (*)()) const = 0;
virtual ~IListener() {}
};
AutoList <IListener *> listeners;
/// Pointer to member listener.
template <class O> struct InstanceListener : public IListener
{
O *i;
void (O::*f)();
void Call() { (i->*f)(); }
bool BelongsToInstance(void *p) const { return asbool(p == (void *)i); }
bool IsFunction(void (*)()) const { return false; }
InstanceListener(O *_i, void (O::*_f)()) : i(_i), f(_f) {}
};
/// Global/static function listener.
struct FunctionListener : public IListener
{
void (*f)();
void Call() { (*f)(); }
bool BelongsToInstance(void *) const { return false; }
bool IsFunction(void (*_f)()) const { return f == _f; }
FunctionListener(void (*_f)()) : f(_f) {}
};
public:
/// Return the number of listener on this signal.
uint GetListenerCount() const { return listeners.GetCount(); }
/// Subscribe an instance member function to call when the event is triggered.
template <class O> void Connect(O *i, void (O::*f)())
{ listeners.Add(new InstanceListener <O> (i, f)); }
/// Remove the subscription of all handlers associated with a specific class instance.
template <class O> void Disconnect(O *i)
{
ListForeachPtr(IListener *, l, listeners)
if (l->BelongsToInstance((void *)i))
listeners.Remove(l);
}
/// Subscribe a function to call when the event is triggered.
void Connect(void (*f)())
{ listeners.Add(new FunctionListener(f)); }
/// Remove a function subscription.
void Disconnect(void (*f)())
{
ListForeachPtr(IListener *, l, listeners)
if (l->IsFunction(f))
listeners.Remove(l);
}
/// Emit the signal, notifies all listeners.
void Emit() const
{
ListForeachPtr(IListener *, l, listeners)
l->Call();
}
};
} // GS
#endif // __SIGNAL__

View File

@ -0,0 +1,38 @@
/* -----------------------------------------------------------------------------
GSFramework
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
----------------------------------------------------------------------------- */
#ifndef __NSOCIAL__
#define __NSOCIAL__
namespace GS {
namespace Social {
struct Account
{
String login;
String first, middle, last;
String email;
String address, phone;
};
/*!
@short Social system abstract interface.
@author Emmanuel Julien (ejulien@owloh.com)
*/
struct ISocial
{
virtual bool Login(const char *login, const char *key) = 0;
virtual bool Logout() = 0;
};
} // Social
} // GS
#endif // __NSOCIAL__

View File

@ -0,0 +1,49 @@
/* -----------------------------------------------------------------------------
GSFramework
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
----------------------------------------------------------------------------- */
#ifndef __ATOMIC_VALUE__
#define __ATOMIC_VALUE__
namespace GS {
namespace Threading {
/*!
@short 32bit atomic value.
@author Emmanuel Julien (ejulien@owloh.com)
*/
class Atomic32
{
void *v;
public:
/// Perform atomic increment, return the new value.
int Inc();
/// Perform atomic decrement, return the new value.
int Dec();
/// Return the current value.
int Get() const;
/// Set new value, return the initial value.
int Set(int);
/*!
@short Perform an atomic compare and swap operation.
Compare the current value with the comparand, if they match set the
new value. Return the initial value.
*/
int Cas(int comparand, int value);
explicit Atomic32(int value = 0);
~Atomic32();
};
} // Threading
} // GS
#endif // __ATOMIC_VALUE__

View File

@ -0,0 +1,90 @@
/* -----------------------------------------------------------------------------
GSFramework
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
----------------------------------------------------------------------------- */
#ifndef __NMUTEX__
#define __NMUTEX__
#if __PLATFORM_POSIX__
#include <stdlib.h>
#include <pthread.h>
#elif __PLATFORM_NINTENDO_WII__
#include <revolution.h>
#endif
#include "ntypes.h"
namespace GS {
namespace Threading {
/// Portable mutex class.
class Mutex
{
protected:
#if __PLATFORM_POSIX__
pthread_mutex_t mutex;
#elif __PLATFORM_WINDOWS__
void *mutex;
#elif __PLATFORM_NINTENDO_WII__
OSMutex mutex;
#endif
public:
void Lock();
bool TryLock();
void Unlock();
Mutex();
~Mutex();
};
/// Mutex helper class.
class MutexLock
{
protected:
Mutex *mutex;
public:
bool HasLock() const
{ return asbool(mutex); }
void Lock(Mutex *m, bool try_only)
{
Unlock();
if (try_only)
{
if (m && m->TryLock())
mutex = m;
}
else
{
if (m)
(mutex = m)->Lock();
}
}
void Unlock()
{
if (mutex)
mutex->Unlock();
mutex = 0;
}
MutexLock(Mutex *m, bool try_only = false) : mutex(0)
{ Lock(m, try_only); }
~MutexLock()
{ Unlock(); }
};
} // Threading
} // GS
#endif // __NMUTEX__

View File

@ -0,0 +1,55 @@
/* -----------------------------------------------------------------------------
GSFramework
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
----------------------------------------------------------------------------- */
#ifndef __NTHREAD__
#define __NTHREAD__
#include "thread/atomic_value.h"
namespace GS {
namespace Threading {
/*
@short Thread abstraction class.
@author Emmanuel Julien (ejulien@gsworks.fr)
*/
struct Thread
{
void *handle;
virtual bool Start();
void Kill();
void Join();
static void SetName(const char *);
// Yield execution to the next running system thread.
static void Switch();
/*
@short Set thread priority.
Set the thread priority from 0 to 31.
0 is the highest priority, 31 is the lowest.
@return False is the required priority was invalid.
*/
bool SetPriority(int priority = 16);
/// Main thread execution function.
virtual void Execute() = 0;
Thread();
virtual ~Thread();
};
} // Threading
} // GS
#endif // __NTHREAD__

View File

@ -0,0 +1,135 @@
/* -----------------------------------------------------------------------------
GSFramework
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
----------------------------------------------------------------------------- */
#ifndef __THREAD_CONTROLLER__
#define __THREAD_CONTROLLER__
#include "thread/atomic_value.h"
#include "thread/thread_event.h"
#include "thread/future.h"
#include "thread/thread.h"
#include "thread/mutex.h"
#include "container/nlist.h"
namespace GS {
namespace Threading {
//------------------------------------------------------------------------------
template <typename Target> struct DefaultControllerPolicy
{
static const bool use_event = true; // use thread event to sleep the worker thread
static const bool own_target = false; // the controller owns the target object and is responsible for deleting it
static void Update(Target *) {}
};
template <typename Target, class Policy = DefaultControllerPolicy <Target> > class Controller
{
public:
struct Command
{
Atomic32 dispose;
virtual void Execute(Target *target) = 0;
Command() : dispose(1) {}
virtual ~Command() {}
};
template <class Result> struct CommandWithResult : public Command
{
Future <Result> future_result;
CommandWithResult() { this->dispose.Set(0); }
};
private:
struct WorkerThread : public Thread
{
Target *target;
Atomic32 running;
Mutex command_mutex;
Event command_event;
AutoList <Command *> command_queue;
void Execute()
{
forever
{
Policy::Update(target);
{
MutexLock lock(&command_mutex);
while (command_queue.GetCount() > 0)
{
command_queue[0]->Execute(target);
while (command_queue[0]->dispose.Get() != 1)
; // spin lock on command dispose flag
command_queue.RemoveAt(0);
}
if (running.Get() != 1)
break;
}
if (Policy::use_event)
command_event.Wait();
}
running.Set(0);
}
void Stop()
{
running.Set(2);
if (Policy::use_event)
command_event.Trigger();
while (running.Get() != 0); // spinlock
}
WorkerThread(Target *t) : target(t), running(1) {}
~WorkerThread()
{
if (Policy::own_target)
delete target;
}
};
WorkerThread worker;
public:
void QueueCommand(Command *c)
{
{
MutexLock lock(&worker.command_mutex);
worker.command_queue.Append(c);
}
worker.command_event.Trigger();
}
template <class Result> Result QueueCommand(CommandWithResult <Result> *c)
{
QueueCommand((Command *)c);
Result result = c->future_result.Get(); // wait for command result
c->dispose.Set(1); // flag command disposal
return result; // return result
}
bool Start()
{ return worker.Start(); }
void Stop()
{ worker.Stop(); }
Controller(Target *t) : worker(t) {}
};
//------------------------------------------------------------------------------
} // Threading
} // GS
#endif // __THREAD_CONTROLLER__

View File

@ -0,0 +1,38 @@
/* -----------------------------------------------------------------------------
GSFramework
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
----------------------------------------------------------------------------- */
#ifndef __NTHREAD_EVENT__
#define __NTHREAD_EVENT__
#include "time/ntime.h"
namespace GS {
namespace Threading {
/*!
@short Multi-threaded event.
@author Emmanuel Julien (ejulien@nworks.fr)
*/
struct Event
{
void *event;
/// Thread entering this function will suspend until this event is triggered.
void Wait(Time * = 0);
/// Trigger event.
void Trigger();
Event();
~Event();
};
} // Threading
} // GS
#endif // __NTHREAD_EVENT__

View File

@ -0,0 +1,81 @@
/* -----------------------------------------------------------------------------
GSFramework
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
----------------------------------------------------------------------------- */
#ifndef __NTIME__
#define __NTIME__
#include "nstring/nstring.h"
namespace GS {
/*!
@short Time class.
@author Emmanuel Julien (ejulien@gsworks.fr)
*/
class Time
{
int sec, nsec; // second, nanosecond (10^9 -> 1 billionth second) (63+ years loop)
public:
static Time Inf;
void operator += (const Time &);
void operator -= (const Time &);
Time operator + (const Time &) const;
Time operator - (const Time &) const;
template <class T> void operator *= (T k) { sec = int(T(sec) * k); nsec = int(T(nsec) * k); Normalize(); }
template <class T> void operator /= (T k) { sec = int(T(sec) / k); nsec = int(T(nsec) / k); Normalize(); }
template <class T> Time operator * (T k) const { return Time(int(T(sec) * k), int(T(nsec) * k)); }
template <class T> Time operator / (T k) const { return Time(int(T(sec) / k), int(T(nsec) / k)); }
bool operator > (const Time &) const;
bool operator < (const Time &) const;
bool operator >= (const Time &) const;
bool operator <= (const Time &) const;
bool operator == (const Time &) const;
bool operator != (const Time &) const;
Time Abs() const;
int getSec() const { return sec; }
int getNanoSec() const { return nsec; }
float toDay() const;
float toHour() const;
float toMin() const;
float toSec() const;
float toMs() const;
float toNs() const;
String toString() const;
void setSec(float);
void setSec(int);
void setMs(int);
void setNs(int);
static Time fromSec(float);
static Time fromSec(int);
static Time fromMs(int);
static Time fromNs(int);
void Normalize();
Time Normalized() const;
Time(const int sec, const int nsec);
explicit Time(const int sec = 0);
explicit Time(const float sec);
};
} // GS
#endif // __NTIME__

View File

@ -0,0 +1,22 @@
/* -----------------------------------------------------------------------------
GSFramework
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
----------------------------------------------------------------------------- */
#ifndef __TIMERANGE__
#define __TIMERANGE__
#include "math/nrange.h"
#include "time/ntime.h"
namespace GS {
typedef Range <Time> TimeRange;
} // GS
#endif // __TIMERANGE__

View File

@ -0,0 +1,49 @@
/* -----------------------------------------------------------------------------
GSFramework
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
----------------------------------------------------------------------------- */
#ifndef __NUNIT__
#define __NUNIT__
#include "ntypes.h"
/*
@short Units namespace.
@author Emmanuel Julien (ejulien@gsworks.fr)
*/
namespace GS {
namespace Units {
template <typename T> T Deg(T v) { return v / T(180) * T(3.1415926535); }
template <typename T> T Rad(T v) { return v; }
template <typename T> T DegreeToRadian(T v) { return v / T(180) * T(3.1415926535); }
template <typename T> T RadianToDegree(T v) { return v / T(3.1415926535) * T(180); }
template <typename T> T Sec(T v) { return v; }
template <typename T> T Csec(T v) { return v * T(0.01); }
template <typename T> T Ms(T v) { return v * T(0.001); }
template <typename T> T Tick(T v) { return v * T(0.001); }
template <typename T> T Kg(T v) { return v; }
template <typename T> T G(T v) { return v * T(0.001); }
template <typename T> T Km(T v) { return v * T(1000); }
template <typename T> T Mtr(T v) { return v; }
template <typename T> T Cm(T v) { return v * T(0.01); }
template <typename T> T Mm(T v) { return v * T(0.001); }
template <typename T> T Inch(T v) { return v * T(0.0254); }
size_t KB(const size_t v);
size_t MB(const size_t v);
} // Units
} // GS
#endif // __NUNIT__

View File

@ -0,0 +1,79 @@
/* -----------------------------------------------------------------------------
GSFramework
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
------------------------------------------------------------------------------*/
#ifndef __NVIDEOMODE__
#define __NVIDEOMODE__
#include "ntypes.h"
/*!
@short Video mode database.
@author Emmanuel Julien (ejulien@gsworks.fr)
*/
namespace nVideoMode
{
struct Mode
{
const char *name;
uint width, height;
uchar bpp;
bool pc_mode;
};
enum AspectRatio
{
AR_4_3,
AR_16_9,
AR_16_10,
AR_Unknown
};
enum Name
{
CGA, // 320x200
QVGA, // 320x240
WQVGA, // 480x272
VGA, // 640x480
SVGA, // 800x600
XGA, // 1024x768
XGAPlus, // 1152x864
HD, // 1366x768
WXGA_922K, // 1280x720
WXGA_1024K, // 1280x800
HDPlus, // 1600x900
SXGA, // 1280x1024
WXGAPlus, // 1440x900
UXGA, // 1600x1200
WSXGAPlus, // 1680x1050
FullHD, // 1920x1080
WUXGA, // 1920x1200
QXGA, // 2048x1536
QWXGA, // 2048x1152
WQHD, // 2560x1440
WQXGA, // 2560x1600
NameLast
};
extern Mode mode_desc[NameLast];
/// Get video mode aspect ratio.
AspectRatio GetModeAspectRatio(const Mode &);
/// Get video mode from resolution.
Mode *GetMode(uint w, uint h);
};
#endif // __NVIDEOMODE__