refactor(Core/Common): restyle common lib with astyle (#3461)

This commit is contained in:
Kargatum
2020-09-12 03:50:48 +07:00
committed by GitHub
parent e15a493927
commit 3a0b0356ac
101 changed files with 4524 additions and 4418 deletions

View File

@@ -12,30 +12,30 @@
namespace acore
{
template <class Pointer, class Lock>
class AutoPtr : public ACE_Strong_Bound_Ptr<Pointer, Lock>
{
typedef ACE_Strong_Bound_Ptr<Pointer, Lock> Base;
public:
AutoPtr()
: Base()
{ }
AutoPtr(Pointer* x)
: Base(x)
{ }
operator bool() const
template <class Pointer, class Lock>
class AutoPtr : public ACE_Strong_Bound_Ptr<Pointer, Lock>
{
return !Base::null();
}
typedef ACE_Strong_Bound_Ptr<Pointer, Lock> Base;
bool operator !() const
{
return Base::null();
}
};
public:
AutoPtr()
: Base()
{ }
AutoPtr(Pointer* x)
: Base(x)
{ }
operator bool() const
{
return !Base::null();
}
bool operator !() const
{
return Base::null();
}
};
} // namespace acore

View File

@@ -7,12 +7,12 @@
#include "BoundingIntervalHierarchy.h"
#ifdef _MSC_VER
#define isnan _isnan
#define isnan _isnan
#else
#define isnan std::isnan
#define isnan std::isnan
#endif
void BIH::buildHierarchy(std::vector<uint32> &tempTree, buildData &dat, BuildStats &stats)
void BIH::buildHierarchy(std::vector<uint32>& tempTree, buildData& dat, BuildStats& stats)
{
// create space for the first node
tempTree.push_back(uint32(3 << 30)); // dummy leaf
@@ -26,7 +26,7 @@ void BIH::buildHierarchy(std::vector<uint32> &tempTree, buildData &dat, BuildSta
subdivide(0, dat.numPrims - 1, tempTree, dat, gridBox, nodeBox, 0, 1, stats);
}
void BIH::subdivide(int left, int right, std::vector<uint32> &tempTree, buildData &dat, AABound &gridBox, AABound &nodeBox, int nodeIndex, int depth, BuildStats &stats)
void BIH::subdivide(int left, int right, std::vector<uint32>& tempTree, buildData& dat, AABound& gridBox, AABound& nodeBox, int nodeIndex, int depth, BuildStats& stats)
{
if ((right - left + 1) <= dat.maxPrims || depth >= MAX_STACK_SIZE)
{
@@ -121,13 +121,15 @@ void BIH::subdivide(int left, int right, std::vector<uint32> &tempTree, buildDat
if (right == rightOrig)
{
// all left
if (prevAxis == axis && G3D::fuzzyEq(prevSplit, split)) {
if (prevAxis == axis && G3D::fuzzyEq(prevSplit, split))
{
// we are stuck here - create a leaf
stats.updateLeaf(depth, right - left + 1);
createNode(tempTree, nodeIndex, left, right);
return;
}
if (clipL <= split) {
if (clipL <= split)
{
// keep looping on left half
gridBox.hi[axis] = split;
prevClip = clipL;
@@ -140,14 +142,16 @@ void BIH::subdivide(int left, int right, std::vector<uint32> &tempTree, buildDat
else if (left > right)
{
// all right
if (prevAxis == axis && G3D::fuzzyEq(prevSplit, split)) {
if (prevAxis == axis && G3D::fuzzyEq(prevSplit, split))
{
// we are stuck here - create a leaf
stats.updateLeaf(depth, right - left + 1);
createNode(tempTree, nodeIndex, left, right);
return;
}
right = rightOrig;
if (clipR >= split) {
if (clipR >= split)
{
// keep looping on right half
gridBox.lo[axis] = split;
prevClip = clipR;
@@ -169,14 +173,17 @@ void BIH::subdivide(int left, int right, std::vector<uint32> &tempTree, buildDat
tempTree.push_back(0);
tempTree.push_back(0);
tempTree.push_back(0);
if (wasLeft) {
if (wasLeft)
{
// create a node with a left child
// write leaf node
stats.updateInner();
tempTree[nodeIndex + 0] = (prevAxis << 30) | nextIndex;
tempTree[nodeIndex + 1] = floatToRawIntBits(prevClip);
tempTree[nodeIndex + 2] = floatToRawIntBits(G3D::inf());
} else {
}
else
{
// create a node with a right child
// write leaf node
stats.updateInner();
@@ -198,14 +205,17 @@ void BIH::subdivide(int left, int right, std::vector<uint32> &tempTree, buildDat
// allocate left node
int nl = right - left + 1;
int nr = rightOrig - (right + 1) + 1;
if (nl > 0) {
if (nl > 0)
{
tempTree.push_back(0);
tempTree.push_back(0);
tempTree.push_back(0);
} else
}
else
nextIndex -= 3;
// allocate right node
if (nr > 0) {
if (nr > 0)
{
tempTree.push_back(0);
tempTree.push_back(0);
tempTree.push_back(0);
@@ -235,7 +245,7 @@ void BIH::subdivide(int left, int right, std::vector<uint32> &tempTree, buildDat
bool BIH::writeToFile(FILE* wf) const
{
uint32 treeSize = tree.size();
uint32 check=0, count;
uint32 check = 0, count;
check += fwrite(&bounds.low(), sizeof(float), 3, wf);
check += fwrite(&bounds.high(), sizeof(float), 3, wf);
check += fwrite(&treeSize, sizeof(uint32), 1, wf);
@@ -250,7 +260,7 @@ bool BIH::readFromFile(FILE* rf)
{
uint32 treeSize;
G3D::Vector3 lo, hi;
uint32 check=0, count=0;
uint32 check = 0, count = 0;
check += fread(&lo, sizeof(float), 3, rf);
check += fread(&hi, sizeof(float), 3, rf);
bounds = G3D::AABox(lo, hi);

View File

@@ -54,332 +54,340 @@ struct AABound
class BIH
{
private:
void init_empty()
private:
void init_empty()
{
tree.clear();
objects.clear();
// create space for the first node
tree.push_back(3u << 30u); // dummy leaf
tree.insert(tree.end(), 2, 0);
}
public:
BIH() { init_empty(); }
template< class BoundsFunc, class PrimArray >
void build(const PrimArray& primitives, BoundsFunc& getBounds, uint32 leafSize = 3, bool printStats = false)
{
if (primitives.size() == 0)
{
tree.clear();
objects.clear();
// create space for the first node
tree.push_back(3u << 30u); // dummy leaf
tree.insert(tree.end(), 2, 0);
init_empty();
return;
}
public:
BIH() { init_empty(); }
template< class BoundsFunc, class PrimArray >
void build(const PrimArray &primitives, BoundsFunc &getBounds, uint32 leafSize = 3, bool printStats=false)
buildData dat;
dat.maxPrims = leafSize;
dat.numPrims = primitives.size();
dat.indices = new uint32[dat.numPrims];
dat.primBound = new G3D::AABox[dat.numPrims];
getBounds(primitives[0], bounds);
for (uint32 i = 0; i < dat.numPrims; ++i)
{
if (primitives.size() == 0)
{
init_empty();
return;
}
buildData dat;
dat.maxPrims = leafSize;
dat.numPrims = primitives.size();
dat.indices = new uint32[dat.numPrims];
dat.primBound = new G3D::AABox[dat.numPrims];
getBounds(primitives[0], bounds);
for (uint32 i=0; i<dat.numPrims; ++i)
{
dat.indices[i] = i;
getBounds(primitives[i], dat.primBound[i]);
bounds.merge(dat.primBound[i]);
}
std::vector<uint32> tempTree;
BuildStats stats;
buildHierarchy(tempTree, dat, stats);
if (printStats)
stats.printStats();
objects.resize(dat.numPrims);
for (uint32 i=0; i<dat.numPrims; ++i)
objects[i] = dat.indices[i];
//nObjects = dat.numPrims;
tree = tempTree;
delete[] dat.primBound;
delete[] dat.indices;
dat.indices[i] = i;
getBounds(primitives[i], dat.primBound[i]);
bounds.merge(dat.primBound[i]);
}
uint32 primCount() const { return objects.size(); }
std::vector<uint32> tempTree;
BuildStats stats;
buildHierarchy(tempTree, dat, stats);
if (printStats)
stats.printStats();
template<typename RayCallback>
void intersectRay(const G3D::Ray &r, RayCallback& intersectCallback, float &maxDist, bool stopAtFirstHit) const
objects.resize(dat.numPrims);
for (uint32 i = 0; i < dat.numPrims; ++i)
objects[i] = dat.indices[i];
//nObjects = dat.numPrims;
tree = tempTree;
delete[] dat.primBound;
delete[] dat.indices;
}
uint32 primCount() const { return objects.size(); }
template<typename RayCallback>
void intersectRay(const G3D::Ray& r, RayCallback& intersectCallback, float& maxDist, bool stopAtFirstHit) const
{
float intervalMin = -1.f;
float intervalMax = -1.f;
G3D::Vector3 org = r.origin();
G3D::Vector3 dir = r.direction();
G3D::Vector3 invDir;
for (int i = 0; i < 3; ++i)
{
float intervalMin = -1.f;
float intervalMax = -1.f;
G3D::Vector3 org = r.origin();
G3D::Vector3 dir = r.direction();
G3D::Vector3 invDir;
for (int i=0; i<3; ++i)
invDir[i] = 1.f / dir[i];
if (G3D::fuzzyNe(dir[i], 0.0f))
{
invDir[i] = 1.f / dir[i];
if (G3D::fuzzyNe(dir[i], 0.0f))
{
float t1 = (bounds.low()[i] - org[i]) * invDir[i];
float t2 = (bounds.high()[i] - org[i]) * invDir[i];
if (t1 > t2)
std::swap(t1, t2);
if (t1 > intervalMin)
intervalMin = t1;
if (t2 < intervalMax || intervalMax < 0.f)
intervalMax = t2;
// intervalMax can only become smaller for other axis,
// and intervalMin only larger respectively, so stop early
if (intervalMax <= 0 || intervalMin >= maxDist)
return;
}
float t1 = (bounds.low()[i] - org[i]) * invDir[i];
float t2 = (bounds.high()[i] - org[i]) * invDir[i];
if (t1 > t2)
std::swap(t1, t2);
if (t1 > intervalMin)
intervalMin = t1;
if (t2 < intervalMax || intervalMax < 0.f)
intervalMax = t2;
// intervalMax can only become smaller for other axis,
// and intervalMin only larger respectively, so stop early
if (intervalMax <= 0 || intervalMin >= maxDist)
return;
}
}
if (intervalMin > intervalMax)
return;
intervalMin = std::max(intervalMin, 0.f);
intervalMax = std::min(intervalMax, maxDist);
if (intervalMin > intervalMax)
return;
intervalMin = std::max(intervalMin, 0.f);
intervalMax = std::min(intervalMax, maxDist);
uint32 offsetFront[3];
uint32 offsetBack[3];
uint32 offsetFront3[3];
uint32 offsetBack3[3];
// compute custom offsets from direction sign bit
uint32 offsetFront[3];
uint32 offsetBack[3];
uint32 offsetFront3[3];
uint32 offsetBack3[3];
// compute custom offsets from direction sign bit
for (int i=0; i<3; ++i)
for (int i = 0; i < 3; ++i)
{
offsetFront[i] = floatToRawIntBits(dir[i]) >> 31;
offsetBack[i] = offsetFront[i] ^ 1;
offsetFront3[i] = offsetFront[i] * 3;
offsetBack3[i] = offsetBack[i] * 3;
// avoid always adding 1 during the inner loop
++offsetFront[i];
++offsetBack[i];
}
StackNode stack[MAX_STACK_SIZE];
int stackPos = 0;
int node = 0;
while (true)
{
while (true)
{
offsetFront[i] = floatToRawIntBits(dir[i]) >> 31;
offsetBack[i] = offsetFront[i] ^ 1;
offsetFront3[i] = offsetFront[i] * 3;
offsetBack3[i] = offsetBack[i] * 3;
// avoid always adding 1 during the inner loop
++offsetFront[i];
++offsetBack[i];
}
StackNode stack[MAX_STACK_SIZE];
int stackPos = 0;
int node = 0;
while (true) {
while (true)
uint32 tn = tree[node];
uint32 axis = (tn & (3 << 30)) >> 30;
bool BVH2 = tn & (1 << 29);
int offset = tn & ~(7 << 29);
if (!BVH2)
{
uint32 tn = tree[node];
uint32 axis = (tn & (3 << 30)) >> 30;
bool BVH2 = tn & (1 << 29);
int offset = tn & ~(7 << 29);
if (!BVH2)
if (axis < 3)
{
if (axis < 3)
// "normal" interior node
float tf = (intBitsToFloat(tree[node + offsetFront[axis]]) - org[axis]) * invDir[axis];
float tb = (intBitsToFloat(tree[node + offsetBack[axis]]) - org[axis]) * invDir[axis];
// ray passes between clip zones
if (tf < intervalMin && tb > intervalMax)
break;
int back = offset + offsetBack3[axis];
node = back;
// ray passes through far node only
if (tf < intervalMin)
{
intervalMin = (tb >= intervalMin) ? tb : intervalMin;
continue;
}
node = offset + offsetFront3[axis]; // front
// ray passes through near node only
if (tb > intervalMax)
{
// "normal" interior node
float tf = (intBitsToFloat(tree[node + offsetFront[axis]]) - org[axis]) * invDir[axis];
float tb = (intBitsToFloat(tree[node + offsetBack[axis]]) - org[axis]) * invDir[axis];
// ray passes between clip zones
if (tf < intervalMin && tb > intervalMax)
break;
int back = offset + offsetBack3[axis];
node = back;
// ray passes through far node only
if (tf < intervalMin) {
intervalMin = (tb >= intervalMin) ? tb : intervalMin;
continue;
}
node = offset + offsetFront3[axis]; // front
// ray passes through near node only
if (tb > intervalMax) {
intervalMax = (tf <= intervalMax) ? tf : intervalMax;
continue;
}
// ray passes through both nodes
// push back node
stack[stackPos].node = back;
stack[stackPos].tnear = (tb >= intervalMin) ? tb : intervalMin;
stack[stackPos].tfar = intervalMax;
stackPos++;
// update ray interval for front node
intervalMax = (tf <= intervalMax) ? tf : intervalMax;
continue;
}
else
{
// leaf - test some objects
int n = tree[node + 1];
while (n > 0) {
bool hit = intersectCallback(r, objects[offset], maxDist, stopAtFirstHit);
if (stopAtFirstHit && hit) return;
--n;
++offset;
}
break;
}
// ray passes through both nodes
// push back node
stack[stackPos].node = back;
stack[stackPos].tnear = (tb >= intervalMin) ? tb : intervalMin;
stack[stackPos].tfar = intervalMax;
stackPos++;
// update ray interval for front node
intervalMax = (tf <= intervalMax) ? tf : intervalMax;
continue;
}
else
{
if (axis>2)
return; // should not happen
float tf = (intBitsToFloat(tree[node + offsetFront[axis]]) - org[axis]) * invDir[axis];
float tb = (intBitsToFloat(tree[node + offsetBack[axis]]) - org[axis]) * invDir[axis];
node = offset;
intervalMin = (tf >= intervalMin) ? tf : intervalMin;
intervalMax = (tb <= intervalMax) ? tb : intervalMax;
if (intervalMin > intervalMax)
break;
continue;
}
} // traversal loop
do
{
// stack is empty?
if (stackPos == 0)
return;
// move back up the stack
stackPos--;
intervalMin = stack[stackPos].tnear;
if (maxDist < intervalMin)
continue;
node = stack[stackPos].node;
intervalMax = stack[stackPos].tfar;
break;
} while (true);
}
}
template<typename IsectCallback>
void intersectPoint(const G3D::Vector3 &p, IsectCallback& intersectCallback) const
{
if (!bounds.contains(p))
return;
StackNode stack[MAX_STACK_SIZE];
int stackPos = 0;
int node = 0;
while (true) {
while (true)
{
uint32 tn = tree[node];
uint32 axis = (tn & (3 << 30)) >> 30;
bool BVH2 = tn & (1 << 29);
int offset = tn & ~(7 << 29);
if (!BVH2)
{
if (axis < 3)
// leaf - test some objects
int n = tree[node + 1];
while (n > 0)
{
// "normal" interior node
float tl = intBitsToFloat(tree[node + 1]);
float tr = intBitsToFloat(tree[node + 2]);
// point is between clip zones
if (tl < p[axis] && tr > p[axis])
break;
int right = offset + 3;
node = right;
// point is in right node only
if (tl < p[axis]) {
continue;
}
node = offset; // left
// point is in left node only
if (tr > p[axis]) {
continue;
}
// point is in both nodes
// push back right node
stack[stackPos].node = right;
stackPos++;
continue;
}
else
{
// leaf - test some objects
int n = tree[node + 1];
while (n > 0) {
intersectCallback(p, objects[offset]); // !!!
--n;
++offset;
}
break;
bool hit = intersectCallback(r, objects[offset], maxDist, stopAtFirstHit);
if (stopAtFirstHit && hit) return;
--n;
++offset;
}
break;
}
else // BVH2 node (empty space cut off left and right)
{
if (axis>2)
return; // should not happen
float tl = intBitsToFloat(tree[node + 1]);
float tr = intBitsToFloat(tree[node + 2]);
node = offset;
if (tl > p[axis] || tr < p[axis])
break;
continue;
}
} // traversal loop
}
else
{
if (axis > 2)
return; // should not happen
float tf = (intBitsToFloat(tree[node + offsetFront[axis]]) - org[axis]) * invDir[axis];
float tb = (intBitsToFloat(tree[node + offsetBack[axis]]) - org[axis]) * invDir[axis];
node = offset;
intervalMin = (tf >= intervalMin) ? tf : intervalMin;
intervalMax = (tb <= intervalMax) ? tb : intervalMax;
if (intervalMin > intervalMax)
break;
continue;
}
} // traversal loop
do
{
// stack is empty?
if (stackPos == 0)
return;
// move back up the stack
stackPos--;
intervalMin = stack[stackPos].tnear;
if (maxDist < intervalMin)
continue;
node = stack[stackPos].node;
}
intervalMax = stack[stackPos].tfar;
break;
} while (true);
}
}
bool writeToFile(FILE* wf) const;
bool readFromFile(FILE* rf);
template<typename IsectCallback>
void intersectPoint(const G3D::Vector3& p, IsectCallback& intersectCallback) const
{
if (!bounds.contains(p))
return;
protected:
std::vector<uint32> tree;
std::vector<uint32> objects;
G3D::AABox bounds;
StackNode stack[MAX_STACK_SIZE];
int stackPos = 0;
int node = 0;
struct buildData
while (true)
{
uint32 *indices;
G3D::AABox *primBound;
uint32 numPrims;
int maxPrims;
};
struct StackNode
{
uint32 node;
float tnear;
float tfar;
};
class BuildStats
{
private:
int numNodes;
int numLeaves;
int sumObjects;
int minObjects;
int maxObjects;
int sumDepth;
int minDepth;
int maxDepth;
int numLeavesN[6];
int numBVH2;
public:
BuildStats():
numNodes(0), numLeaves(0), sumObjects(0), minObjects(0x0FFFFFFF),
maxObjects(0xFFFFFFFF), sumDepth(0), minDepth(0x0FFFFFFF),
maxDepth(0xFFFFFFFF), numBVH2(0)
while (true)
{
for (int i=0; i<6; ++i) numLeavesN[i] = 0;
}
uint32 tn = tree[node];
uint32 axis = (tn & (3 << 30)) >> 30;
bool BVH2 = tn & (1 << 29);
int offset = tn & ~(7 << 29);
if (!BVH2)
{
if (axis < 3)
{
// "normal" interior node
float tl = intBitsToFloat(tree[node + 1]);
float tr = intBitsToFloat(tree[node + 2]);
// point is between clip zones
if (tl < p[axis] && tr > p[axis])
break;
int right = offset + 3;
node = right;
// point is in right node only
if (tl < p[axis])
{
continue;
}
node = offset; // left
// point is in left node only
if (tr > p[axis])
{
continue;
}
// point is in both nodes
// push back right node
stack[stackPos].node = right;
stackPos++;
continue;
}
else
{
// leaf - test some objects
int n = tree[node + 1];
while (n > 0)
{
intersectCallback(p, objects[offset]); // !!!
--n;
++offset;
}
break;
}
}
else // BVH2 node (empty space cut off left and right)
{
if (axis > 2)
return; // should not happen
float tl = intBitsToFloat(tree[node + 1]);
float tr = intBitsToFloat(tree[node + 2]);
node = offset;
if (tl > p[axis] || tr < p[axis])
break;
continue;
}
} // traversal loop
void updateInner() { numNodes++; }
void updateBVH2() { numBVH2++; }
void updateLeaf(int depth, int n);
void printStats();
};
// stack is empty?
if (stackPos == 0)
return;
// move back up the stack
stackPos--;
node = stack[stackPos].node;
}
}
void buildHierarchy(std::vector<uint32> &tempTree, buildData &dat, BuildStats &stats);
bool writeToFile(FILE* wf) const;
bool readFromFile(FILE* rf);
void createNode(std::vector<uint32> &tempTree, int nodeIndex, uint32 left, uint32 right) const
protected:
std::vector<uint32> tree;
std::vector<uint32> objects;
G3D::AABox bounds;
struct buildData
{
uint32* indices;
G3D::AABox* primBound;
uint32 numPrims;
int maxPrims;
};
struct StackNode
{
uint32 node;
float tnear;
float tfar;
};
class BuildStats
{
private:
int numNodes;
int numLeaves;
int sumObjects;
int minObjects;
int maxObjects;
int sumDepth;
int minDepth;
int maxDepth;
int numLeavesN[6];
int numBVH2;
public:
BuildStats():
numNodes(0), numLeaves(0), sumObjects(0), minObjects(0x0FFFFFFF),
maxObjects(0xFFFFFFFF), sumDepth(0), minDepth(0x0FFFFFFF),
maxDepth(0xFFFFFFFF), numBVH2(0)
{
// write leaf node
tempTree[nodeIndex + 0] = (3 << 30) | left;
tempTree[nodeIndex + 1] = right - left + 1;
for (int i = 0; i < 6; ++i) numLeavesN[i] = 0;
}
void subdivide(int left, int right, std::vector<uint32> &tempTree, buildData &dat, AABound &gridBox, AABound &nodeBox, int nodeIndex, int depth, BuildStats &stats);
void updateInner() { numNodes++; }
void updateBVH2() { numBVH2++; }
void updateLeaf(int depth, int n);
void printStats();
};
void buildHierarchy(std::vector<uint32>& tempTree, buildData& dat, BuildStats& stats);
void createNode(std::vector<uint32>& tempTree, int nodeIndex, uint32 left, uint32 right) const
{
// write leaf node
tempTree[nodeIndex + 0] = (3 << 30) | left;
tempTree[nodeIndex + 1] = right - left + 1;
}
void subdivide(int left, int right, std::vector<uint32>& tempTree, buildData& dat, AABound& gridBox, AABound& nodeBox, int nodeIndex, int depth, BuildStats& stats);
};
#endif // _BIH_H

View File

@@ -66,7 +66,7 @@ public:
{
++unbalanced_times;
uint32 Idx = 0;
const T * temp;
const T* temp;
if (m_obj2Idx.getRemove(&obj, temp, Idx))
m_objects[Idx] = NULL;
else

View File

@@ -21,21 +21,25 @@
using VMAP::ModelInstance;
namespace {
namespace
{
int CHECK_TREE_PERIOD = 200;
int CHECK_TREE_PERIOD = 200;
} // namespace
template<> struct HashTrait< GameObjectModel>{
template<> struct HashTrait< GameObjectModel>
{
static size_t hashCode(const GameObjectModel& g) { return (size_t)(void*)&g; }
};
template<> struct PositionTrait< GameObjectModel> {
template<> struct PositionTrait< GameObjectModel>
{
static void getPosition(const GameObjectModel& g, G3D::Vector3& p) { p = g.getPosition(); }
};
template<> struct BoundsTrait< GameObjectModel> {
template<> struct BoundsTrait< GameObjectModel>
{
static void getBounds(const GameObjectModel& g, G3D::AABox& out) { out = g.getBounds();}
static void getBounds2(const GameObjectModel* g, G3D::AABox& out) { out = g->getBounds();}
};
@@ -148,7 +152,7 @@ struct DynamicTreeIntersectionCallback
};
bool DynamicMapTree::getIntersectionTime(const uint32 phasemask, const G3D::Ray& ray,
const G3D::Vector3& endPos, float& maxDist) const
const G3D::Vector3& endPos, float& maxDist) const
{
float distance = maxDist;
DynamicTreeIntersectionCallback callback(phasemask);
@@ -172,7 +176,7 @@ bool DynamicMapTree::getObjectHitPos(const uint32 phasemask, const G3D::Vector3&
resultHit = endPos;
return false;
}
G3D::Vector3 dir = (endPos - startPos)/maxDist; // direction with length of 1
G3D::Vector3 dir = (endPos - startPos) / maxDist; // direction with length of 1
G3D::Ray ray(startPos, dir);
float dist = maxDist;
if (getIntersectionTime(phasemask, ray, endPos, dist))
@@ -181,12 +185,12 @@ bool DynamicMapTree::getObjectHitPos(const uint32 phasemask, const G3D::Vector3&
if (modifyDist < 0)
{
if ((resultHit - startPos).magnitude() > -modifyDist)
resultHit = resultHit + dir*modifyDist;
resultHit = resultHit + dir * modifyDist;
else
resultHit = startPos;
}
else
resultHit = resultHit + dir*modifyDist;
resultHit = resultHit + dir * modifyDist;
result = true;
}
@@ -207,7 +211,7 @@ bool DynamicMapTree::isInLineOfSight(float x1, float y1, float z1, float x2, flo
if (!G3D::fuzzyGt(maxDist, 0) )
return true;
G3D::Ray r(v1, (v2-v1) / maxDist);
G3D::Ray r(v1, (v2 - v1) / maxDist);
DynamicTreeIntersectionCallback callback(phasemask);
impl->intersectRay(r, callback, maxDist, v2, true);

View File

@@ -20,7 +20,7 @@ struct DynTreeImpl;
class DynamicMapTree
{
DynTreeImpl *impl;
DynTreeImpl* impl;
public:

View File

@@ -22,16 +22,16 @@ namespace MMAP
class IMMapManager
{
private:
bool iEnablePathFinding;
private:
bool iEnablePathFinding;
public:
IMMapManager() : iEnablePathFinding(true) {}
virtual ~IMMapManager(void) {}
public:
IMMapManager() : iEnablePathFinding(true) {}
virtual ~IMMapManager(void) {}
//Enabled/Disabled Pathfinding
void setEnablePathFinding(bool value) { iEnablePathFinding = value; }
bool isEnablePathFinding() const { return (iEnablePathFinding); }
//Enabled/Disabled Pathfinding
void setEnablePathFinding(bool value) { iEnablePathFinding = value; }
bool isEnablePathFinding() const { return (iEnablePathFinding); }
};
}

View File

@@ -26,62 +26,62 @@ namespace VMAP
VMAP_LOAD_RESULT_IGNORED
};
#define VMAP_INVALID_HEIGHT -100000.0f // for check
#define VMAP_INVALID_HEIGHT_VALUE -200000.0f // real assigned value in unknown height case
#define VMAP_INVALID_HEIGHT -100000.0f // for check
#define VMAP_INVALID_HEIGHT_VALUE -200000.0f // real assigned value in unknown height case
//===========================================================
class IVMapManager
{
private:
bool iEnableLineOfSightCalc;
bool iEnableHeightCalc;
private:
bool iEnableLineOfSightCalc;
bool iEnableHeightCalc;
public:
IVMapManager() : iEnableLineOfSightCalc(true), iEnableHeightCalc(true) { }
public:
IVMapManager() : iEnableLineOfSightCalc(true), iEnableHeightCalc(true) { }
virtual ~IVMapManager(void) { }
virtual ~IVMapManager(void) { }
virtual int loadMap(const char* pBasePath, unsigned int pMapId, int x, int y) = 0;
virtual int loadMap(const char* pBasePath, unsigned int pMapId, int x, int y) = 0;
virtual bool existsMap(const char* pBasePath, unsigned int pMapId, int x, int y) = 0;
virtual bool existsMap(const char* pBasePath, unsigned int pMapId, int x, int y) = 0;
virtual void unloadMap(unsigned int pMapId, int x, int y) = 0;
virtual void unloadMap(unsigned int pMapId) = 0;
virtual void unloadMap(unsigned int pMapId, int x, int y) = 0;
virtual void unloadMap(unsigned int pMapId) = 0;
virtual bool isInLineOfSight(unsigned int pMapId, float x1, float y1, float z1, float x2, float y2, float z2) = 0;
virtual float getHeight(unsigned int pMapId, float x, float y, float z, float maxSearchDist) = 0;
/**
test if we hit an object. return true if we hit one. rx, ry, rz will hold the hit position or the dest position, if no intersection was found
return a position, that is pReduceDist closer to the origin
*/
virtual bool getObjectHitPos(unsigned int pMapId, float x1, float y1, float z1, float x2, float y2, float z2, float& rx, float &ry, float& rz, float pModifyDist) = 0;
/**
send debug commands
*/
virtual bool processCommand(char *pCommand)= 0;
virtual bool isInLineOfSight(unsigned int pMapId, float x1, float y1, float z1, float x2, float y2, float z2) = 0;
virtual float getHeight(unsigned int pMapId, float x, float y, float z, float maxSearchDist) = 0;
/**
test if we hit an object. return true if we hit one. rx, ry, rz will hold the hit position or the dest position, if no intersection was found
return a position, that is pReduceDist closer to the origin
*/
virtual bool getObjectHitPos(unsigned int pMapId, float x1, float y1, float z1, float x2, float y2, float z2, float& rx, float& ry, float& rz, float pModifyDist) = 0;
/**
send debug commands
*/
virtual bool processCommand(char* pCommand) = 0;
/**
Enable/disable LOS calculation
It is enabled by default. If it is enabled in mid game the maps have to loaded manualy
*/
void setEnableLineOfSightCalc(bool pVal) { iEnableLineOfSightCalc = pVal; }
/**
Enable/disable model height calculation
It is enabled by default. If it is enabled in mid game the maps have to loaded manualy
*/
void setEnableHeightCalc(bool pVal) { iEnableHeightCalc = pVal; }
/**
Enable/disable LOS calculation
It is enabled by default. If it is enabled in mid game the maps have to loaded manualy
*/
void setEnableLineOfSightCalc(bool pVal) { iEnableLineOfSightCalc = pVal; }
/**
Enable/disable model height calculation
It is enabled by default. If it is enabled in mid game the maps have to loaded manualy
*/
void setEnableHeightCalc(bool pVal) { iEnableHeightCalc = pVal; }
bool isLineOfSightCalcEnabled() const { return(iEnableLineOfSightCalc); }
bool isHeightCalcEnabled() const { return(iEnableHeightCalc); }
bool isMapLoadingEnabled() const { return(iEnableLineOfSightCalc || iEnableHeightCalc ); }
bool isLineOfSightCalcEnabled() const { return(iEnableLineOfSightCalc); }
bool isHeightCalcEnabled() const { return(iEnableHeightCalc); }
bool isMapLoadingEnabled() const { return(iEnableLineOfSightCalc || iEnableHeightCalc ); }
virtual std::string getDirFileName(unsigned int pMapId, int x, int y) const =0;
/**
Query world model area info.
\param z gets adjusted to the ground height for which this are info is valid
*/
virtual bool getAreaInfo(unsigned int pMapId, float x, float y, float &z, uint32 &flags, int32 &adtId, int32 &rootId, int32 &groupId) const=0;
virtual bool GetLiquidLevel(uint32 pMapId, float x, float y, float z, uint8 ReqLiquidType, float &level, float &floor, uint32 &type) const=0;
virtual std::string getDirFileName(unsigned int pMapId, int x, int y) const = 0;
/**
Query world model area info.
\param z gets adjusted to the ground height for which this are info is valid
*/
virtual bool getAreaInfo(unsigned int pMapId, float x, float y, float& z, uint32& flags, int32& adtId, int32& rootId, int32& groupId) const = 0;
virtual bool GetLiquidLevel(uint32 pMapId, float x, float y, float z, uint8 ReqLiquidType, float& level, float& floor, uint32& type) const = 0;
};
}

View File

@@ -12,7 +12,7 @@ namespace MMAP
{
// ######################## MMapFactory ########################
// our global singleton copy
MMapManager *g_MMapManager = NULL;
MMapManager* g_MMapManager = NULL;
bool MMapFactory::forbiddenMaps[1000] = {0};
MMapManager* MMapFactory::createOrGetMMapManager()

View File

@@ -28,12 +28,12 @@ namespace MMAP
// access point to MMapManager singleton
class MMapFactory
{
public:
static MMapManager* createOrGetMMapManager();
static void clear();
static bool IsPathfindingEnabled(const Map* map);
static void InitializeDisabledMaps();
static bool forbiddenMaps[1000];
public:
static MMapManager* createOrGetMMapManager();
static void clear();
static bool IsPathfindingEnabled(const Map* map);
static void InitializeDisabledMaps();
static bool forbiddenMaps[1000];
};
}

View File

@@ -27,9 +27,9 @@ namespace MMAP
return true;
// load and init dtNavMesh - read parameters from file
uint32 pathLen = sWorld->GetDataPath().length() + strlen("mmaps/%03i.mmap")+1;
char *fileName = new char[pathLen];
snprintf(fileName, pathLen, (sWorld->GetDataPath()+"mmaps/%03i.mmap").c_str(), mapId);
uint32 pathLen = sWorld->GetDataPath().length() + strlen("mmaps/%03i.mmap") + 1;
char* fileName = new char[pathLen];
snprintf(fileName, pathLen, (sWorld->GetDataPath() + "mmaps/%03i.mmap").c_str(), mapId);
FILE* file = fopen(fileName, "rb");
if (!file)
@@ -112,11 +112,11 @@ namespace MMAP
}
// load this tile :: mmaps/MMMXXYY.mmtile
uint32 pathLen = sWorld->GetDataPath().length() + strlen("mmaps/%03i%02i%02i.mmtile")+1;
char *fileName = new char[pathLen];
snprintf(fileName, pathLen, (sWorld->GetDataPath()+"mmaps/%03i%02i%02i.mmtile").c_str(), mapId, x, y);
uint32 pathLen = sWorld->GetDataPath().length() + strlen("mmaps/%03i%02i%02i.mmtile") + 1;
char* fileName = new char[pathLen];
snprintf(fileName, pathLen, (sWorld->GetDataPath() + "mmaps/%03i%02i%02i.mmtile").c_str(), mapId, x, y);
FILE *file = fopen(fileName, "rb");
FILE* file = fopen(fileName, "rb");
if (!file)
{
#if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS)
@@ -139,7 +139,7 @@ namespace MMAP
if (fileHeader.mmapVersion != MMAP_VERSION)
{
sLog->outError("MMAP:loadMap: %03u%02i%02i.mmtile was built with generator v%i, expected v%i",
mapId, x, y, fileHeader.mmapVersion, MMAP_VERSION);
mapId, x, y, fileHeader.mmapVersion, MMAP_VERSION);
fclose(file);
return false;
}
@@ -345,26 +345,26 @@ namespace MMAP
MMapData* mmap = loadedMMaps[mapId];
if (mmap->navMeshQueries.find(instanceId) == mmap->navMeshQueries.end())
{
// pussywizard: different instances of the same map shouldn't access this simultaneously
ACORE_WRITE_GUARD(ACE_RW_Thread_Mutex, GetMMapLock(mapId));
// check again after acquiring mutex
if (mmap->navMeshQueries.find(instanceId) == mmap->navMeshQueries.end())
{
// allocate mesh query
dtNavMeshQuery* query = dtAllocNavMeshQuery();
ASSERT(query);
if (DT_SUCCESS != query->init(mmap->navMesh, 1024))
// pussywizard: different instances of the same map shouldn't access this simultaneously
ACORE_WRITE_GUARD(ACE_RW_Thread_Mutex, GetMMapLock(mapId));
// check again after acquiring mutex
if (mmap->navMeshQueries.find(instanceId) == mmap->navMeshQueries.end())
{
dtFreeNavMeshQuery(query);
sLog->outError("MMAP:GetNavMeshQuery: Failed to initialize dtNavMeshQuery for mapId %03u instanceId %u", mapId, instanceId);
return NULL;
}
// allocate mesh query
dtNavMeshQuery* query = dtAllocNavMeshQuery();
ASSERT(query);
if (DT_SUCCESS != query->init(mmap->navMesh, 1024))
{
dtFreeNavMeshQuery(query);
sLog->outError("MMAP:GetNavMeshQuery: Failed to initialize dtNavMeshQuery for mapId %03u instanceId %u", mapId, instanceId);
return NULL;
}
#if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS)
sLog->outDetail("MMAP:GetNavMeshQuery: created dtNavMeshQuery for mapId %03u instanceId %u", mapId, instanceId);
sLog->outDetail("MMAP:GetNavMeshQuery: created dtNavMeshQuery for mapId %03u instanceId %u", mapId, instanceId);
#endif
mmap->navMeshQueries.insert(std::pair<uint32, dtNavMeshQuery*>(instanceId, query));
}
mmap->navMeshQueries.insert(std::pair<uint32, dtNavMeshQuery*>(instanceId, query));
}
}
return mmap->navMeshQueries[instanceId];

View File

@@ -57,34 +57,34 @@ namespace MMAP
// holds all all access to mmap loading unloading and meshes
class MMapManager
{
public:
MMapManager() : loadedTiles(0) {}
~MMapManager();
public:
MMapManager() : loadedTiles(0) {}
~MMapManager();
bool loadMap(uint32 mapId, int32 x, int32 y);
bool unloadMap(uint32 mapId, int32 x, int32 y);
bool unloadMap(uint32 mapId);
bool unloadMapInstance(uint32 mapId, uint32 instanceId);
bool loadMap(uint32 mapId, int32 x, int32 y);
bool unloadMap(uint32 mapId, int32 x, int32 y);
bool unloadMap(uint32 mapId);
bool unloadMapInstance(uint32 mapId, uint32 instanceId);
// the returned [dtNavMeshQuery const*] is NOT threadsafe
dtNavMeshQuery const* GetNavMeshQuery(uint32 mapId, uint32 instanceId);
dtNavMesh const* GetNavMesh(uint32 mapId);
// the returned [dtNavMeshQuery const*] is NOT threadsafe
dtNavMeshQuery const* GetNavMeshQuery(uint32 mapId, uint32 instanceId);
dtNavMesh const* GetNavMesh(uint32 mapId);
uint32 getLoadedTilesCount() const { return loadedTiles; }
uint32 getLoadedMapsCount() const { return loadedMMaps.size(); }
uint32 getLoadedTilesCount() const { return loadedTiles; }
uint32 getLoadedMapsCount() const { return loadedMMaps.size(); }
ACE_RW_Thread_Mutex& GetMMapLock(uint32 mapId);
ACE_RW_Thread_Mutex& GetMMapGeneralLock() { return MMapLock; } // pussywizard: in case a per-map mutex can't be found, should never happen
ACE_RW_Thread_Mutex& GetManagerLock() { return MMapManagerLock; }
private:
bool loadMapData(uint32 mapId);
uint32 packTileID(int32 x, int32 y);
ACE_RW_Thread_Mutex& GetMMapLock(uint32 mapId);
ACE_RW_Thread_Mutex& GetMMapGeneralLock() { return MMapLock; } // pussywizard: in case a per-map mutex can't be found, should never happen
ACE_RW_Thread_Mutex& GetManagerLock() { return MMapManagerLock; }
private:
bool loadMapData(uint32 mapId);
uint32 packTileID(int32 x, int32 y);
MMapDataSet loadedMMaps;
uint32 loadedTiles;
MMapDataSet loadedMMaps;
uint32 loadedTiles;
ACE_RW_Thread_Mutex MMapManagerLock;
ACE_RW_Thread_Mutex MMapLock; // pussywizard: in case a per-map mutex can't be found, should never happen
ACE_RW_Thread_Mutex MMapManagerLock;
ACE_RW_Thread_Mutex MMapLock; // pussywizard: in case a per-map mutex can't be found, should never happen
};
}

View File

@@ -16,7 +16,7 @@ namespace VMAP
IVMapManager* VMapFactory::createOrGetVMapManager()
{
if (gVMapManager == 0)
gVMapManager= new VMapManager2(); // should be taken from config ... Please change if you like :-)
gVMapManager = new VMapManager2(); // should be taken from config ... Please change if you like :-)
return gVMapManager;
}

View File

@@ -19,9 +19,9 @@ namespace VMAP
class VMapFactory
{
public:
static IVMapManager* createOrGetVMapManager();
static void clear();
public:
static IVMapManager* createOrGetVMapManager();
static void clear();
};
}

View File

@@ -95,10 +95,10 @@ namespace VMAP
std::string mapFileName = getMapFileName(mapId);
StaticMapTree* newTree = new StaticMapTree(mapId, basePath);
if (!newTree->InitMap(mapFileName, this))
{
delete newTree;
{
delete newTree;
return false;
}
}
instanceTree = iInstanceMapTrees.insert(InstanceTreeMap::value_type(mapId, newTree)).first;
}
@@ -158,7 +158,7 @@ namespace VMAP
get the hit position and return true if we hit something
otherwise the result pos will be the dest pos
*/
bool VMapManager2::getObjectHitPos(unsigned int mapId, float x1, float y1, float z1, float x2, float y2, float z2, float& rx, float &ry, float& rz, float modifyDist)
bool VMapManager2::getObjectHitPos(unsigned int mapId, float x1, float y1, float z1, float x2, float y2, float z2, float& rx, float& ry, float& rz, float modifyDist)
{
#if defined(ENABLE_EXTRAS) && defined(ENABLE_VMAP_CHECKS)
if (isLineOfSightCalcEnabled() && !DisableMgr::IsDisabledFor(DISABLE_TYPE_VMAP, mapId, NULL, VMAP_DISABLE_LOS))
@@ -283,7 +283,7 @@ namespace VMAP
return model->second.getModel();
}
void VMapManager2::releaseModelInstance(const std::string &filename)
void VMapManager2::releaseModelInstance(const std::string& filename)
{
//! Critical section, thread safe access to iLoadedModelFiles
ACORE_GUARD(ACE_Thread_Mutex, LoadedModelFilesLock);

View File

@@ -51,15 +51,15 @@ namespace VMAP
class ManagedModel
{
public:
ManagedModel() : iModel(0), iRefCount(0) { }
void setModel(WorldModel* model) { iModel = model; }
WorldModel* getModel() { return iModel; }
void incRefCount() { ++iRefCount; }
int decRefCount() { return --iRefCount; }
protected:
WorldModel* iModel;
int iRefCount;
public:
ManagedModel() : iModel(0), iRefCount(0) { }
void setModel(WorldModel* model) { iModel = model; }
WorldModel* getModel() { return iModel; }
void incRefCount() { ++iRefCount; }
int decRefCount() { return --iRefCount; }
protected:
WorldModel* iModel;
int iRefCount;
};
typedef std::unordered_map<uint32, StaticMapTree*> InstanceTreeMap;
@@ -67,57 +67,57 @@ namespace VMAP
class VMapManager2 : public IVMapManager
{
protected:
// Tree to check collision
ModelFileMap iLoadedModelFiles;
InstanceTreeMap iInstanceMapTrees;
// Mutex for iLoadedModelFiles
ACE_Thread_Mutex LoadedModelFilesLock;
protected:
// Tree to check collision
ModelFileMap iLoadedModelFiles;
InstanceTreeMap iInstanceMapTrees;
// Mutex for iLoadedModelFiles
ACE_Thread_Mutex LoadedModelFilesLock;
bool _loadMap(uint32 mapId, const std::string& basePath, uint32 tileX, uint32 tileY);
/* void _unloadMap(uint32 pMapId, uint32 x, uint32 y); */
bool _loadMap(uint32 mapId, const std::string& basePath, uint32 tileX, uint32 tileY);
/* void _unloadMap(uint32 pMapId, uint32 x, uint32 y); */
static uint32 GetLiquidFlagsDummy(uint32) { return 0; }
static uint32 GetLiquidFlagsDummy(uint32) { return 0; }
public:
// public for debug
G3D::Vector3 convertPositionToInternalRep(float x, float y, float z) const;
static std::string getMapFileName(unsigned int mapId);
public:
// public for debug
G3D::Vector3 convertPositionToInternalRep(float x, float y, float z) const;
static std::string getMapFileName(unsigned int mapId);
VMapManager2();
~VMapManager2(void);
VMapManager2();
~VMapManager2(void);
int loadMap(const char* pBasePath, unsigned int mapId, int x, int y);
int loadMap(const char* pBasePath, unsigned int mapId, int x, int y);
void unloadMap(unsigned int mapId, int x, int y);
void unloadMap(unsigned int mapId);
void unloadMap(unsigned int mapId, int x, int y);
void unloadMap(unsigned int mapId);
bool isInLineOfSight(unsigned int mapId, float x1, float y1, float z1, float x2, float y2, float z2) ;
/**
fill the hit pos and return true, if an object was hit
*/
bool getObjectHitPos(unsigned int mapId, float x1, float y1, float z1, float x2, float y2, float z2, float& rx, float& ry, float& rz, float modifyDist);
float getHeight(unsigned int mapId, float x, float y, float z, float maxSearchDist);
bool isInLineOfSight(unsigned int mapId, float x1, float y1, float z1, float x2, float y2, float z2) ;
/**
fill the hit pos and return true, if an object was hit
*/
bool getObjectHitPos(unsigned int mapId, float x1, float y1, float z1, float x2, float y2, float z2, float& rx, float& ry, float& rz, float modifyDist);
float getHeight(unsigned int mapId, float x, float y, float z, float maxSearchDist);
bool processCommand(char* /*command*/) { return false; } // for debug and extensions
bool processCommand(char* /*command*/) { return false; } // for debug and extensions
bool getAreaInfo(unsigned int pMapId, float x, float y, float& z, uint32& flags, int32& adtId, int32& rootId, int32& groupId) const;
bool GetLiquidLevel(uint32 pMapId, float x, float y, float z, uint8 reqLiquidType, float& level, float& floor, uint32& type) const;
bool getAreaInfo(unsigned int pMapId, float x, float y, float& z, uint32& flags, int32& adtId, int32& rootId, int32& groupId) const;
bool GetLiquidLevel(uint32 pMapId, float x, float y, float z, uint8 reqLiquidType, float& level, float& floor, uint32& type) const;
WorldModel* acquireModelInstance(const std::string& basepath, const std::string& filename);
void releaseModelInstance(const std::string& filename);
WorldModel* acquireModelInstance(const std::string& basepath, const std::string& filename);
void releaseModelInstance(const std::string& filename);
// what's the use of this? o.O
virtual std::string getDirFileName(unsigned int mapId, int /*x*/, int /*y*/) const
{
return getMapFileName(mapId);
}
virtual bool existsMap(const char* basePath, unsigned int mapId, int x, int y);
public:
void getInstanceMapTree(InstanceTreeMap &instanceMapTree);
// what's the use of this? o.O
virtual std::string getDirFileName(unsigned int mapId, int /*x*/, int /*y*/) const
{
return getMapFileName(mapId);
}
virtual bool existsMap(const char* basePath, unsigned int mapId, int x, int y);
public:
void getInstanceMapTree(InstanceTreeMap& instanceMapTree);
typedef uint32(*GetLiquidFlagsFn)(uint32 liquidType);
GetLiquidFlagsFn GetLiquidFlagsPtr;
typedef uint32(*GetLiquidFlagsFn)(uint32 liquidType);
GetLiquidFlagsFn GetLiquidFlagsPtr;
};
}

View File

@@ -23,15 +23,15 @@ namespace VMAP
class MapRayCallback
{
public:
MapRayCallback(ModelInstance* val): prims(val), hit(false) {}
bool operator()(const G3D::Ray& ray, uint32 entry, float& distance, bool StopAtFirstHit)
{
bool result = prims[entry].intersectRay(ray, distance, StopAtFirstHit);
if (result)
hit = true;
return result;
}
public:
MapRayCallback(ModelInstance* val): prims(val), hit(false) {}
bool operator()(const G3D::Ray& ray, uint32 entry, float& distance, bool StopAtFirstHit)
{
bool result = prims[entry].intersectRay(ray, distance, StopAtFirstHit);
if (result)
hit = true;
return result;
}
bool didHit() { return hit; }
protected:
ModelInstance* prims;
@@ -40,36 +40,36 @@ namespace VMAP
class AreaInfoCallback
{
public:
AreaInfoCallback(ModelInstance* val): prims(val) {}
void operator()(const Vector3& point, uint32 entry)
{
public:
AreaInfoCallback(ModelInstance* val): prims(val) {}
void operator()(const Vector3& point, uint32 entry)
{
#if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS) && defined(VMAP_DEBUG)
sLog->outDebug(LOG_FILTER_MAPS, "AreaInfoCallback: trying to intersect '%s'", prims[entry].name.c_str());
sLog->outDebug(LOG_FILTER_MAPS, "AreaInfoCallback: trying to intersect '%s'", prims[entry].name.c_str());
#endif
prims[entry].intersectPoint(point, aInfo);
}
prims[entry].intersectPoint(point, aInfo);
}
ModelInstance* prims;
AreaInfo aInfo;
ModelInstance* prims;
AreaInfo aInfo;
};
class LocationInfoCallback
{
public:
LocationInfoCallback(ModelInstance* val, LocationInfo &info): prims(val), locInfo(info), result(false) {}
void operator()(const Vector3& point, uint32 entry)
{
public:
LocationInfoCallback(ModelInstance* val, LocationInfo& info): prims(val), locInfo(info), result(false) {}
void operator()(const Vector3& point, uint32 entry)
{
#if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS) && defined(VMAP_DEBUG)
sLog->outDebug(LOG_FILTER_MAPS, "LocationInfoCallback: trying to intersect '%s'", prims[entry].name.c_str());
sLog->outDebug(LOG_FILTER_MAPS, "LocationInfoCallback: trying to intersect '%s'", prims[entry].name.c_str());
#endif
if (prims[entry].GetLocationInfo(point, locInfo))
result = true;
}
if (prims[entry].GetLocationInfo(point, locInfo))
result = true;
}
ModelInstance* prims;
LocationInfo &locInfo;
bool result;
ModelInstance* prims;
LocationInfo& locInfo;
bool result;
};
//=========================================================
@@ -84,7 +84,7 @@ namespace VMAP
return tilefilename.str();
}
bool StaticMapTree::getAreaInfo(Vector3 &pos, uint32 &flags, int32 &adtId, int32 &rootId, int32 &groupId) const
bool StaticMapTree::getAreaInfo(Vector3& pos, uint32& flags, int32& adtId, int32& rootId, int32& groupId) const
{
AreaInfoCallback intersectionCallBack(iTreeValues);
iTree.intersectPoint(pos, intersectionCallBack);
@@ -100,17 +100,17 @@ namespace VMAP
return false;
}
bool StaticMapTree::GetLocationInfo(const Vector3 &pos, LocationInfo &info) const
bool StaticMapTree::GetLocationInfo(const Vector3& pos, LocationInfo& info) const
{
LocationInfoCallback intersectionCallBack(iTreeValues, info);
iTree.intersectPoint(pos, intersectionCallBack);
return intersectionCallBack.result;
}
StaticMapTree::StaticMapTree(uint32 mapID, const std::string &basePath)
StaticMapTree::StaticMapTree(uint32 mapID, const std::string& basePath)
: iMapID(mapID), iIsTiled(false), iTreeValues(0), iBasePath(basePath)
{
if (iBasePath.length() > 0 && iBasePath[iBasePath.length()-1] != '/' && iBasePath[iBasePath.length()-1] != '\\')
if (iBasePath.length() > 0 && iBasePath[iBasePath.length() - 1] != '/' && iBasePath[iBasePath.length() - 1] != '\\')
{
iBasePath.push_back('/');
}
@@ -129,7 +129,7 @@ namespace VMAP
Else, pMaxDist is not modified and returns false;
*/
bool StaticMapTree::getIntersectionTime(const G3D::Ray& pRay, float &pMaxDist, bool StopAtFirstHit) const
bool StaticMapTree::getIntersectionTime(const G3D::Ray& pRay, float& pMaxDist, bool StopAtFirstHit) const
{
float distance = pMaxDist;
MapRayCallback intersectionCallBack(iTreeValues);
@@ -153,7 +153,7 @@ namespace VMAP
if (maxDist < 1e-10f)
return true;
// direction with length of 1
G3D::Ray ray = G3D::Ray::fromOriginAndDirection(pos1, (pos2 - pos1)/maxDist);
G3D::Ray ray = G3D::Ray::fromOriginAndDirection(pos1, (pos2 - pos1) / maxDist);
if (getIntersectionTime(ray, maxDist, true))
return false;
@@ -167,7 +167,7 @@ namespace VMAP
bool StaticMapTree::getObjectHitPos(const Vector3& pPos1, const Vector3& pPos2, Vector3& pResultHitPos, float pModifyDist) const
{
bool result=false;
bool result = false;
float maxDist = (pPos2 - pPos1).magnitude();
// valid map coords should *never ever* produce float overflow, but this would produce NaNs too
ASSERT(maxDist < std::numeric_limits<float>::max());
@@ -177,7 +177,7 @@ namespace VMAP
pResultHitPos = pPos2;
return false;
}
Vector3 dir = (pPos2 - pPos1)/maxDist; // direction with length of 1
Vector3 dir = (pPos2 - pPos1) / maxDist; // direction with length of 1
G3D::Ray ray(pPos1, dir);
float dist = maxDist;
if (getIntersectionTime(ray, dist, false))
@@ -187,7 +187,7 @@ namespace VMAP
{
if ((pResultHitPos - pPos1).magnitude() > -pModifyDist)
{
pResultHitPos = pResultHitPos + dir*pModifyDist;
pResultHitPos = pResultHitPos + dir * pModifyDist;
}
else
{
@@ -196,7 +196,7 @@ namespace VMAP
}
else
{
pResultHitPos = pResultHitPos + dir*pModifyDist;
pResultHitPos = pResultHitPos + dir * pModifyDist;
}
result = true;
}
@@ -225,10 +225,10 @@ namespace VMAP
//=========================================================
bool StaticMapTree::CanLoadMap(const std::string &vmapPath, uint32 mapID, uint32 tileX, uint32 tileY)
bool StaticMapTree::CanLoadMap(const std::string& vmapPath, uint32 mapID, uint32 tileX, uint32 tileY)
{
std::string basePath = vmapPath;
if (basePath.length() > 0 && basePath[basePath.length()-1] != '/' && basePath[basePath.length()-1] != '\\')
if (basePath.length() > 0 && basePath[basePath.length() - 1] != '/' && basePath[basePath.length() - 1] != '\\')
basePath.push_back('/');
std::string fullname = basePath + VMapManager2::getMapFileName(mapID);
bool success = true;
@@ -262,7 +262,7 @@ namespace VMAP
//=========================================================
bool StaticMapTree::InitMap(const std::string &fname, VMapManager2* vm)
bool StaticMapTree::InitMap(const std::string& fname, VMapManager2* vm)
{
//VMAP_DEBUG_LOG(LOG_FILTER_MAPS, "StaticMapTree::InitMap() : initializing StaticMapTree '%s'", fname.c_str());
bool success = false;
@@ -275,7 +275,7 @@ namespace VMAP
char tiled = '\0';
if (readChunk(rf, chunk, VMAP_MAGIC, 8) && fread(&tiled, sizeof(char), 1, rf) == 1 &&
readChunk(rf, chunk, "NODE", 4) && iTree.readFromFile(rf))
readChunk(rf, chunk, "NODE", 4) && iTree.readFromFile(rf))
{
iNTreeValues = iTree.primCount();
iTreeValues = new ModelInstance[iNTreeValues];
@@ -354,7 +354,7 @@ namespace VMAP
uint32 numSpawns = 0;
if (result && fread(&numSpawns, sizeof(uint32), 1, tf) != 1)
result = false;
for (uint32 i=0; i<numSpawns && result; ++i)
for (uint32 i = 0; i < numSpawns && result; ++i)
{
// read model spawns
ModelSpawn spawn;
@@ -423,14 +423,14 @@ namespace VMAP
FILE* tf = fopen(tilefile.c_str(), "rb");
if (tf)
{
bool result=true;
bool result = true;
char chunk[8];
if (!readChunk(tf, chunk, VMAP_MAGIC, 8))
result = false;
uint32 numSpawns;
if (fread(&numSpawns, sizeof(uint32), 1, tf) != 1)
result = false;
for (uint32 i=0; i<numSpawns && result; ++i)
for (uint32 i = 0; i < numSpawns && result; ++i)
{
// read model spawns
ModelSpawn spawn;
@@ -448,7 +448,7 @@ namespace VMAP
else
{
if (!iLoadedSpawns.count(referencedNode))
sLog->outError("StaticMapTree::UnloadMapTile() : trying to unload non-referenced model '%s' (ID:%u)", spawn.name.c_str(), spawn.ID);
sLog->outError("StaticMapTree::UnloadMapTile() : trying to unload non-referenced model '%s' (ID:%u)", spawn.name.c_str(), spawn.ID);
else if (--iLoadedSpawns[referencedNode] == 0)
{
iTreeValues[referencedNode].setUnloaded();

View File

@@ -29,46 +29,46 @@ namespace VMAP
{
typedef std::unordered_map<uint32, bool> loadedTileMap;
typedef std::unordered_map<uint32, uint32> loadedSpawnMap;
private:
uint32 iMapID;
bool iIsTiled;
BIH iTree;
ModelInstance* iTreeValues; // the tree entries
uint32 iNTreeValues;
private:
uint32 iMapID;
bool iIsTiled;
BIH iTree;
ModelInstance* iTreeValues; // the tree entries
uint32 iNTreeValues;
// Store all the map tile idents that are loaded for that map
// some maps are not splitted into tiles and we have to make sure, not removing the map before all tiles are removed
// empty tiles have no tile file, hence map with bool instead of just a set (consistency check)
loadedTileMap iLoadedTiles;
// stores <tree_index, reference_count> to invalidate tree values, unload map, and to be able to report errors
loadedSpawnMap iLoadedSpawns;
std::string iBasePath;
// Store all the map tile idents that are loaded for that map
// some maps are not splitted into tiles and we have to make sure, not removing the map before all tiles are removed
// empty tiles have no tile file, hence map with bool instead of just a set (consistency check)
loadedTileMap iLoadedTiles;
// stores <tree_index, reference_count> to invalidate tree values, unload map, and to be able to report errors
loadedSpawnMap iLoadedSpawns;
std::string iBasePath;
private:
bool getIntersectionTime(const G3D::Ray& pRay, float &pMaxDist, bool StopAtFirstHit) const;
//bool containsLoadedMapTile(unsigned int pTileIdent) const { return(iLoadedMapTiles.containsKey(pTileIdent)); }
public:
static std::string getTileFileName(uint32 mapID, uint32 tileX, uint32 tileY);
static uint32 packTileID(uint32 tileX, uint32 tileY) { return tileX<<16 | tileY; }
static void unpackTileID(uint32 ID, uint32 &tileX, uint32 &tileY) { tileX = ID>>16; tileY = ID&0xFF; }
static bool CanLoadMap(const std::string &basePath, uint32 mapID, uint32 tileX, uint32 tileY);
private:
bool getIntersectionTime(const G3D::Ray& pRay, float& pMaxDist, bool StopAtFirstHit) const;
//bool containsLoadedMapTile(unsigned int pTileIdent) const { return(iLoadedMapTiles.containsKey(pTileIdent)); }
public:
static std::string getTileFileName(uint32 mapID, uint32 tileX, uint32 tileY);
static uint32 packTileID(uint32 tileX, uint32 tileY) { return tileX << 16 | tileY; }
static void unpackTileID(uint32 ID, uint32& tileX, uint32& tileY) { tileX = ID >> 16; tileY = ID & 0xFF; }
static bool CanLoadMap(const std::string& basePath, uint32 mapID, uint32 tileX, uint32 tileY);
StaticMapTree(uint32 mapID, const std::string &basePath);
~StaticMapTree();
StaticMapTree(uint32 mapID, const std::string& basePath);
~StaticMapTree();
bool isInLineOfSight(const G3D::Vector3& pos1, const G3D::Vector3& pos2) const;
bool getObjectHitPos(const G3D::Vector3& pos1, const G3D::Vector3& pos2, G3D::Vector3& pResultHitPos, float pModifyDist) const;
float getHeight(const G3D::Vector3& pPos, float maxSearchDist) const;
bool getAreaInfo(G3D::Vector3 &pos, uint32 &flags, int32 &adtId, int32 &rootId, int32 &groupId) const;
bool GetLocationInfo(const G3D::Vector3 &pos, LocationInfo &info) const;
bool isInLineOfSight(const G3D::Vector3& pos1, const G3D::Vector3& pos2) const;
bool getObjectHitPos(const G3D::Vector3& pos1, const G3D::Vector3& pos2, G3D::Vector3& pResultHitPos, float pModifyDist) const;
float getHeight(const G3D::Vector3& pPos, float maxSearchDist) const;
bool getAreaInfo(G3D::Vector3& pos, uint32& flags, int32& adtId, int32& rootId, int32& groupId) const;
bool GetLocationInfo(const G3D::Vector3& pos, LocationInfo& info) const;
bool InitMap(const std::string &fname, VMapManager2* vm);
void UnloadMap(VMapManager2* vm);
bool LoadMapTile(uint32 tileX, uint32 tileY, VMapManager2* vm);
void UnloadMapTile(uint32 tileX, uint32 tileY, VMapManager2* vm);
bool isTiled() const { return iIsTiled; }
uint32 numLoadedTiles() const { return iLoadedTiles.size(); }
void getModelInstances(ModelInstance* &models, uint32 &count);
bool InitMap(const std::string& fname, VMapManager2* vm);
void UnloadMap(VMapManager2* vm);
bool LoadMapTile(uint32 tileX, uint32 tileY, VMapManager2* vm);
void UnloadMapTile(uint32 tileX, uint32 tileY, VMapManager2* vm);
bool isTiled() const { return iIsTiled; }
uint32 numLoadedTiles() const { return iLoadedTiles.size(); }
void getModelInstances(ModelInstance*& models, uint32& count);
};
struct AreaInfo

View File

@@ -22,12 +22,12 @@ using std::pair;
template<> struct BoundsTrait<VMAP::ModelSpawn*>
{
static void getBounds(const VMAP::ModelSpawn* const &obj, G3D::AABox& out) { out = obj->getBounds(); }
static void getBounds(const VMAP::ModelSpawn* const& obj, G3D::AABox& out) { out = obj->getBounds(); }
};
namespace VMAP
{
bool readChunk(FILE* rf, char *dest, const char *compare, uint32 len)
bool readChunk(FILE* rf, char* dest, const char* compare, uint32 len)
{
if (fread(dest, sizeof(char), len, rf) != len) return false;
return memcmp(dest, compare, len) == 0;
@@ -79,7 +79,7 @@ namespace VMAP
{
/// @todo remove extractor hack and uncomment below line:
//entry->second.iPos += Vector3(533.33333f*32, 533.33333f*32, 0.f);
entry->second.iBound = entry->second.iBound + Vector3(533.33333f*32, 533.33333f*32, 0.f);
entry->second.iBound = entry->second.iBound + Vector3(533.33333f * 32, 533.33333f * 32, 0.f);
}
mapSpawns.push_back(&(entry->second));
spawnedModelFiles.insert(entry->second.name);
@@ -100,7 +100,7 @@ namespace VMAP
// ===> possibly move this code to StaticMapTree class
std::map<uint32, uint32> modelNodeIdx;
for (uint32 i=0; i<mapSpawns.size(); ++i)
for (uint32 i = 0; i < mapSpawns.size(); ++i)
modelNodeIdx.insert(pair<uint32, uint32>(mapSpawns[i]->ID, i));
// write map tree file
@@ -126,7 +126,7 @@ namespace VMAP
// global map spawns (WDT), if any (most instances)
if (success && fwrite("GOBJ", 4, 1, mapfile) != 1) success = false;
for (TileMap::iterator glob=globalRange.first; glob != globalRange.second && success; ++glob)
for (TileMap::iterator glob = globalRange.first; glob != globalRange.second && success; ++glob)
{
success = ModelSpawn::writeToFile(mapfile, map_iter->second->UniqueEntries[glob->second]);
}
@@ -136,11 +136,11 @@ namespace VMAP
// <====
// write map tile files, similar to ADT files, only with extra BSP tree node info
TileMap &tileEntries = map_iter->second->TileEntries;
TileMap& tileEntries = map_iter->second->TileEntries;
TileMap::iterator tile;
for (tile = tileEntries.begin(); tile != tileEntries.end(); ++tile)
{
const ModelSpawn &spawn = map_iter->second->UniqueEntries[tile->second];
const ModelSpawn& spawn = map_iter->second->UniqueEntries[tile->second];
if (spawn.flags & MOD_WORLDSPAWN) // WDT spawn, saved as tile 65/65 currently...
continue;
uint32 nSpawns = tileEntries.count(tile->first);
@@ -157,11 +157,11 @@ namespace VMAP
// write number of tile spawns
if (success && fwrite(&nSpawns, sizeof(uint32), 1, tilefile) != 1) success = false;
// write tile spawns
for (uint32 s=0; s<nSpawns; ++s)
for (uint32 s = 0; s < nSpawns; ++s)
{
if (s)
++tile;
const ModelSpawn &spawn2 = map_iter->second->UniqueEntries[tile->second];
const ModelSpawn& spawn2 = map_iter->second->UniqueEntries[tile->second];
success = success && ModelSpawn::writeToFile(tilefile, spawn2);
// MapTree nodes to update when loading tile:
std::map<uint32, uint32>::iterator nIdx = modelNodeIdx.find(spawn2.ID);
@@ -206,7 +206,7 @@ namespace VMAP
return false;
}
printf("Read coordinate mapping...\n");
uint32 mapID, tileX, tileY, check=0;
uint32 mapID, tileX, tileY, check = 0;
G3D::Vector3 v1, v2;
ModelSpawn spawn;
while (!feof(dirf))
@@ -221,7 +221,7 @@ namespace VMAP
if (!ModelSpawn::readFromFile(dirf, spawn))
break;
MapSpawns *current;
MapSpawns* current;
MapData::iterator map_iter = mapData.find(mapID);
if (map_iter == mapData.end())
{
@@ -237,7 +237,7 @@ namespace VMAP
return success;
}
bool TileAssembler::calculateTransformedBound(ModelSpawn &spawn)
bool TileAssembler::calculateTransformedBound(ModelSpawn& spawn)
{
std::string modelFilename(iSrcDir);
modelFilename.push_back('/');
@@ -257,9 +257,9 @@ namespace VMAP
printf("Warning: '%s' does not seem to be a M2 model!\n", modelFilename.c_str());
AABox modelBound;
bool boundEmpty=true;
bool boundEmpty = true;
for (uint32 g=0; g<groups; ++g) // should be only one for M2 files...
for (uint32 g = 0; g < groups; ++g) // should be only one for M2 files...
{
std::vector<Vector3>& vertices = raw_model.groupsArray[g].vertexArray;
@@ -275,7 +275,7 @@ namespace VMAP
Vector3 v = modelPosition.transform(vertices[i]);
if (boundEmpty)
modelBound = AABox(v, v), boundEmpty=false;
modelBound = AABox(v, v), boundEmpty = false;
else
modelBound.merge(v);
}
@@ -298,7 +298,7 @@ namespace VMAP
{
bool success = true;
std::string filename = iSrcDir;
if (filename.length() >0)
if (filename.length() > 0)
filename.push_back('/');
filename.append(pModelFilename);
@@ -348,9 +348,9 @@ namespace VMAP
while (!feof(model_list))
{
if (fread(&displayId, sizeof(uint32), 1, model_list) != 1
|| fread(&name_length, sizeof(uint32), 1, model_list) != 1
|| name_length >= sizeof(buff)
|| fread(&buff, sizeof(char), name_length, model_list) != name_length)
|| fread(&name_length, sizeof(uint32), 1, model_list) != 1
|| name_length >= sizeof(buff)
|| fread(&buff, sizeof(char), name_length, model_list) != name_length)
{
std::cout << "\nFile 'temp_gameobject_models' seems to be corrupted" << std::endl;
break;
@@ -390,12 +390,12 @@ namespace VMAP
fclose(model_list);
fclose(model_list_copy);
}
// temporary use defines to simplify read/check code (close file and return at fail)
#define READ_OR_RETURN(V, S) if (fread((V), (S), 1, rf) != 1) { \
// temporary use defines to simplify read/check code (close file and return at fail)
#define READ_OR_RETURN(V, S) if (fread((V), (S), 1, rf) != 1) { \
fclose(rf); printf("readfail, op = %i\n", readOperation); return(false); }
#define READ_OR_RETURN_WITH_DELETE(V, S) if (fread((V), (S), 1, rf) != 1) { \
#define READ_OR_RETURN_WITH_DELETE(V, S) if (fread((V), (S), 1, rf) != 1) { \
fclose(rf); printf("readfail, op = %i\n", readOperation); delete[] V; return(false); };
#define CMP_OR_RETURN(V, S) if (strcmp((V), (S)) != 0) { \
#define CMP_OR_RETURN(V, S) if (strcmp((V), (S)) != 0) { \
fclose(rf); printf("cmpfail, %s!=%s\n", V, S);return(false); }
bool GroupModel_Raw::Read(FILE* rf)
@@ -423,7 +423,7 @@ namespace VMAP
CMP_OR_RETURN(blockId, "GRP ");
READ_OR_RETURN(&blocksize, sizeof(int));
READ_OR_RETURN(&branches, sizeof(uint32));
for (uint32 b=0; b<branches; ++b)
for (uint32 b = 0; b < branches; ++b)
{
uint32 indexes;
// indexes for each branch (not used jet)
@@ -436,13 +436,13 @@ namespace VMAP
READ_OR_RETURN(&blocksize, sizeof(int));
uint32 nindexes;
READ_OR_RETURN(&nindexes, sizeof(uint32));
if (nindexes >0)
if (nindexes > 0)
{
uint16 *indexarray = new uint16[nindexes];
READ_OR_RETURN_WITH_DELETE(indexarray, nindexes*sizeof(uint16));
uint16* indexarray = new uint16[nindexes];
READ_OR_RETURN_WITH_DELETE(indexarray, nindexes * sizeof(uint16));
triangles.reserve(nindexes / 3);
for (uint32 i=0; i<nindexes; i+=3)
triangles.push_back(MeshTriangle(indexarray[i], indexarray[i+1], indexarray[i+2]));
for (uint32 i = 0; i < nindexes; i += 3)
triangles.push_back(MeshTriangle(indexarray[i], indexarray[i + 1], indexarray[i + 2]));
delete[] indexarray;
}
@@ -454,18 +454,18 @@ namespace VMAP
uint32 nvectors;
READ_OR_RETURN(&nvectors, sizeof(uint32));
if (nvectors >0)
if (nvectors > 0)
{
float *vectorarray = new float[nvectors*3];
READ_OR_RETURN_WITH_DELETE(vectorarray, nvectors*sizeof(float)*3);
for (uint32 i=0; i<nvectors; ++i)
vertexArray.push_back( Vector3(vectorarray + 3*i) );
float* vectorarray = new float[nvectors * 3];
READ_OR_RETURN_WITH_DELETE(vectorarray, nvectors * sizeof(float) * 3);
for (uint32 i = 0; i < nvectors; ++i)
vertexArray.push_back( Vector3(vectorarray + 3 * i) );
delete[] vectorarray;
}
// ----- liquid
liquid = 0;
if (liquidflags& 1)
if (liquidflags & 1)
{
WMOLiquidHeader hlq;
READ_OR_RETURN(&blockId, 4);
@@ -473,9 +473,9 @@ namespace VMAP
READ_OR_RETURN(&blocksize, sizeof(int));
READ_OR_RETURN(&hlq, sizeof(WMOLiquidHeader));
liquid = new WmoLiquid(hlq.xtiles, hlq.ytiles, Vector3(hlq.pos_x, hlq.pos_y, hlq.pos_z), hlq.type);
uint32 size = hlq.xverts*hlq.yverts;
READ_OR_RETURN(liquid->GetHeightStorage(), size*sizeof(float));
size = hlq.xtiles*hlq.ytiles;
uint32 size = hlq.xverts * hlq.yverts;
READ_OR_RETURN(liquid->GetHeightStorage(), size * sizeof(float));
size = hlq.xtiles * hlq.ytiles;
READ_OR_RETURN(liquid->GetFlagsStorage(), size);
}
@@ -488,7 +488,7 @@ namespace VMAP
delete liquid;
}
bool WorldModel_Raw::Read(const char * path)
bool WorldModel_Raw::Read(const char* path)
{
FILE* rf = fopen(path, "rb");
if (!rf)
@@ -523,6 +523,6 @@ namespace VMAP
}
// drop of temporary use defines
#undef READ_OR_RETURN
#undef CMP_OR_RETURN
#undef READ_OR_RETURN
#undef CMP_OR_RETURN
}

View File

@@ -25,19 +25,19 @@ namespace VMAP
class ModelPosition
{
private:
G3D::Matrix3 iRotation;
public:
ModelPosition(): iScale(0.0f) { }
G3D::Vector3 iPos;
G3D::Vector3 iDir;
float iScale;
void init()
{
iRotation = G3D::Matrix3::fromEulerAnglesZYX(G3D::pif()*iDir.y/180.f, G3D::pif()*iDir.x/180.f, G3D::pif()*iDir.z/180.f);
}
G3D::Vector3 transform(const G3D::Vector3& pIn) const;
void moveToBasePos(const G3D::Vector3& pBasePos) { iPos -= pBasePos; }
private:
G3D::Matrix3 iRotation;
public:
ModelPosition(): iScale(0.0f) { }
G3D::Vector3 iPos;
G3D::Vector3 iDir;
float iScale;
void init()
{
iRotation = G3D::Matrix3::fromEulerAnglesZYX(G3D::pif() * iDir.y / 180.f, G3D::pif() * iDir.x / 180.f, G3D::pif() * iDir.z / 180.f);
}
G3D::Vector3 transform(const G3D::Vector3& pIn) const;
void moveToBasePos(const G3D::Vector3& pBasePos) { iPos -= pBasePos; }
};
typedef std::map<uint32, ModelSpawn> UniqueEntryMap;
@@ -75,32 +75,32 @@ namespace VMAP
uint32 RootWMOID;
std::vector<GroupModel_Raw> groupsArray;
bool Read(const char * path);
bool Read(const char* path);
};
class TileAssembler
{
private:
std::string iDestDir;
std::string iSrcDir;
bool (*iFilterMethod)(char *pName);
G3D::Table<std::string, unsigned int > iUniqueNameIds;
unsigned int iCurrentUniqueNameId;
MapData mapData;
std::set<std::string> spawnedModelFiles;
private:
std::string iDestDir;
std::string iSrcDir;
bool (*iFilterMethod)(char* pName);
G3D::Table<std::string, unsigned int > iUniqueNameIds;
unsigned int iCurrentUniqueNameId;
MapData mapData;
std::set<std::string> spawnedModelFiles;
public:
TileAssembler(const std::string& pSrcDirName, const std::string& pDestDirName);
virtual ~TileAssembler();
public:
TileAssembler(const std::string& pSrcDirName, const std::string& pDestDirName);
virtual ~TileAssembler();
bool convertWorld2();
bool readMapSpawns();
bool calculateTransformedBound(ModelSpawn &spawn);
void exportGameobjectModels();
bool convertWorld2();
bool readMapSpawns();
bool calculateTransformedBound(ModelSpawn& spawn);
void exportGameobjectModels();
bool convertRawFile(const std::string& pModelFilename);
void setModelNameFilterMethod(bool (*pFilterMethod)(char *pName)) { iFilterMethod = pFilterMethod; }
std::string getDirEntryNameFromModName(unsigned int pMapId, const std::string& pModPosName);
bool convertRawFile(const std::string& pModelFilename);
void setModelNameFilterMethod(bool (*pFilterMethod)(char* pName)) { iFilterMethod = pFilterMethod; }
std::string getDirEntryNameFromModName(unsigned int pMapId, const std::string& pModPosName);
};
} // VMAP

View File

@@ -36,9 +36,9 @@ ModelList model_list;
void LoadGameObjectModelList()
{
//#ifndef NO_CORE_FUNCS
//#ifndef NO_CORE_FUNCS
uint32 oldMSTime = getMSTime();
//#endif
//#endif
FILE* model_list_file = fopen((sWorld->GetDataPath() + "vmaps/" + VMAP::GAMEOBJECT_MODELS).c_str(), "rb");
if (!model_list_file)
@@ -57,10 +57,10 @@ void LoadGameObjectModelList()
break;
if (fread(&name_length, sizeof(uint32), 1, model_list_file) != 1
|| name_length >= sizeof(buff)
|| fread(&buff, sizeof(char), name_length, model_list_file) != name_length
|| fread(&v1, sizeof(Vector3), 1, model_list_file) != 1
|| fread(&v2, sizeof(Vector3), 1, model_list_file) != 1)
|| name_length >= sizeof(buff)
|| fread(&buff, sizeof(char), name_length, model_list_file) != name_length
|| fread(&v1, sizeof(Vector3), 1, model_list_file) != 1
|| fread(&v2, sizeof(Vector3), 1, model_list_file) != 1)
{
sLog->outError("File '%s' seems to be corrupted!", VMAP::GAMEOBJECT_MODELS);
break;
@@ -108,7 +108,7 @@ bool GameObjectModel::initialize(const GameObject& go, const GameObjectDisplayIn
//ID = 0;
iPos = Vector3(go.GetPositionX(), go.GetPositionY(), go.GetPositionZ());
// pussywizard:
// pussywizard:
phasemask = (go.GetGoState() == GO_STATE_READY || go.IsTransport()) ? go.GetPhaseMask() : 0;
iScale = go.GetFloatValue(OBJECT_FIELD_SCALE_X);

View File

@@ -14,10 +14,10 @@ using G3D::Ray;
namespace VMAP
{
ModelInstance::ModelInstance(const ModelSpawn &spawn, WorldModel* model): ModelSpawn(spawn), iModel(model)
ModelInstance::ModelInstance(const ModelSpawn& spawn, WorldModel* model): ModelSpawn(spawn), iModel(model)
{
iInvRot = G3D::Matrix3::fromEulerAnglesZYX(G3D::pi()*iRot.y/180.f, G3D::pi()*iRot.x/180.f, G3D::pi()*iRot.z/180.f).inverse();
iInvScale = 1.f/iScale;
iInvRot = G3D::Matrix3::fromEulerAnglesZYX(G3D::pi() * iRot.y / 180.f, G3D::pi() * iRot.x / 180.f, G3D::pi() * iRot.z / 180.f).inverse();
iInvScale = 1.f / iScale;
}
bool ModelInstance::intersectRay(const G3D::Ray& pRay, float& pMaxDist, bool StopAtFirstHit) const
@@ -30,16 +30,16 @@ namespace VMAP
float time = pRay.intersectionTime(iBound);
if (time == G3D::inf())
{
// std::cout << "Ray does not hit '" << name << "'\n";
// std::cout << "Ray does not hit '" << name << "'\n";
return false;
}
// std::cout << "Ray crosses bound of '" << name << "'\n";
/* std::cout << "ray from:" << pRay.origin().x << ", " << pRay.origin().y << ", " << pRay.origin().z
<< " dir:" << pRay.direction().x << ", " << pRay.direction().y << ", " << pRay.direction().z
<< " t/tmax:" << time << '/' << pMaxDist;
std::cout << "\nBound lo:" << iBound.low().x << ", " << iBound.low().y << ", " << iBound.low().z << " hi: "
<< iBound.high().x << ", " << iBound.high().y << ", " << iBound.high().z << std::endl; */
// std::cout << "Ray crosses bound of '" << name << "'\n";
/* std::cout << "ray from:" << pRay.origin().x << ", " << pRay.origin().y << ", " << pRay.origin().z
<< " dir:" << pRay.direction().x << ", " << pRay.direction().y << ", " << pRay.direction().z
<< " t/tmax:" << time << '/' << pMaxDist;
std::cout << "\nBound lo:" << iBound.low().x << ", " << iBound.low().y << ", " << iBound.low().z << " hi: "
<< iBound.high().x << ", " << iBound.high().y << ", " << iBound.high().z << std::endl; */
// child bounds are defined in object space:
Vector3 p = iInvRot * (pRay.origin() - iPos) * iInvScale;
Ray modRay(p, iInvRot * pRay.direction());
@@ -53,7 +53,7 @@ namespace VMAP
return hit;
}
void ModelInstance::intersectPoint(const G3D::Vector3& p, AreaInfo &info) const
void ModelInstance::intersectPoint(const G3D::Vector3& p, AreaInfo& info) const
{
if (!iModel)
{
@@ -87,7 +87,7 @@ namespace VMAP
}
}
bool ModelInstance::GetLocationInfo(const G3D::Vector3& p, LocationInfo &info) const
bool ModelInstance::GetLocationInfo(const G3D::Vector3& p, LocationInfo& info) const
{
if (!iModel)
{
@@ -123,7 +123,7 @@ namespace VMAP
return false;
}
bool ModelInstance::GetLiquidLevel(const G3D::Vector3& p, LocationInfo &info, float &liqHeight) const
bool ModelInstance::GetLiquidLevel(const G3D::Vector3& p, LocationInfo& info, float& liqHeight) const
{
// child bounds are defined in object space:
Vector3 pModel = iInvRot * (p - iPos) * iInvScale;
@@ -139,7 +139,7 @@ namespace VMAP
return false;
}
bool ModelSpawn::readFromFile(FILE* rf, ModelSpawn &spawn)
bool ModelSpawn::readFromFile(FILE* rf, ModelSpawn& spawn)
{
uint32 check = 0, nameLen;
check += fread(&spawn.flags, sizeof(uint32), 1, rf);
@@ -185,9 +185,9 @@ namespace VMAP
return true;
}
bool ModelSpawn::writeToFile(FILE* wf, const ModelSpawn &spawn)
bool ModelSpawn::writeToFile(FILE* wf, const ModelSpawn& spawn)
{
uint32 check=0;
uint32 check = 0;
check += fwrite(&spawn.flags, sizeof(uint32), 1, wf);
check += fwrite(&spawn.adtId, sizeof(uint16), 1, wf);
check += fwrite(&spawn.ID, sizeof(uint32), 1, wf);

View File

@@ -23,47 +23,47 @@ namespace VMAP
enum ModelFlags
{
MOD_M2 = 1,
MOD_WORLDSPAWN = 1<<1,
MOD_HAS_BOUND = 1<<2
MOD_WORLDSPAWN = 1 << 1,
MOD_HAS_BOUND = 1 << 2
};
class ModelSpawn
{
public:
//mapID, tileX, tileY, Flags, ID, Pos, Rot, Scale, Bound_lo, Bound_hi, name
uint32 flags;
uint16 adtId;
uint32 ID;
G3D::Vector3 iPos;
G3D::Vector3 iRot;
float iScale;
G3D::AABox iBound;
std::string name;
bool operator==(const ModelSpawn &other) const { return ID == other.ID; }
//uint32 hashCode() const { return ID; }
// temp?
const G3D::AABox& getBounds() const { return iBound; }
public:
//mapID, tileX, tileY, Flags, ID, Pos, Rot, Scale, Bound_lo, Bound_hi, name
uint32 flags;
uint16 adtId;
uint32 ID;
G3D::Vector3 iPos;
G3D::Vector3 iRot;
float iScale;
G3D::AABox iBound;
std::string name;
bool operator==(const ModelSpawn& other) const { return ID == other.ID; }
//uint32 hashCode() const { return ID; }
// temp?
const G3D::AABox& getBounds() const { return iBound; }
static bool readFromFile(FILE* rf, ModelSpawn &spawn);
static bool writeToFile(FILE* rw, const ModelSpawn &spawn);
static bool readFromFile(FILE* rf, ModelSpawn& spawn);
static bool writeToFile(FILE* rw, const ModelSpawn& spawn);
};
class ModelInstance: public ModelSpawn
{
public:
ModelInstance(): iInvScale(0.0f), iModel(0) { }
ModelInstance(const ModelSpawn &spawn, WorldModel* model);
void setUnloaded() { iModel = 0; }
bool intersectRay(const G3D::Ray& pRay, float& pMaxDist, bool StopAtFirstHit) const;
void intersectPoint(const G3D::Vector3& p, AreaInfo &info) const;
bool GetLocationInfo(const G3D::Vector3& p, LocationInfo &info) const;
bool GetLiquidLevel(const G3D::Vector3& p, LocationInfo &info, float &liqHeight) const;
protected:
G3D::Matrix3 iInvRot;
float iInvScale;
WorldModel* iModel;
public:
WorldModel* getWorldModel();
public:
ModelInstance(): iInvScale(0.0f), iModel(0) { }
ModelInstance(const ModelSpawn& spawn, WorldModel* model);
void setUnloaded() { iModel = 0; }
bool intersectRay(const G3D::Ray& pRay, float& pMaxDist, bool StopAtFirstHit) const;
void intersectPoint(const G3D::Vector3& p, AreaInfo& info) const;
bool GetLocationInfo(const G3D::Vector3& p, LocationInfo& info) const;
bool GetLiquidLevel(const G3D::Vector3& p, LocationInfo& info, float& liqHeight) const;
protected:
G3D::Matrix3 iInvRot;
float iInvScale;
WorldModel* iModel;
public:
WorldModel* getWorldModel();
};
} // namespace VMAP

View File

@@ -19,7 +19,7 @@ template<> struct BoundsTrait<VMAP::GroupModel>
namespace VMAP
{
bool IntersectTriangle(const MeshTriangle &tri, std::vector<Vector3>::const_iterator points, const G3D::Ray &ray, float &distance)
bool IntersectTriangle(const MeshTriangle& tri, std::vector<Vector3>::const_iterator points, const G3D::Ray& ray, float& distance)
{
static const float EPS = 1e-5f;
@@ -30,7 +30,8 @@ namespace VMAP
const Vector3 p(ray.direction().cross(e2));
const float a = e1.dot(p);
if (fabs(a) < EPS) {
if (fabs(a) < EPS)
{
// Determinant is ill-conditioned; abort early
return false;
}
@@ -39,7 +40,8 @@ namespace VMAP
const Vector3 s(ray.origin() - points[tri.idx0]);
const float u = f * s.dot(p);
if ((u < 0.0f) || (u > 1.0f)) {
if ((u < 0.0f) || (u > 1.0f))
{
// We hit the plane of the m_geometry, but outside the m_geometry
return false;
}
@@ -47,7 +49,8 @@ namespace VMAP
const Vector3 q(s.cross(e1));
const float v = f * ray.direction().dot(q);
if ((v < 0.0f) || ((u + v) > 1.0f)) {
if ((v < 0.0f) || ((u + v) > 1.0f))
{
// We hit the plane of the triangle, but outside the triangle
return false;
}
@@ -71,32 +74,32 @@ namespace VMAP
class TriBoundFunc
{
public:
TriBoundFunc(std::vector<Vector3> &vert): vertices(vert.begin()) { }
void operator()(const MeshTriangle &tri, G3D::AABox &out) const
{
G3D::Vector3 lo = vertices[tri.idx0];
G3D::Vector3 hi = lo;
public:
TriBoundFunc(std::vector<Vector3>& vert): vertices(vert.begin()) { }
void operator()(const MeshTriangle& tri, G3D::AABox& out) const
{
G3D::Vector3 lo = vertices[tri.idx0];
G3D::Vector3 hi = lo;
lo = (lo.min(vertices[tri.idx1])).min(vertices[tri.idx2]);
hi = (hi.max(vertices[tri.idx1])).max(vertices[tri.idx2]);
lo = (lo.min(vertices[tri.idx1])).min(vertices[tri.idx2]);
hi = (hi.max(vertices[tri.idx1])).max(vertices[tri.idx2]);
out = G3D::AABox(lo, hi);
}
protected:
const std::vector<Vector3>::const_iterator vertices;
out = G3D::AABox(lo, hi);
}
protected:
const std::vector<Vector3>::const_iterator vertices;
};
// ===================== WmoLiquid ==================================
WmoLiquid::WmoLiquid(uint32 width, uint32 height, const Vector3 &corner, uint32 type):
WmoLiquid::WmoLiquid(uint32 width, uint32 height, const Vector3& corner, uint32 type):
iTilesX(width), iTilesY(height), iCorner(corner), iType(type)
{
iHeight = new float[(width+1)*(height+1)];
iFlags = new uint8[width*height];
iHeight = new float[(width + 1) * (height + 1)];
iFlags = new uint8[width * height];
}
WmoLiquid::WmoLiquid(const WmoLiquid &other): iHeight(0), iFlags(0)
WmoLiquid::WmoLiquid(const WmoLiquid& other): iHeight(0), iFlags(0)
{
*this = other; // use assignment operator...
}
@@ -107,7 +110,7 @@ namespace VMAP
delete[] iFlags;
}
WmoLiquid& WmoLiquid::operator=(const WmoLiquid &other)
WmoLiquid& WmoLiquid::operator=(const WmoLiquid& other)
{
if (this == &other)
return *this;
@@ -119,8 +122,8 @@ namespace VMAP
delete[] iFlags;
if (other.iHeight)
{
iHeight = new float[(iTilesX+1)*(iTilesY+1)];
memcpy(iHeight, other.iHeight, (iTilesX+1)*(iTilesY+1)*sizeof(float));
iHeight = new float[(iTilesX + 1) * (iTilesY + 1)];
memcpy(iHeight, other.iHeight, (iTilesX + 1) * (iTilesY + 1)*sizeof(float));
}
else
iHeight = 0;
@@ -134,20 +137,20 @@ namespace VMAP
return *this;
}
bool WmoLiquid::GetLiquidHeight(const Vector3 &pos, float &liqHeight) const
bool WmoLiquid::GetLiquidHeight(const Vector3& pos, float& liqHeight) const
{
float tx_f = (pos.x - iCorner.x)/LIQUID_TILE_SIZE;
float tx_f = (pos.x - iCorner.x) / LIQUID_TILE_SIZE;
uint32 tx = uint32(tx_f);
if (tx_f < 0.0f || tx >= iTilesX)
return false;
float ty_f = (pos.y - iCorner.y)/LIQUID_TILE_SIZE;
float ty_f = (pos.y - iCorner.y) / LIQUID_TILE_SIZE;
uint32 ty = uint32(ty_f);
if (ty_f < 0.0f || ty >= iTilesY)
return false;
// check if tile shall be used for liquid level
// checking for 0x08 *might* be enough, but disabled tiles always are 0x?F:
if ((iFlags[tx + ty*iTilesX] & 0x0F) == 0x0F)
if ((iFlags[tx + ty * iTilesX] & 0x0F) == 0x0F)
return false;
// (dx, dy) coordinates inside tile, in [0, 1]^2
@@ -170,14 +173,14 @@ namespace VMAP
const uint32 rowOffset = iTilesX + 1;
if (dx > dy) // case (a)
{
float sx = iHeight[tx+1 + ty * rowOffset] - iHeight[tx + ty * rowOffset];
float sy = iHeight[tx+1 + (ty+1) * rowOffset] - iHeight[tx+1 + ty * rowOffset];
float sx = iHeight[tx + 1 + ty * rowOffset] - iHeight[tx + ty * rowOffset];
float sy = iHeight[tx + 1 + (ty + 1) * rowOffset] - iHeight[tx + 1 + ty * rowOffset];
liqHeight = iHeight[tx + ty * rowOffset] + dx * sx + dy * sy;
}
else // case (b)
{
float sx = iHeight[tx+1 + (ty+1) * rowOffset] - iHeight[tx + (ty+1) * rowOffset];
float sy = iHeight[tx + (ty+1) * rowOffset] - iHeight[tx + ty * rowOffset];
float sx = iHeight[tx + 1 + (ty + 1) * rowOffset] - iHeight[tx + (ty + 1) * rowOffset];
float sy = iHeight[tx + (ty + 1) * rowOffset] - iHeight[tx + ty * rowOffset];
liqHeight = iHeight[tx + ty * rowOffset] + dx * sx + dy * sy;
}
return true;
@@ -186,23 +189,23 @@ namespace VMAP
uint32 WmoLiquid::GetFileSize()
{
return 2 * sizeof(uint32) +
sizeof(Vector3) +
(iTilesX + 1)*(iTilesY + 1) * sizeof(float) +
iTilesX * iTilesY;
sizeof(Vector3) +
(iTilesX + 1) * (iTilesY + 1) * sizeof(float) +
iTilesX * iTilesY;
}
bool WmoLiquid::writeToFile(FILE* wf)
{
bool result = false;
if (fwrite(&iTilesX, sizeof(uint32), 1, wf) == 1 &&
fwrite(&iTilesY, sizeof(uint32), 1, wf) == 1 &&
fwrite(&iCorner, sizeof(Vector3), 1, wf) == 1 &&
fwrite(&iType, sizeof(uint32), 1, wf) == 1)
fwrite(&iTilesY, sizeof(uint32), 1, wf) == 1 &&
fwrite(&iCorner, sizeof(Vector3), 1, wf) == 1 &&
fwrite(&iType, sizeof(uint32), 1, wf) == 1)
{
uint32 size = (iTilesX + 1) * (iTilesY + 1);
if (fwrite(iHeight, sizeof(float), size, wf) == size)
{
size = iTilesX*iTilesY;
size = iTilesX * iTilesY;
result = fwrite(iFlags, sizeof(uint8), size, wf) == size;
}
}
@@ -210,15 +213,15 @@ namespace VMAP
return result;
}
bool WmoLiquid::readFromFile(FILE* rf, WmoLiquid* &out)
bool WmoLiquid::readFromFile(FILE* rf, WmoLiquid*& out)
{
bool result = false;
WmoLiquid* liquid = new WmoLiquid();
if (fread(&liquid->iTilesX, sizeof(uint32), 1, rf) == 1 &&
fread(&liquid->iTilesY, sizeof(uint32), 1, rf) == 1 &&
fread(&liquid->iCorner, sizeof(Vector3), 1, rf) == 1 &&
fread(&liquid->iType, sizeof(uint32), 1, rf) == 1)
fread(&liquid->iTilesY, sizeof(uint32), 1, rf) == 1 &&
fread(&liquid->iCorner, sizeof(Vector3), 1, rf) == 1 &&
fread(&liquid->iType, sizeof(uint32), 1, rf) == 1)
{
uint32 size = (liquid->iTilesX + 1) * (liquid->iTilesY + 1);
liquid->iHeight = new float[size];
@@ -240,7 +243,7 @@ namespace VMAP
// ===================== GroupModel ==================================
GroupModel::GroupModel(const GroupModel &other):
GroupModel::GroupModel(const GroupModel& other):
iBound(other.iBound), iMogpFlags(other.iMogpFlags), iGroupWMOID(other.iGroupWMOID),
vertices(other.vertices), triangles(other.triangles), meshTree(other.meshTree), iLiquid(0)
{
@@ -248,7 +251,7 @@ namespace VMAP
iLiquid = new WmoLiquid(*other.iLiquid);
}
void GroupModel::setMeshData(std::vector<Vector3> &vert, std::vector<MeshTriangle> &tri)
void GroupModel::setMeshData(std::vector<Vector3>& vert, std::vector<MeshTriangle>& tri)
{
vertices.swap(vert);
triangles.swap(tri);
@@ -268,7 +271,7 @@ namespace VMAP
// write vertices
if (result && fwrite("VERT", 1, 4, wf) != 4) result = false;
count = vertices.size();
chunkSize = sizeof(uint32)+ sizeof(Vector3)*count;
chunkSize = sizeof(uint32) + sizeof(Vector3) * count;
if (result && fwrite(&chunkSize, sizeof(uint32), 1, wf) != 1) result = false;
if (result && fwrite(&count, sizeof(uint32), 1, wf) != 1) result = false;
if (!count) // models without (collision) geometry end here, unsure if they are useful
@@ -278,7 +281,7 @@ namespace VMAP
// write triangle mesh
if (result && fwrite("TRIM", 1, 4, wf) != 4) result = false;
count = triangles.size();
chunkSize = sizeof(uint32)+ sizeof(MeshTriangle)*count;
chunkSize = sizeof(uint32) + sizeof(MeshTriangle) * count;
if (result && fwrite(&chunkSize, sizeof(uint32), 1, wf) != 1) result = false;
if (result && fwrite(&count, sizeof(uint32), 1, wf) != 1) result = false;
if (result && fwrite(&triangles[0], sizeof(MeshTriangle), count, wf) != count) result = false;
@@ -347,12 +350,12 @@ namespace VMAP
struct GModelRayCallback
{
GModelRayCallback(const std::vector<MeshTriangle> &tris, const std::vector<Vector3> &vert):
GModelRayCallback(const std::vector<MeshTriangle>& tris, const std::vector<Vector3>& vert):
vertices(vert.begin()), triangles(tris.begin()), hit(false) { }
bool operator()(const G3D::Ray& ray, uint32 entry, float& distance, bool /*StopAtFirstHit*/)
{
bool result = IntersectTriangle(triangles[entry], vertices, ray, distance);
if (result) hit=true;
if (result) hit = true;
return hit;
}
std::vector<Vector3>::const_iterator vertices;
@@ -360,7 +363,7 @@ namespace VMAP
bool hit;
};
bool GroupModel::IntersectRay(const G3D::Ray &ray, float &distance, bool stopAtFirstHit) const
bool GroupModel::IntersectRay(const G3D::Ray& ray, float& distance, bool stopAtFirstHit) const
{
if (triangles.empty())
return false;
@@ -370,7 +373,7 @@ namespace VMAP
return callback.hit;
}
bool GroupModel::IsInsideObject(const Vector3 &pos, const Vector3 &down, float &z_dist) const
bool GroupModel::IsInsideObject(const Vector3& pos, const Vector3& down, float& z_dist) const
{
if (triangles.empty() || !iBound.contains(pos))
return false;
@@ -384,7 +387,7 @@ namespace VMAP
return hit;
}
bool GroupModel::GetLiquidLevel(const Vector3 &pos, float &liqHeight) const
bool GroupModel::GetLiquidLevel(const Vector3& pos, float& liqHeight) const
{
if (iLiquid)
return iLiquid->GetLiquidHeight(pos, liqHeight);
@@ -400,7 +403,7 @@ namespace VMAP
// ===================== WorldModel ==================================
void WorldModel::setGroupModels(std::vector<GroupModel> &models)
void WorldModel::setGroupModels(std::vector<GroupModel>& models)
{
groupModels.swap(models);
groupTree.build(groupModels, BoundsTrait<GroupModel>::getBounds, 1);
@@ -408,18 +411,18 @@ namespace VMAP
struct WModelRayCallBack
{
WModelRayCallBack(const std::vector<GroupModel> &mod): models(mod.begin()), hit(false) { }
WModelRayCallBack(const std::vector<GroupModel>& mod): models(mod.begin()), hit(false) { }
bool operator()(const G3D::Ray& ray, uint32 entry, float& distance, bool StopAtFirstHit)
{
bool result = models[entry].IntersectRay(ray, distance, StopAtFirstHit);
if (result) hit=true;
if (result) hit = true;
return hit;
}
std::vector<GroupModel>::const_iterator models;
bool hit;
};
bool WorldModel::IntersectRay(const G3D::Ray &ray, float &distance, bool stopAtFirstHit) const
bool WorldModel::IntersectRay(const G3D::Ray& ray, float& distance, bool stopAtFirstHit) const
{
// small M2 workaround, maybe better make separate class with virtual intersection funcs
// in any case, there's no need to use a bound tree if we only have one submodel
@@ -431,44 +434,45 @@ namespace VMAP
return isc.hit;
}
class WModelAreaCallback {
public:
WModelAreaCallback(const std::vector<GroupModel> &vals, const Vector3 &down):
prims(vals.begin()), hit(vals.end()), minVol(G3D::inf()), zDist(G3D::inf()), zVec(down) { }
std::vector<GroupModel>::const_iterator prims;
std::vector<GroupModel>::const_iterator hit;
float minVol;
float zDist;
Vector3 zVec;
void operator()(const Vector3& point, uint32 entry)
class WModelAreaCallback
{
public:
WModelAreaCallback(const std::vector<GroupModel>& vals, const Vector3& down):
prims(vals.begin()), hit(vals.end()), minVol(G3D::inf()), zDist(G3D::inf()), zVec(down) { }
std::vector<GroupModel>::const_iterator prims;
std::vector<GroupModel>::const_iterator hit;
float minVol;
float zDist;
Vector3 zVec;
void operator()(const Vector3& point, uint32 entry)
{
float group_Z;
//float pVol = prims[entry].GetBound().volume();
//if (pVol < minVol)
//{
/* if (prims[entry].iBound.contains(point)) */
if (prims[entry].IsInsideObject(point, zVec, group_Z))
{
float group_Z;
//float pVol = prims[entry].GetBound().volume();
//if (pVol < minVol)
//{
/* if (prims[entry].iBound.contains(point)) */
if (prims[entry].IsInsideObject(point, zVec, group_Z))
{
//minVol = pVol;
//hit = prims + entry;
if (group_Z < zDist)
{
zDist = group_Z;
hit = prims + entry;
}
//minVol = pVol;
//hit = prims + entry;
if (group_Z < zDist)
{
zDist = group_Z;
hit = prims + entry;
}
#ifdef VMAP_DEBUG
const GroupModel &gm = prims[entry];
printf("%10u %8X %7.3f, %7.3f, %7.3f | %7.3f, %7.3f, %7.3f | z=%f, p_z=%f\n", gm.GetWmoID(), gm.GetMogpFlags(),
gm.GetBound().low().x, gm.GetBound().low().y, gm.GetBound().low().z,
gm.GetBound().high().x, gm.GetBound().high().y, gm.GetBound().high().z, group_Z, point.z);
const GroupModel& gm = prims[entry];
printf("%10u %8X %7.3f, %7.3f, %7.3f | %7.3f, %7.3f, %7.3f | z=%f, p_z=%f\n", gm.GetWmoID(), gm.GetMogpFlags(),
gm.GetBound().low().x, gm.GetBound().low().y, gm.GetBound().low().z,
gm.GetBound().high().x, gm.GetBound().high().y, gm.GetBound().high().z, group_Z, point.z);
#endif
}
//}
//std::cout << "trying to intersect '" << prims[entry].name << "'\n";
}
//}
//std::cout << "trying to intersect '" << prims[entry].name << "'\n";
}
};
bool WorldModel::IntersectPoint(const G3D::Vector3 &p, const G3D::Vector3 &down, float &dist, AreaInfo &info) const
bool WorldModel::IntersectPoint(const G3D::Vector3& p, const G3D::Vector3& down, float& dist, AreaInfo& info) const
{
if (groupModels.empty())
return false;
@@ -487,7 +491,7 @@ namespace VMAP
return false;
}
bool WorldModel::GetLocationInfo(const G3D::Vector3 &p, const G3D::Vector3 &down, float &dist, LocationInfo &info) const
bool WorldModel::GetLocationInfo(const G3D::Vector3& p, const G3D::Vector3& down, float& dist, LocationInfo& info) const
{
if (groupModels.empty())
return false;
@@ -503,7 +507,7 @@ namespace VMAP
return false;
}
bool WorldModel::writeFile(const std::string &filename)
bool WorldModel::writeFile(const std::string& filename)
{
FILE* wf = fopen(filename.c_str(), "wb");
if (!wf)
@@ -517,14 +521,14 @@ namespace VMAP
if (result && fwrite(&RootWMOID, sizeof(uint32), 1, wf) != 1) result = false;
// write group models
count=groupModels.size();
count = groupModels.size();
if (count)
{
if (result && fwrite("GMOD", 1, 4, wf) != 4) result = false;
//chunkSize = sizeof(uint32)+ sizeof(GroupModel)*count;
//if (result && fwrite(&chunkSize, sizeof(uint32), 1, wf) != 1) result = false;
if (result && fwrite(&count, sizeof(uint32), 1, wf) != 1) result = false;
for (uint32 i=0; i<groupModels.size() && result; ++i)
for (uint32 i = 0; i < groupModels.size() && result; ++i)
result = groupModels[i].writeToFile(wf);
// write group BIH
@@ -536,7 +540,7 @@ namespace VMAP
return result;
}
bool WorldModel::readFile(const std::string &filename)
bool WorldModel::readFile(const std::string& filename)
{
FILE* rf = fopen(filename.c_str(), "rb");
if (!rf)
@@ -560,7 +564,7 @@ namespace VMAP
if (result && fread(&count, sizeof(uint32), 1, rf) != 1) result = false;
if (result) groupModels.resize(count);
//if (result && fread(&groupModels[0], sizeof(GroupModel), count, rf) != count) result = false;
for (uint32 i=0; i<count && result; ++i)
for (uint32 i = 0; i < count && result; ++i)
result = groupModels[i].readFromFile(rf);
// read group BIH

View File

@@ -23,94 +23,94 @@ namespace VMAP
class MeshTriangle
{
public:
MeshTriangle() : idx0(0), idx1(0), idx2(0) { }
MeshTriangle(uint32 na, uint32 nb, uint32 nc): idx0(na), idx1(nb), idx2(nc) { }
public:
MeshTriangle() : idx0(0), idx1(0), idx2(0) { }
MeshTriangle(uint32 na, uint32 nb, uint32 nc): idx0(na), idx1(nb), idx2(nc) { }
uint32 idx0;
uint32 idx1;
uint32 idx2;
uint32 idx0;
uint32 idx1;
uint32 idx2;
};
class WmoLiquid
{
public:
WmoLiquid(uint32 width, uint32 height, const G3D::Vector3 &corner, uint32 type);
WmoLiquid(const WmoLiquid &other);
~WmoLiquid();
WmoLiquid& operator=(const WmoLiquid &other);
bool GetLiquidHeight(const G3D::Vector3 &pos, float &liqHeight) const;
uint32 GetType() const { return iType; }
float *GetHeightStorage() { return iHeight; }
uint8 *GetFlagsStorage() { return iFlags; }
uint32 GetFileSize();
bool writeToFile(FILE* wf);
static bool readFromFile(FILE* rf, WmoLiquid* &liquid);
private:
WmoLiquid(): iTilesX(0), iTilesY(0), iType(0), iHeight(0), iFlags(0) { }
uint32 iTilesX; //!< number of tiles in x direction, each
uint32 iTilesY;
G3D::Vector3 iCorner; //!< the lower corner
uint32 iType; //!< liquid type
float *iHeight; //!< (tilesX + 1)*(tilesY + 1) height values
uint8 *iFlags; //!< info if liquid tile is used
public:
void getPosInfo(uint32 &tilesX, uint32 &tilesY, G3D::Vector3 &corner) const;
public:
WmoLiquid(uint32 width, uint32 height, const G3D::Vector3& corner, uint32 type);
WmoLiquid(const WmoLiquid& other);
~WmoLiquid();
WmoLiquid& operator=(const WmoLiquid& other);
bool GetLiquidHeight(const G3D::Vector3& pos, float& liqHeight) const;
uint32 GetType() const { return iType; }
float* GetHeightStorage() { return iHeight; }
uint8* GetFlagsStorage() { return iFlags; }
uint32 GetFileSize();
bool writeToFile(FILE* wf);
static bool readFromFile(FILE* rf, WmoLiquid*& liquid);
private:
WmoLiquid(): iTilesX(0), iTilesY(0), iType(0), iHeight(0), iFlags(0) { }
uint32 iTilesX; //!< number of tiles in x direction, each
uint32 iTilesY;
G3D::Vector3 iCorner; //!< the lower corner
uint32 iType; //!< liquid type
float* iHeight; //!< (tilesX + 1)*(tilesY + 1) height values
uint8* iFlags; //!< info if liquid tile is used
public:
void getPosInfo(uint32& tilesX, uint32& tilesY, G3D::Vector3& corner) const;
};
/*! holding additional info for WMO group files */
class GroupModel
{
public:
GroupModel(): iMogpFlags(0), iGroupWMOID(0), iLiquid(0) { }
GroupModel(const GroupModel &other);
GroupModel(uint32 mogpFlags, uint32 groupWMOID, const G3D::AABox &bound):
iBound(bound), iMogpFlags(mogpFlags), iGroupWMOID(groupWMOID), iLiquid(0) { }
~GroupModel() { delete iLiquid; }
public:
GroupModel(): iMogpFlags(0), iGroupWMOID(0), iLiquid(0) { }
GroupModel(const GroupModel& other);
GroupModel(uint32 mogpFlags, uint32 groupWMOID, const G3D::AABox& bound):
iBound(bound), iMogpFlags(mogpFlags), iGroupWMOID(groupWMOID), iLiquid(0) { }
~GroupModel() { delete iLiquid; }
//! pass mesh data to object and create BIH. Passed vectors get get swapped with old geometry!
void setMeshData(std::vector<G3D::Vector3> &vert, std::vector<MeshTriangle> &tri);
void setLiquidData(WmoLiquid*& liquid) { iLiquid = liquid; liquid = NULL; }
bool IntersectRay(const G3D::Ray &ray, float &distance, bool stopAtFirstHit) const;
bool IsInsideObject(const G3D::Vector3 &pos, const G3D::Vector3 &down, float &z_dist) const;
bool GetLiquidLevel(const G3D::Vector3 &pos, float &liqHeight) const;
uint32 GetLiquidType() const;
bool writeToFile(FILE* wf);
bool readFromFile(FILE* rf);
const G3D::AABox& GetBound() const { return iBound; }
uint32 GetMogpFlags() const { return iMogpFlags; }
uint32 GetWmoID() const { return iGroupWMOID; }
protected:
G3D::AABox iBound;
uint32 iMogpFlags;// 0x8 outdor; 0x2000 indoor
uint32 iGroupWMOID;
std::vector<G3D::Vector3> vertices;
std::vector<MeshTriangle> triangles;
BIH meshTree;
WmoLiquid* iLiquid;
public:
void getMeshData(std::vector<G3D::Vector3> &vertices, std::vector<MeshTriangle> &triangles, WmoLiquid* &liquid);
//! pass mesh data to object and create BIH. Passed vectors get get swapped with old geometry!
void setMeshData(std::vector<G3D::Vector3>& vert, std::vector<MeshTriangle>& tri);
void setLiquidData(WmoLiquid*& liquid) { iLiquid = liquid; liquid = NULL; }
bool IntersectRay(const G3D::Ray& ray, float& distance, bool stopAtFirstHit) const;
bool IsInsideObject(const G3D::Vector3& pos, const G3D::Vector3& down, float& z_dist) const;
bool GetLiquidLevel(const G3D::Vector3& pos, float& liqHeight) const;
uint32 GetLiquidType() const;
bool writeToFile(FILE* wf);
bool readFromFile(FILE* rf);
const G3D::AABox& GetBound() const { return iBound; }
uint32 GetMogpFlags() const { return iMogpFlags; }
uint32 GetWmoID() const { return iGroupWMOID; }
protected:
G3D::AABox iBound;
uint32 iMogpFlags;// 0x8 outdor; 0x2000 indoor
uint32 iGroupWMOID;
std::vector<G3D::Vector3> vertices;
std::vector<MeshTriangle> triangles;
BIH meshTree;
WmoLiquid* iLiquid;
public:
void getMeshData(std::vector<G3D::Vector3>& vertices, std::vector<MeshTriangle>& triangles, WmoLiquid*& liquid);
};
/*! Holds a model (converted M2 or WMO) in its original coordinate space */
class WorldModel
{
public:
WorldModel(): RootWMOID(0) { }
public:
WorldModel(): RootWMOID(0) { }
//! pass group models to WorldModel and create BIH. Passed vector is swapped with old geometry!
void setGroupModels(std::vector<GroupModel> &models);
void setRootWmoID(uint32 id) { RootWMOID = id; }
bool IntersectRay(const G3D::Ray &ray, float &distance, bool stopAtFirstHit) const;
bool IntersectPoint(const G3D::Vector3 &p, const G3D::Vector3 &down, float &dist, AreaInfo &info) const;
bool GetLocationInfo(const G3D::Vector3 &p, const G3D::Vector3 &down, float &dist, LocationInfo &info) const;
bool writeFile(const std::string &filename);
bool readFile(const std::string &filename);
protected:
uint32 RootWMOID;
std::vector<GroupModel> groupModels;
BIH groupTree;
public:
void getGroupModels(std::vector<GroupModel> &groupModels);
//! pass group models to WorldModel and create BIH. Passed vector is swapped with old geometry!
void setGroupModels(std::vector<GroupModel>& models);
void setRootWmoID(uint32 id) { RootWMOID = id; }
bool IntersectRay(const G3D::Ray& ray, float& distance, bool stopAtFirstHit) const;
bool IntersectPoint(const G3D::Vector3& p, const G3D::Vector3& down, float& dist, AreaInfo& info) const;
bool GetLocationInfo(const G3D::Vector3& p, const G3D::Vector3& down, float& dist, LocationInfo& info) const;
bool writeFile(const std::string& filename);
bool readFile(const std::string& filename);
protected:
uint32 RootWMOID;
std::vector<GroupModel> groupModels;
BIH groupTree;
public:
void getGroupModels(std::vector<GroupModel>& groupModels);
};
} // namespace VMAP

View File

@@ -16,7 +16,7 @@ public:
explicit NodeArray() { memset(&_nodes, 0, sizeof(_nodes)); }
void AddNode(Node* n)
{
for (uint8 i=0; i<9; ++i)
for (uint8 i = 0; i < 9; ++i)
if (_nodes[i] == 0)
{
_nodes[i] = n;
@@ -29,37 +29,41 @@ public:
};
template<class Node>
struct NodeCreator{
static Node * makeNode(int /*x*/, int /*y*/) { return new Node();}
struct NodeCreator
{
static Node* makeNode(int /*x*/, int /*y*/) { return new Node();}
};
template<class T,
class Node,
class NodeCreatorFunc = NodeCreator<Node>,
/*class BoundsFunc = BoundsTrait<T>,*/
class PositionFunc = PositionTrait<T>
>
class Node,
class NodeCreatorFunc = NodeCreator<Node>,
/*class BoundsFunc = BoundsTrait<T>,*/
class PositionFunc = PositionTrait<T>
>
class RegularGrid2D
{
public:
enum{
enum
{
CELL_NUMBER = 64,
};
#define HGRID_MAP_SIZE (533.33333f * 64.f) // shouldn't be changed
#define CELL_SIZE float(HGRID_MAP_SIZE/(float)CELL_NUMBER)
#define HGRID_MAP_SIZE (533.33333f * 64.f) // shouldn't be changed
#define CELL_SIZE float(HGRID_MAP_SIZE/(float)CELL_NUMBER)
typedef G3D::Table<const T*, NodeArray<Node> > MemberTable;
MemberTable memberTable;
Node* nodes[CELL_NUMBER][CELL_NUMBER];
RegularGrid2D(){
RegularGrid2D()
{
memset(nodes, 0, sizeof(nodes));
}
~RegularGrid2D(){
~RegularGrid2D()
{
for (int x = 0; x < CELL_NUMBER; ++x)
for (int y = 0; y < CELL_NUMBER; ++y)
delete nodes[x][y];
@@ -72,14 +76,14 @@ public:
pos[1] = value.getBounds().corner(1);
pos[2] = value.getBounds().corner(2);
pos[3] = value.getBounds().corner(3);
pos[4] = (pos[0] + pos[1])/2.0f;
pos[5] = (pos[1] + pos[2])/2.0f;
pos[6] = (pos[2] + pos[3])/2.0f;
pos[7] = (pos[3] + pos[0])/2.0f;
pos[8] = (pos[0] + pos[2])/2.0f;
pos[4] = (pos[0] + pos[1]) / 2.0f;
pos[5] = (pos[1] + pos[2]) / 2.0f;
pos[6] = (pos[2] + pos[3]) / 2.0f;
pos[7] = (pos[3] + pos[0]) / 2.0f;
pos[8] = (pos[0] + pos[2]) / 2.0f;
NodeArray<Node> na;
for (uint8 i=0; i<9; ++i)
for (uint8 i = 0; i < 9; ++i)
{
Cell c = Cell::ComputeCell(pos[i].x, pos[i].y);
if (!c.isValid())
@@ -88,7 +92,7 @@ public:
na.AddNode(&node);
}
for (uint8 i=0; i<9; ++i)
for (uint8 i = 0; i < 9; ++i)
{
if (na._nodes[i])
na._nodes[i]->insert(value);
@@ -102,7 +106,7 @@ public:
void remove(const T& value)
{
NodeArray<Node>& na = memberTable[&value];
for (uint8 i=0; i<9; ++i)
for (uint8 i = 0; i < 9; ++i)
{
if (na._nodes[i])
na._nodes[i]->remove(value);
@@ -132,7 +136,7 @@ public:
static Cell ComputeCell(float fx, float fy)
{
Cell c = { int(fx * (1.f/CELL_SIZE) + (CELL_NUMBER/2)), int(fy * (1.f/CELL_SIZE) + (CELL_NUMBER/2)) };
Cell c = { int(fx * (1.f / CELL_SIZE) + (CELL_NUMBER / 2)), int(fy * (1.f / CELL_SIZE) + (CELL_NUMBER / 2)) };
return c;
}
@@ -185,26 +189,26 @@ public:
if (kx_inv >= 0)
{
stepX = 1;
float x_border = (cell.x+1) * voxel;
float x_border = (cell.x + 1) * voxel;
tMaxX = (x_border - bx) * kx_inv;
}
else
{
stepX = -1;
float x_border = (cell.x-1) * voxel;
float x_border = (cell.x - 1) * voxel;
tMaxX = (x_border - bx) * kx_inv;
}
if (ky_inv >= 0)
{
stepY = 1;
float y_border = (cell.y+1) * voxel;
float y_border = (cell.y + 1) * voxel;
tMaxY = (y_border - by) * ky_inv;
}
else
{
stepY = -1;
float y_border = (cell.y-1) * voxel;
float y_border = (cell.y - 1) * voxel;
tMaxY = (y_border - by) * ky_inv;
}

View File

@@ -17,6 +17,6 @@ namespace VMAP
const char GAMEOBJECT_MODELS[] = "GameObjectModels.dtree";
// defined in TileAssembler.cpp currently...
bool readChunk(FILE* rf, char *dest, const char *compare, uint32 len);
bool readChunk(FILE* rf, char* dest, const char* compare, uint32 len);
}
#endif

View File

@@ -21,13 +21,15 @@ The collision detection is modified to return true, if we are inside an object.
namespace VMAP
{
template<class TValue>
class IntersectionCallBack {
class IntersectionCallBack
{
public:
TValue* closestEntity;
G3D::Vector3 hitLocation;
G3D::Vector3 hitNormal;
void operator()(const G3D::Ray& ray, const TValue* entity, bool StopAtFirstHit, float& distance) {
void operator()(const G3D::Ray& ray, const TValue* entity, bool StopAtFirstHit, float& distance)
{
entity->intersect(ray, distance, StopAtFirstHit, hitLocation, hitNormal);
}
};
@@ -116,7 +118,7 @@ namespace VMAP
{
location[i] = origin[i] + MaxT[WhichPlane] * dir[i];
if ((location[i] < MinB[i]) ||
(location[i] > MaxB[i]))
(location[i] > MaxB[i]))
{
// On this plane we're outside the box extents, so
// we miss the box

View File

@@ -6,22 +6,23 @@
#include "Common.h"
char const* localeNames[TOTAL_LOCALES] = {
"enUS",
"koKR",
"frFR",
"deDE",
"zhCN",
"zhTW",
"esES",
"esMX",
"ruRU"
char const* localeNames[TOTAL_LOCALES] =
{
"enUS",
"koKR",
"frFR",
"deDE",
"zhCN",
"zhTW",
"esES",
"esMX",
"ruRU"
};
LocaleConstant GetLocaleByName(const std::string& name)
{
for (uint32 i = 0; i < TOTAL_LOCALES; ++i)
if (name==localeNames[i])
if (name == localeNames[i])
return LocaleConstant(i);
return LOCALE_enUS; // including enGB case
@@ -30,8 +31,8 @@ LocaleConstant GetLocaleByName(const std::string& name)
void CleanStringForMysqlQuery(std::string& str)
{
std::string::size_type n = 0;
while ((n=str.find('\\')) != str.npos) str.erase(n,1);
while ((n=str.find('"')) != str.npos) str.erase(n,1);
while ((n=str.find('\'')) != str.npos) str.erase(n,1);
while ((n = str.find('\\')) != str.npos) str.erase(n, 1);
while ((n = str.find('"')) != str.npos) str.erase(n, 1);
while ((n = str.find('\'')) != str.npos) str.erase(n, 1);
}

View File

@@ -136,11 +136,11 @@ inline bool myisfinite(float f) { return isfinite(f) && !isnan(f); }
enum TimeConstants
{
MINUTE = 60,
HOUR = MINUTE*60,
DAY = HOUR*24,
WEEK = DAY*7,
MONTH = DAY*30,
YEAR = MONTH*12,
HOUR = MINUTE * 60,
DAY = HOUR * 24,
WEEK = DAY * 7,
MONTH = DAY * 30,
YEAR = MONTH * 12,
IN_MILLISECONDS = 1000
};

View File

@@ -36,35 +36,35 @@ namespace acore
template <class T>
class CheckedBufferOutputIterator
{
public:
using iterator_category = std::output_iterator_tag;
using value_type = void;
using pointer = T*;
using reference = T&;
using difference_type = std::ptrdiff_t;
public:
using iterator_category = std::output_iterator_tag;
using value_type = void;
using pointer = T*;
using reference = T&;
using difference_type = std::ptrdiff_t;
CheckedBufferOutputIterator(T* buf, size_t n) : _buf(buf), _end(buf+n) {}
CheckedBufferOutputIterator(T* buf, size_t n) : _buf(buf), _end(buf + n) {}
T& operator*() const { check(); return *_buf; }
CheckedBufferOutputIterator& operator++() { check(); ++_buf; return *this; }
CheckedBufferOutputIterator operator++(int) { CheckedBufferOutputIterator v = *this; operator++(); return v; }
T& operator*() const { check(); return *_buf; }
CheckedBufferOutputIterator& operator++() { check(); ++_buf; return *this; }
CheckedBufferOutputIterator operator++(int) { CheckedBufferOutputIterator v = *this; operator++(); return v; }
size_t remaining() const { return (_end - _buf); }
size_t remaining() const { return (_end - _buf); }
private:
T* _buf;
T* _end;
void check() const
{
if (!(_buf < _end))
throw std::out_of_range("index");
}
private:
T* _buf;
T* _end;
void check() const
{
if (!(_buf < _end))
throw std::out_of_range("index");
}
};
namespace Containers
{
template<class T>
void RandomResizeList(std::list<T> &list, uint32 size)
void RandomResizeList(std::list<T>& list, uint32 size)
{
size_t list_size = list.size();
@@ -78,7 +78,7 @@ namespace acore
}
template<class T, class Predicate>
void RandomResizeList(std::list<T> &list, Predicate& predicate, uint32 size)
void RandomResizeList(std::list<T>& list, Predicate& predicate, uint32 size)
{
//! First use predicate filter
std::list<T> listCopy;

View File

@@ -12,14 +12,14 @@
class ARC4
{
public:
ARC4(uint32 len);
ARC4(uint8* seed, uint32 len);
~ARC4();
void Init(uint8* seed);
void UpdateData(int len, uint8* data);
private:
EVP_CIPHER_CTX* m_ctx;
public:
ARC4(uint32 len);
ARC4(uint8* seed, uint32 len);
~ARC4();
void Init(uint8* seed);
void UpdateData(int len, uint8* data);
private:
EVP_CIPHER_CTX* m_ctx;
};
#endif

View File

@@ -17,11 +17,11 @@ void AuthCrypt::Init(BigNumber* K)
{
uint8 ServerEncryptionKey[SEED_KEY_SIZE] = { 0xCC, 0x98, 0xAE, 0x04, 0xE8, 0x97, 0xEA, 0xCA, 0x12, 0xDD, 0xC0, 0x93, 0x42, 0x91, 0x53, 0x57 };
HmacHash serverEncryptHmac(SEED_KEY_SIZE, (uint8*)ServerEncryptionKey);
uint8 *encryptHash = serverEncryptHmac.ComputeHash(K);
uint8* encryptHash = serverEncryptHmac.ComputeHash(K);
uint8 ServerDecryptionKey[SEED_KEY_SIZE] = { 0xC2, 0xB3, 0x72, 0x3C, 0xC6, 0xAE, 0xD9, 0xB5, 0x34, 0x3C, 0x53, 0xEE, 0x2F, 0x43, 0x67, 0xCE };
HmacHash clientDecryptHmac(SEED_KEY_SIZE, (uint8*)ServerDecryptionKey);
uint8 *decryptHash = clientDecryptHmac.ComputeHash(K);
uint8* decryptHash = clientDecryptHmac.ComputeHash(K);
//ARC4 _serverDecrypt(encryptHash);
_clientDecrypt.Init(decryptHash);
@@ -43,7 +43,7 @@ void AuthCrypt::Init(BigNumber* K)
_initialized = true;
}
void AuthCrypt::DecryptRecv(uint8 *data, size_t len)
void AuthCrypt::DecryptRecv(uint8* data, size_t len)
{
if (!_initialized)
return;
@@ -51,7 +51,7 @@ void AuthCrypt::DecryptRecv(uint8 *data, size_t len)
_clientDecrypt.UpdateData(len, data);
}
void AuthCrypt::EncryptSend(uint8 *data, size_t len)
void AuthCrypt::EncryptSend(uint8* data, size_t len)
{
if (!_initialized)
return;

View File

@@ -13,18 +13,18 @@ class BigNumber;
class AuthCrypt
{
public:
AuthCrypt();
public:
AuthCrypt();
void Init(BigNumber* K);
void DecryptRecv(uint8 *, size_t);
void EncryptSend(uint8 *, size_t);
void Init(BigNumber* K);
void DecryptRecv(uint8*, size_t);
void EncryptSend(uint8*, size_t);
bool IsInitialized() const { return _initialized; }
bool IsInitialized() const { return _initialized; }
private:
ARC4 _clientDecrypt;
ARC4 _serverEncrypt;
bool _initialized;
private:
ARC4 _clientDecrypt;
ARC4 _serverEncrypt;
bool _initialized;
};
#endif

View File

@@ -87,7 +87,7 @@ BigNumber BigNumber::operator-=(BigNumber const& bn)
BigNumber BigNumber::operator*=(BigNumber const& bn)
{
BN_CTX *bnctx;
BN_CTX* bnctx;
bnctx = BN_CTX_new();
BN_mul(_bn, _bn, bn._bn, bnctx);
@@ -98,7 +98,7 @@ BigNumber BigNumber::operator*=(BigNumber const& bn)
BigNumber BigNumber::operator/=(BigNumber const& bn)
{
BN_CTX *bnctx;
BN_CTX* bnctx;
bnctx = BN_CTX_new();
BN_div(_bn, NULL, _bn, bn._bn, bnctx);
@@ -109,7 +109,7 @@ BigNumber BigNumber::operator/=(BigNumber const& bn)
BigNumber BigNumber::operator%=(BigNumber const& bn)
{
BN_CTX *bnctx;
BN_CTX* bnctx;
bnctx = BN_CTX_new();
BN_mod(_bn, _bn, bn._bn, bnctx);
@@ -121,7 +121,7 @@ BigNumber BigNumber::operator%=(BigNumber const& bn)
BigNumber BigNumber::Exp(BigNumber const& bn)
{
BigNumber ret;
BN_CTX *bnctx;
BN_CTX* bnctx;
bnctx = BN_CTX_new();
BN_exp(ret._bn, _bn, bn._bn, bnctx);
@@ -133,7 +133,7 @@ BigNumber BigNumber::Exp(BigNumber const& bn)
BigNumber BigNumber::ModExp(BigNumber const& bn1, BigNumber const& bn2)
{
BigNumber ret;
BN_CTX *bnctx;
BN_CTX* bnctx;
bnctx = BN_CTX_new();
BN_mod_exp(ret._bn, _bn, bn1._bn, bn2._bn, bnctx);
@@ -178,12 +178,12 @@ std::unique_ptr<uint8[]> BigNumber::AsByteArray(int32 minSize, bool littleEndian
return ret;
}
char * BigNumber::AsHexStr() const
char* BigNumber::AsHexStr() const
{
return BN_bn2hex(_bn);
}
char * BigNumber::AsDecStr() const
char* BigNumber::AsDecStr() const
{
return BN_bn2dec(_bn);
}

View File

@@ -17,74 +17,74 @@ struct bignum_st;
class BigNumber
{
public:
BigNumber();
BigNumber(BigNumber const& bn);
BigNumber(uint32);
~BigNumber();
public:
BigNumber();
BigNumber(BigNumber const& bn);
BigNumber(uint32);
~BigNumber();
void SetDword(uint32);
void SetQword(uint64);
void SetBinary(uint8 const* bytes, int32 len);
void SetHexStr(char const* str);
void SetDword(uint32);
void SetQword(uint64);
void SetBinary(uint8 const* bytes, int32 len);
void SetHexStr(char const* str);
void SetRand(int32 numbits);
void SetRand(int32 numbits);
BigNumber& operator=(BigNumber const& bn);
BigNumber& operator=(BigNumber const& bn);
BigNumber operator+=(BigNumber const& bn);
BigNumber operator+(BigNumber const& bn)
{
BigNumber t(*this);
return t += bn;
}
BigNumber operator+=(BigNumber const& bn);
BigNumber operator+(BigNumber const& bn)
{
BigNumber t(*this);
return t += bn;
}
BigNumber operator-=(BigNumber const& bn);
BigNumber operator-(BigNumber const& bn)
{
BigNumber t(*this);
return t -= bn;
}
BigNumber operator-=(BigNumber const& bn);
BigNumber operator-(BigNumber const& bn)
{
BigNumber t(*this);
return t -= bn;
}
BigNumber operator*=(BigNumber const& bn);
BigNumber operator*(BigNumber const& bn)
{
BigNumber t(*this);
return t *= bn;
}
BigNumber operator*=(BigNumber const& bn);
BigNumber operator*(BigNumber const& bn)
{
BigNumber t(*this);
return t *= bn;
}
BigNumber operator/=(BigNumber const& bn);
BigNumber operator/(BigNumber const& bn)
{
BigNumber t(*this);
return t /= bn;
}
BigNumber operator/=(BigNumber const& bn);
BigNumber operator/(BigNumber const& bn)
{
BigNumber t(*this);
return t /= bn;
}
BigNumber operator%=(BigNumber const& bn);
BigNumber operator%(BigNumber const& bn)
{
BigNumber t(*this);
return t %= bn;
}
BigNumber operator%=(BigNumber const& bn);
BigNumber operator%(BigNumber const& bn)
{
BigNumber t(*this);
return t %= bn;
}
bool isZero() const;
bool isZero() const;
BigNumber ModExp(BigNumber const& bn1, BigNumber const& bn2);
BigNumber Exp(BigNumber const&);
BigNumber ModExp(BigNumber const& bn1, BigNumber const& bn2);
BigNumber Exp(BigNumber const&);
int32 GetNumBytes(void);
int32 GetNumBytes(void);
struct bignum_st *BN() { return _bn; }
struct bignum_st* BN() { return _bn; }
uint32 AsDword();
uint32 AsDword();
std::unique_ptr<uint8[]> AsByteArray(int32 minSize = 0, bool littleEndian = true);
std::unique_ptr<uint8[]> AsByteArray(int32 minSize = 0, bool littleEndian = true);
char * AsHexStr() const;
char * AsDecStr() const;
char* AsHexStr() const;
char* AsDecStr() const;
private:
struct bignum_st *_bn;
private:
struct bignum_st* _bn;
};
#endif

View File

@@ -12,7 +12,7 @@
#if defined(OPENSSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER < 0x10100000L
HMAC_CTX* HMAC_CTX_new()
{
HMAC_CTX *ctx = new HMAC_CTX();
HMAC_CTX* ctx = new HMAC_CTX();
HMAC_CTX_init(ctx);
return ctx;
}

View File

@@ -18,18 +18,18 @@ class BigNumber;
class HmacHash
{
public:
HmacHash(uint32 len, uint8* seed);
~HmacHash();
void UpdateData(std::string const& str);
void UpdateData(uint8 const* data, size_t len);
void Finalize();
uint8* ComputeHash(BigNumber* bn);
uint8* GetDigest() { return m_digest; }
int GetLength() const { return SHA_DIGEST_LENGTH; }
private:
HMAC_CTX* m_ctx;
uint8 m_digest[SHA_DIGEST_LENGTH];
public:
HmacHash(uint32 len, uint8* seed);
~HmacHash();
void UpdateData(std::string const& str);
void UpdateData(uint8 const* data, size_t len);
void Finalize();
uint8* ComputeHash(BigNumber* bn);
uint8* GetDigest() { return m_digest; }
int GetLength() const { return SHA_DIGEST_LENGTH; }
private:
HMAC_CTX* m_ctx;
uint8 m_digest[SHA_DIGEST_LENGTH];
};
#endif

View File

@@ -19,7 +19,7 @@ static void lockingCallback(int mode, int type, char const* /*file*/, int /*line
else
cryptoLocks[type]->unlock();
}
static void threadIdCallback(CRYPTO_THREADID * id)
static void threadIdCallback(CRYPTO_THREADID* id)
{
(void)id;
CRYPTO_THREADID_set_numeric(id, std::hash<std::thread::id>()(std::this_thread::get_id()));

View File

@@ -19,12 +19,12 @@ SHA1Hash::~SHA1Hash()
SHA1_Init(&mC);
}
void SHA1Hash::UpdateData(const uint8 *dta, int len)
void SHA1Hash::UpdateData(const uint8* dta, int len)
{
SHA1_Update(&mC, dta, len);
}
void SHA1Hash::UpdateData(const std::string &str)
void SHA1Hash::UpdateData(const std::string& str)
{
UpdateData((uint8 const*)str.c_str(), str.length());
}

View File

@@ -15,24 +15,24 @@ class BigNumber;
class SHA1Hash
{
public:
SHA1Hash();
~SHA1Hash();
public:
SHA1Hash();
~SHA1Hash();
void UpdateBigNumbers(BigNumber* bn0, ...);
void UpdateBigNumbers(BigNumber* bn0, ...);
void UpdateData(const uint8 *dta, int len);
void UpdateData(const std::string &str);
void UpdateData(const uint8* dta, int len);
void UpdateData(const std::string& str);
void Initialize();
void Finalize();
void Initialize();
void Finalize();
uint8 *GetDigest(void) { return mDigest; };
int GetLength(void) const { return SHA_DIGEST_LENGTH; };
uint8* GetDigest(void) { return mDigest; };
int GetLength(void) const { return SHA_DIGEST_LENGTH; };
private:
SHA_CTX mC;
uint8 mDigest[SHA_DIGEST_LENGTH];
private:
SHA_CTX mC;
uint8 mDigest[SHA_DIGEST_LENGTH];
};
#endif

View File

@@ -14,7 +14,7 @@ class SHA1Randx
public:
SHA1Randx(uint8* buff, uint32 size)
{
uint32 taken = size/2;
uint32 taken = size / 2;
sh.Initialize();
sh.UpdateData(buff, taken);

View File

@@ -84,7 +84,7 @@ bool DBCFileLoader::Load(char const* filename, char const* fmt)
}
data = new unsigned char[recordSize * recordCount + stringSize];
stringTable = data + recordSize*recordCount;
stringTable = data + recordSize * recordCount;
if (fread(data, recordSize * recordCount + stringSize, 1, f) != 1)
{
@@ -210,7 +210,7 @@ char* DBCFileLoader::AutoProduceData(char const* format, uint32& records, char**
else
indexTable[y] = &dataTable[offset];
for (uint32 x=0; x < fieldCount; ++x)
for (uint32 x = 0; x < fieldCount; ++x)
{
switch (format[x])
{
@@ -275,17 +275,17 @@ char* DBCFileLoader::AutoProduceStrings(char const* format, char* dataTable)
offset += sizeof(uint8);
break;
case FT_STRING:
{
// fill only not filled entries
char** slot = (char**)(&dataTable[offset]);
if (!*slot || !**slot)
{
const char * st = getRecord(y).getString(x);
*slot = stringPool + (st - (char const*)stringTable);
// fill only not filled entries
char** slot = (char**)(&dataTable[offset]);
if (!*slot || !** slot)
{
const char* st = getRecord(y).getString(x);
*slot = stringPool + (st - (char const*)stringTable);
}
offset += sizeof(char*);
break;
}
offset += sizeof(char*);
break;
}
case FT_LOGIC:
ASSERT(false && "Attempted to load DBC files that does not have field types that match what is in the core. Check DBCfmt.h or your DBC files.");
break;

View File

@@ -30,7 +30,7 @@ public:
DBCFileLoader();
~DBCFileLoader();
bool Load(const char *filename, const char *fmt);
bool Load(const char* filename, const char* fmt);
class Record
{
@@ -38,7 +38,7 @@ public:
float getFloat(size_t field) const
{
ASSERT(field < file.fieldCount);
float val = *reinterpret_cast<float*>(offset+file.GetOffset(field));
float val = *reinterpret_cast<float*>(offset + file.GetOffset(field));
EndianConvert(val);
return val;
}
@@ -46,7 +46,7 @@ public:
uint32 getUInt(size_t field) const
{
ASSERT(field < file.fieldCount);
uint32 val = *reinterpret_cast<uint32*>(offset+file.GetOffset(field));
uint32 val = *reinterpret_cast<uint32*>(offset + file.GetOffset(field));
EndianConvert(val);
return val;
}
@@ -54,10 +54,10 @@ public:
uint8 getUInt8(size_t field) const
{
ASSERT(field < file.fieldCount);
return *reinterpret_cast<uint8*>(offset+file.GetOffset(field));
return *reinterpret_cast<uint8*>(offset + file.GetOffset(field));
}
const char *getString(size_t field) const
const char* getString(size_t field) const
{
ASSERT(field < file.fieldCount);
size_t stringOffset = getUInt(field);
@@ -66,9 +66,9 @@ public:
}
private:
Record(DBCFileLoader &file_, unsigned char *offset_): offset(offset_), file(file_) { }
unsigned char *offset;
DBCFileLoader &file;
Record(DBCFileLoader& file_, unsigned char* offset_): offset(offset_), file(file_) { }
unsigned char* offset;
DBCFileLoader& file;
friend class DBCFileLoader;
@@ -84,16 +84,16 @@ public:
bool IsLoaded() const { return data != nullptr; }
char* AutoProduceData(char const* fmt, uint32& count, char**& indexTable);
char* AutoProduceStrings(char const* fmt, char* dataTable);
static uint32 GetFormatRecordSize(const char * format, int32 * index_pos = nullptr);
static uint32 GetFormatRecordSize(const char* format, int32* index_pos = nullptr);
private:
uint32 recordSize;
uint32 recordCount;
uint32 fieldCount;
uint32 stringSize;
uint32 *fieldsOffset;
unsigned char *data;
unsigned char *stringTable;
uint32* fieldsOffset;
unsigned char* data;
unsigned char* stringTable;
DBCFileLoader(DBCFileLoader const& right) = delete;
DBCFileLoader& operator=(DBCFileLoader const& right) = delete;

View File

@@ -9,14 +9,14 @@
/*! Basic, ad-hoc queries. */
BasicStatementTask::BasicStatementTask(const char* sql) :
m_has_result(false)
m_has_result(false)
{
m_sql = strdup(sql);
}
BasicStatementTask::BasicStatementTask(const char* sql, QueryResultFuture result) :
m_has_result(true),
m_result(result)
m_has_result(true),
m_result(result)
{
m_sql = strdup(sql);
}

View File

@@ -14,17 +14,17 @@ typedef ACE_Future<QueryResult> QueryResultFuture;
/*! Raw, ad-hoc query. */
class BasicStatementTask : public SQLOperation
{
public:
BasicStatementTask(const char* sql);
BasicStatementTask(const char* sql, QueryResultFuture result);
~BasicStatementTask();
public:
BasicStatementTask(const char* sql);
BasicStatementTask(const char* sql, QueryResultFuture result);
~BasicStatementTask();
bool Execute();
bool Execute();
private:
const char* m_sql; //- Raw query to be executed
bool m_has_result;
QueryResultFuture m_result;
private:
const char* m_sql; //- Raw query to be executed
bool m_has_result;
QueryResultFuture m_result;
};
#endif

View File

@@ -11,8 +11,8 @@
#include "MySQLThreading.h"
DatabaseWorker::DatabaseWorker(ACE_Activation_Queue* new_queue, MySQLConnection* con) :
m_queue(new_queue),
m_conn(con)
m_queue(new_queue),
m_conn(con)
{
/// Assign thread to task
activate();
@@ -23,7 +23,7 @@ int DatabaseWorker::svc()
if (!m_queue)
return -1;
SQLOperation *request = NULL;
SQLOperation* request = NULL;
while (1)
{
request = (SQLOperation*)(m_queue->dequeue());

View File

@@ -14,17 +14,17 @@ class MySQLConnection;
class DatabaseWorker : protected ACE_Task_Base
{
public:
DatabaseWorker(ACE_Activation_Queue* new_queue, MySQLConnection* con);
public:
DatabaseWorker(ACE_Activation_Queue* new_queue, MySQLConnection* con);
///- Inherited from ACE_Task_Base
int svc();
int wait() { return ACE_Task_Base::wait(); }
///- Inherited from ACE_Task_Base
int svc();
int wait() { return ACE_Task_Base::wait(); }
private:
DatabaseWorker() : ACE_Task_Base() { }
ACE_Activation_Queue* m_queue;
MySQLConnection* m_conn;
private:
DatabaseWorker() : ACE_Task_Base() { }
ACE_Activation_Queue* m_queue;
MySQLConnection* m_conn;
};
#endif

View File

@@ -12,8 +12,8 @@
template <class T>
DatabaseWorkerPool<T>::DatabaseWorkerPool() :
_mqueue(new ACE_Message_Queue<ACE_SYNCH>(2*1024*1024, 2*1024*1024)),
_queue(new ACE_Activation_Queue(_mqueue))
_mqueue(new ACE_Message_Queue<ACE_SYNCH>(2 * 1024 * 1024, 2 * 1024 * 1024)),
_queue(new ACE_Activation_Queue(_mqueue))
{
memset(_connectionCount, 0, sizeof(_connectionCount));
_connections.resize(IDX_SIZE);
@@ -29,7 +29,7 @@ bool DatabaseWorkerPool<T>::Open(const std::string& infoString, uint8 async_thre
_connectionInfo = MySQLConnectionInfo(infoString);
sLog->outSQLDriver("Opening DatabasePool '%s'. Asynchronous connections: %u, synchronous connections: %u.",
GetDatabaseName(), async_threads, synch_threads);
GetDatabaseName(), async_threads, synch_threads);
//! Open asynchronous connections (delayed operations)
_connections[IDX_ASYNC].resize(async_threads);
@@ -39,7 +39,7 @@ bool DatabaseWorkerPool<T>::Open(const std::string& infoString, uint8 async_thre
res &= t->Open();
if (res) // only check mysql version if connection is valid
WPFatal(mysql_get_server_version(t->GetHandle()) >= MIN_MYSQL_SERVER_VERSION, "AzerothCore does not support MySQL versions below 5.6");
_connections[IDX_ASYNC][i] = t;
++_connectionCount[IDX_ASYNC];
}
@@ -56,11 +56,11 @@ bool DatabaseWorkerPool<T>::Open(const std::string& infoString, uint8 async_thre
if (res)
sLog->outSQLDriver("DatabasePool '%s' opened successfully. %u total connections running.", GetDatabaseName(),
(_connectionCount[IDX_SYNCH] + _connectionCount[IDX_ASYNC]));
(_connectionCount[IDX_SYNCH] + _connectionCount[IDX_ASYNC]));
else
sLog->outError("DatabasePool %s NOT opened. There were errors opening the MySQL connections. Check your SQLDriverLogFile "
"for specific errors.", GetDatabaseName());
"for specific errors.", GetDatabaseName());
return res;
}
@@ -84,7 +84,7 @@ void DatabaseWorkerPool<T>::Close()
}
sLog->outSQLDriver("Asynchronous connections on DatabasePool '%s' terminated. Proceeding with synchronous connections.",
GetDatabaseName());
GetDatabaseName());
//! Shut down the synchronous connections
//! There's no need for locking the connection, because DatabaseWorkerPool<>::Close
@@ -212,7 +212,7 @@ SQLTransaction DatabaseWorkerPool<T>::BeginTransaction()
template <class T>
void DatabaseWorkerPool<T>::CommitTransaction(SQLTransaction transaction)
{
#ifdef ACORE_DEBUG
#ifdef ACORE_DEBUG
//! Only analyze transaction weaknesses in Debug mode.
//! Ideally we catch the faults in Debug mode and then correct them,
//! so there's no need to waste these CPU cycles in Release mode.
@@ -227,7 +227,7 @@ void DatabaseWorkerPool<T>::CommitTransaction(SQLTransaction transaction)
default:
break;
}
#endif // ACORE_DEBUG
#endif // ACORE_DEBUG
Enqueue(new TransactionTask(transaction));
}
@@ -311,7 +311,7 @@ T* DatabaseWorkerPool<T>::GetFreeConnection()
uint8 i = 0;
size_t num_cons = _connectionCount[IDX_SYNCH];
T* t = nullptr;
//! Block forever until a connection is free
for (;;)
{

View File

@@ -34,211 +34,211 @@ class PingOperation : public SQLOperation
template <class T>
class DatabaseWorkerPool
{
public:
/* Activity state */
DatabaseWorkerPool();
public:
/* Activity state */
DatabaseWorkerPool();
~DatabaseWorkerPool() { }
~DatabaseWorkerPool() { }
bool Open(const std::string& infoString, uint8 async_threads, uint8 synch_threads);
bool Open(const std::string& infoString, uint8 async_threads, uint8 synch_threads);
void Close();
void Close();
/**
Delayed one-way statement methods.
*/
/**
Delayed one-way statement methods.
*/
//! Enqueues a one-way SQL operation in string format that will be executed asynchronously.
//! This method should only be used for queries that are only executed once, e.g during startup.
void Execute(const char* sql);
//! Enqueues a one-way SQL operation in string format that will be executed asynchronously.
//! This method should only be used for queries that are only executed once, e.g during startup.
void Execute(const char* sql);
//! Enqueues a one-way SQL operation in string format -with variable args- that will be executed asynchronously.
//! This method should only be used for queries that are only executed once, e.g during startup.
template<typename Format, typename... Args>
void PExecute(Format&& sql, Args&&... args)
{
if (acore::IsFormatEmptyOrNull(sql))
return;
//! Enqueues a one-way SQL operation in string format -with variable args- that will be executed asynchronously.
//! This method should only be used for queries that are only executed once, e.g during startup.
template<typename Format, typename... Args>
void PExecute(Format&& sql, Args&& ... args)
{
if (acore::IsFormatEmptyOrNull(sql))
return;
Execute(acore::StringFormat(std::forward<Format>(sql), std::forward<Args>(args)...).c_str());
}
Execute(acore::StringFormat(std::forward<Format>(sql), std::forward<Args>(args)...).c_str());
}
//! Enqueues a one-way SQL operation in prepared statement format that will be executed asynchronously.
//! Statement must be prepared with CONNECTION_ASYNC flag.
void Execute(PreparedStatement* stmt);
//! Enqueues a one-way SQL operation in prepared statement format that will be executed asynchronously.
//! Statement must be prepared with CONNECTION_ASYNC flag.
void Execute(PreparedStatement* stmt);
/**
Direct synchronous one-way statement methods.
*/
/**
Direct synchronous one-way statement methods.
*/
//! Directly executes a one-way SQL operation in string format, that will block the calling thread until finished.
//! This method should only be used for queries that are only executed once, e.g during startup.
void DirectExecute(const char* sql);
//! Directly executes a one-way SQL operation in string format, that will block the calling thread until finished.
//! This method should only be used for queries that are only executed once, e.g during startup.
void DirectExecute(const char* sql);
//! Directly executes a one-way SQL operation in string format -with variable args-, that will block the calling thread until finished.
//! This method should only be used for queries that are only executed once, e.g during startup.
template<typename Format, typename... Args>
void DirectPExecute(Format&& sql, Args&&... args)
{
if (acore::IsFormatEmptyOrNull(sql))
return;
//! Directly executes a one-way SQL operation in string format -with variable args-, that will block the calling thread until finished.
//! This method should only be used for queries that are only executed once, e.g during startup.
template<typename Format, typename... Args>
void DirectPExecute(Format&& sql, Args&& ... args)
{
if (acore::IsFormatEmptyOrNull(sql))
return;
DirectExecute(acore::StringFormat(std::forward<Format>(sql), std::forward<Args>(args)...).c_str());
}
DirectExecute(acore::StringFormat(std::forward<Format>(sql), std::forward<Args>(args)...).c_str());
}
//! Directly executes a one-way SQL operation in prepared statement format, that will block the calling thread until finished.
//! Statement must be prepared with the CONNECTION_SYNCH flag.
void DirectExecute(PreparedStatement* stmt);
//! Directly executes a one-way SQL operation in prepared statement format, that will block the calling thread until finished.
//! Statement must be prepared with the CONNECTION_SYNCH flag.
void DirectExecute(PreparedStatement* stmt);
/**
Synchronous query (with resultset) methods.
*/
/**
Synchronous query (with resultset) methods.
*/
//! Directly executes an SQL query in string format that will block the calling thread until finished.
//! Returns reference counted auto pointer, no need for manual memory management in upper level code.
QueryResult Query(const char* sql, T* conn = nullptr);
//! Directly executes an SQL query in string format that will block the calling thread until finished.
//! Returns reference counted auto pointer, no need for manual memory management in upper level code.
QueryResult Query(const char* sql, T* conn = nullptr);
//! Directly executes an SQL query in string format -with variable args- that will block the calling thread until finished.
//! Returns reference counted auto pointer, no need for manual memory management in upper level code.
template<typename Format, typename... Args>
QueryResult PQuery(Format&& sql, T* conn, Args&&... args)
{
if (acore::IsFormatEmptyOrNull(sql))
return QueryResult(nullptr);
//! Directly executes an SQL query in string format -with variable args- that will block the calling thread until finished.
//! Returns reference counted auto pointer, no need for manual memory management in upper level code.
template<typename Format, typename... Args>
QueryResult PQuery(Format&& sql, T* conn, Args&& ... args)
{
if (acore::IsFormatEmptyOrNull(sql))
return QueryResult(nullptr);
return Query(acore::StringFormat(std::forward<Format>(sql), std::forward<Args>(args)...).c_str(), conn);
}
return Query(acore::StringFormat(std::forward<Format>(sql), std::forward<Args>(args)...).c_str(), conn);
}
//! Directly executes an SQL query in string format -with variable args- that will block the calling thread until finished.
//! Returns reference counted auto pointer, no need for manual memory management in upper level code.
template<typename Format, typename... Args>
QueryResult PQuery(Format&& sql, Args&&... args)
{
if (acore::IsFormatEmptyOrNull(sql))
return QueryResult(nullptr);
//! Directly executes an SQL query in string format -with variable args- that will block the calling thread until finished.
//! Returns reference counted auto pointer, no need for manual memory management in upper level code.
template<typename Format, typename... Args>
QueryResult PQuery(Format&& sql, Args&& ... args)
{
if (acore::IsFormatEmptyOrNull(sql))
return QueryResult(nullptr);
return Query(acore::StringFormat(std::forward<Format>(sql), std::forward<Args>(args)...).c_str());
}
return Query(acore::StringFormat(std::forward<Format>(sql), std::forward<Args>(args)...).c_str());
}
//! Directly executes an SQL query in prepared format that will block the calling thread until finished.
//! Returns reference counted auto pointer, no need for manual memory management in upper level code.
//! Statement must be prepared with CONNECTION_SYNCH flag.
PreparedQueryResult Query(PreparedStatement* stmt);
//! Directly executes an SQL query in prepared format that will block the calling thread until finished.
//! Returns reference counted auto pointer, no need for manual memory management in upper level code.
//! Statement must be prepared with CONNECTION_SYNCH flag.
PreparedQueryResult Query(PreparedStatement* stmt);
/**
Asynchronous query (with resultset) methods.
*/
/**
Asynchronous query (with resultset) methods.
*/
//! Enqueues a query in string format that will set the value of the QueryResultFuture return object as soon as the query is executed.
//! The return value is then processed in ProcessQueryCallback methods.
QueryResultFuture AsyncQuery(const char* sql);
//! Enqueues a query in string format that will set the value of the QueryResultFuture return object as soon as the query is executed.
//! The return value is then processed in ProcessQueryCallback methods.
QueryResultFuture AsyncQuery(const char* sql);
//! Enqueues a query in string format -with variable args- that will set the value of the QueryResultFuture return object as soon as the query is executed.
//! The return value is then processed in ProcessQueryCallback methods.
template<typename Format, typename... Args>
QueryResultFuture AsyncPQuery(Format&& sql, Args&&... args)
{
if (acore::IsFormatEmptyOrNull(sql))
return QueryResult(nullptr);
//! Enqueues a query in string format -with variable args- that will set the value of the QueryResultFuture return object as soon as the query is executed.
//! The return value is then processed in ProcessQueryCallback methods.
template<typename Format, typename... Args>
QueryResultFuture AsyncPQuery(Format&& sql, Args&& ... args)
{
if (acore::IsFormatEmptyOrNull(sql))
return QueryResult(nullptr);
return AsyncQuery(acore::StringFormat(std::forward<Format>(sql), std::forward<Args>(args)...).c_str());
}
return AsyncQuery(acore::StringFormat(std::forward<Format>(sql), std::forward<Args>(args)...).c_str());
}
//! Enqueues a query in prepared format that will set the value of the PreparedQueryResultFuture return object as soon as the query is executed.
//! The return value is then processed in ProcessQueryCallback methods.
//! Statement must be prepared with CONNECTION_ASYNC flag.
PreparedQueryResultFuture AsyncQuery(PreparedStatement* stmt);
//! Enqueues a query in prepared format that will set the value of the PreparedQueryResultFuture return object as soon as the query is executed.
//! The return value is then processed in ProcessQueryCallback methods.
//! Statement must be prepared with CONNECTION_ASYNC flag.
PreparedQueryResultFuture AsyncQuery(PreparedStatement* stmt);
//! Enqueues a vector of SQL operations (can be both adhoc and prepared) that will set the value of the QueryResultHolderFuture
//! return object as soon as the query is executed.
//! The return value is then processed in ProcessQueryCallback methods.
//! Any prepared statements added to this holder need to be prepared with the CONNECTION_ASYNC flag.
QueryResultHolderFuture DelayQueryHolder(SQLQueryHolder* holder);
//! Enqueues a vector of SQL operations (can be both adhoc and prepared) that will set the value of the QueryResultHolderFuture
//! return object as soon as the query is executed.
//! The return value is then processed in ProcessQueryCallback methods.
//! Any prepared statements added to this holder need to be prepared with the CONNECTION_ASYNC flag.
QueryResultHolderFuture DelayQueryHolder(SQLQueryHolder* holder);
/**
Transaction context methods.
*/
/**
Transaction context methods.
*/
//! Begins an automanaged transaction pointer that will automatically rollback if not commited. (Autocommit=0)
SQLTransaction BeginTransaction();
//! Begins an automanaged transaction pointer that will automatically rollback if not commited. (Autocommit=0)
SQLTransaction BeginTransaction();
//! Enqueues a collection of one-way SQL operations (can be both adhoc and prepared). The order in which these operations
//! were appended to the transaction will be respected during execution.
void CommitTransaction(SQLTransaction transaction);
//! Enqueues a collection of one-way SQL operations (can be both adhoc and prepared). The order in which these operations
//! were appended to the transaction will be respected during execution.
void CommitTransaction(SQLTransaction transaction);
//! Directly executes a collection of one-way SQL operations (can be both adhoc and prepared). The order in which these operations
//! were appended to the transaction will be respected during execution.
void DirectCommitTransaction(SQLTransaction& transaction);
//! Directly executes a collection of one-way SQL operations (can be both adhoc and prepared). The order in which these operations
//! were appended to the transaction will be respected during execution.
void DirectCommitTransaction(SQLTransaction& transaction);
//! Method used to execute prepared statements in a diverse context.
//! Will be wrapped in a transaction if valid object is present, otherwise executed standalone.
void ExecuteOrAppend(SQLTransaction& trans, PreparedStatement* stmt);
//! Method used to execute prepared statements in a diverse context.
//! Will be wrapped in a transaction if valid object is present, otherwise executed standalone.
void ExecuteOrAppend(SQLTransaction& trans, PreparedStatement* stmt);
//! Method used to execute ad-hoc statements in a diverse context.
//! Will be wrapped in a transaction if valid object is present, otherwise executed standalone.
void ExecuteOrAppend(SQLTransaction& trans, const char* sql);
//! Method used to execute ad-hoc statements in a diverse context.
//! Will be wrapped in a transaction if valid object is present, otherwise executed standalone.
void ExecuteOrAppend(SQLTransaction& trans, const char* sql);
/**
Other
*/
/**
Other
*/
//! Automanaged (internally) pointer to a prepared statement object for usage in upper level code.
//! Pointer is deleted in this->DirectExecute(PreparedStatement*), this->Query(PreparedStatement*) or PreparedStatementTask::~PreparedStatementTask.
//! This object is not tied to the prepared statement on the MySQL context yet until execution.
PreparedStatement* GetPreparedStatement(uint32 index);
//! Automanaged (internally) pointer to a prepared statement object for usage in upper level code.
//! Pointer is deleted in this->DirectExecute(PreparedStatement*), this->Query(PreparedStatement*) or PreparedStatementTask::~PreparedStatementTask.
//! This object is not tied to the prepared statement on the MySQL context yet until execution.
PreparedStatement* GetPreparedStatement(uint32 index);
//! Apply escape string'ing for current collation. (utf8)
unsigned long EscapeString(char* to, const char* from, unsigned long length)
{
if (!to || !from || !length)
return 0;
//! Apply escape string'ing for current collation. (utf8)
unsigned long EscapeString(char* to, const char* from, unsigned long length)
{
if (!to || !from || !length)
return 0;
return mysql_real_escape_string(_connections[IDX_SYNCH][0]->GetHandle(), to, from, length);
}
return mysql_real_escape_string(_connections[IDX_SYNCH][0]->GetHandle(), to, from, length);
}
//! Keeps all our MySQL connections alive, prevent the server from disconnecting us.
void KeepAlive();
//! Keeps all our MySQL connections alive, prevent the server from disconnecting us.
void KeepAlive();
char const* GetDatabaseName() const
{
return _connectionInfo.database.c_str();
}
char const* GetDatabaseName() const
{
return _connectionInfo.database.c_str();
}
void EscapeString(std::string& str)
{
if (str.empty())
return;
void EscapeString(std::string& str)
{
if (str.empty())
return;
char* buf = new char[str.size() * 2 + 1];
EscapeString(buf, str.c_str(), str.size());
str = buf;
delete[] buf;
}
char* buf = new char[str.size() * 2 + 1];
EscapeString(buf, str.c_str(), str.size());
str = buf;
delete[] buf;
}
private:
private:
void Enqueue(SQLOperation* op)
{
_queue->enqueue(op);
}
void Enqueue(SQLOperation* op)
{
_queue->enqueue(op);
}
//! Gets a free connection in the synchronous connection pool.
//! Caller MUST call t->Unlock() after touching the MySQL context to prevent deadlocks.
T* GetFreeConnection();
//! Gets a free connection in the synchronous connection pool.
//! Caller MUST call t->Unlock() after touching the MySQL context to prevent deadlocks.
T* GetFreeConnection();
private:
enum _internalIndex
{
IDX_ASYNC,
IDX_SYNCH,
IDX_SIZE
};
private:
enum _internalIndex
{
IDX_ASYNC,
IDX_SYNCH,
IDX_SIZE
};
ACE_Message_Queue<ACE_SYNCH>* _mqueue;
ACE_Activation_Queue* _queue; //! Queue shared by async worker threads.
std::vector<std::vector<T*>> _connections;
uint32 _connectionCount[2]; //! Counter of MySQL connections;
MySQLConnectionInfo _connectionInfo;
ACE_Message_Queue<ACE_SYNCH>* _mqueue;
ACE_Activation_Queue* _queue; //! Queue shared by async worker threads.
std::vector<std::vector<T*>> _connections;
uint32 _connectionCount[2]; //! Counter of MySQL connections;
MySQLConnectionInfo _connectionInfo;
};
#endif

View File

@@ -44,7 +44,7 @@ void Field::SetStructuredValue(char* newValue, enum_field_types newType)
if (newValue)
{
size_t size = strlen(newValue);
data.value = new char [size+1];
data.value = new char [size + 1];
strcpy((char*)data.value, newValue);
data.length = size;
}

View File

@@ -17,369 +17,396 @@ class Field
friend class ResultSet;
friend class PreparedResultSet;
public:
public:
bool GetBool() const // Wrapper, actually gets integer
bool GetBool() const // Wrapper, actually gets integer
{
return (GetUInt8() == 1);
}
uint8 GetUInt8() const
{
if (!data.value)
return 0;
#ifdef ACORE_DEBUG
if (!IsType(MYSQL_TYPE_TINY))
{
return (GetUInt8() == 1);
}
uint8 GetUInt8() const
{
if (!data.value)
return 0;
#ifdef ACORE_DEBUG
if (!IsType(MYSQL_TYPE_TINY))
{
sLog->outSQLDriver("Warning: GetUInt8() on non-tinyint field. Using type: %s.", FieldTypeToString(data.type));
return 0;
}
#endif
if (data.raw)
return *reinterpret_cast<uint8*>(data.value);
return static_cast<uint8>(atol((char*)data.value));
}
int8 GetInt8() const
{
if (!data.value)
return 0;
#ifdef ACORE_DEBUG
if (!IsType(MYSQL_TYPE_TINY))
{
sLog->outSQLDriver("Warning: GetInt8() on non-tinyint field. Using type: %s.", FieldTypeToString(data.type));
return 0;
}
#endif
if (data.raw)
return *reinterpret_cast<int8*>(data.value);
return static_cast<int8>(atol((char*)data.value));
}
#ifdef ELUNA
enum_field_types GetType() const
{
return data.type;
sLog->outSQLDriver("Warning: GetUInt8() on non-tinyint field. Using type: %s.", FieldTypeToString(data.type));
return 0;
}
#endif
uint16 GetUInt16() const
if (data.raw)
return *reinterpret_cast<uint8*>(data.value);
return static_cast<uint8>(atol((char*)data.value));
}
int8 GetInt8() const
{
if (!data.value)
return 0;
#ifdef ACORE_DEBUG
if (!IsType(MYSQL_TYPE_TINY))
{
if (!data.value)
sLog->outSQLDriver("Warning: GetInt8() on non-tinyint field. Using type: %s.", FieldTypeToString(data.type));
return 0;
}
#endif
if (data.raw)
return *reinterpret_cast<int8*>(data.value);
return static_cast<int8>(atol((char*)data.value));
}
#ifdef ELUNA
enum_field_types GetType() const
{
return data.type;
}
#endif
uint16 GetUInt16() const
{
if (!data.value)
return 0;
#ifdef ACORE_DEBUG
if (!IsType(MYSQL_TYPE_SHORT) && !IsType(MYSQL_TYPE_YEAR))
{
sLog->outSQLDriver("Warning: GetUInt16() on non-smallint field. Using type: %s.", FieldTypeToString(data.type));
return 0;
}
#endif
if (data.raw)
return *reinterpret_cast<uint16*>(data.value);
return static_cast<uint16>(atol((char*)data.value));
}
int16 GetInt16() const
{
if (!data.value)
return 0;
#ifdef ACORE_DEBUG
if (!IsType(MYSQL_TYPE_SHORT) && !IsType(MYSQL_TYPE_YEAR))
{
sLog->outSQLDriver("Warning: GetInt16() on non-smallint field. Using type: %s.", FieldTypeToString(data.type));
return 0;
}
#endif
if (data.raw)
return *reinterpret_cast<int16*>(data.value);
return static_cast<int16>(atol((char*)data.value));
}
uint32 GetUInt32() const
{
if (!data.value)
return 0;
#ifdef ACORE_DEBUG
if (!IsType(MYSQL_TYPE_INT24) && !IsType(MYSQL_TYPE_LONG))
{
sLog->outSQLDriver("Warning: GetUInt32() on non-(medium)int field. Using type: %s.", FieldTypeToString(data.type));
return 0;
}
#endif
if (data.raw)
return *reinterpret_cast<uint32*>(data.value);
return static_cast<uint32>(atol((char*)data.value));
}
int32 GetInt32() const
{
if (!data.value)
return 0;
#ifdef ACORE_DEBUG
if (!IsType(MYSQL_TYPE_INT24) && !IsType(MYSQL_TYPE_LONG))
{
sLog->outSQLDriver("Warning: GetInt32() on non-(medium)int field. Using type: %s.", FieldTypeToString(data.type));
return 0;
}
#endif
if (data.raw)
return *reinterpret_cast<int32*>(data.value);
return static_cast<int32>(atol((char*)data.value));
}
uint64 GetUInt64() const
{
if (!data.value)
return 0;
#ifdef ACORE_DEBUG
if (!IsType(MYSQL_TYPE_LONGLONG) && !IsType(MYSQL_TYPE_BIT))
{
sLog->outSQLDriver("Warning: GetUInt64() on non-bigint field. Using type: %s.", FieldTypeToString(data.type));
return 0;
}
#endif
if (data.raw)
return *reinterpret_cast<uint64*>(data.value);
return static_cast<uint64>(atol((char*)data.value));
}
int64 GetInt64() const
{
if (!data.value)
return 0;
#ifdef ACORE_DEBUG
if (!IsType(MYSQL_TYPE_LONGLONG) && !IsType(MYSQL_TYPE_BIT))
{
sLog->outSQLDriver("Warning: GetInt64() on non-bigint field. Using type: %s.", FieldTypeToString(data.type));
return 0;
}
#endif
if (data.raw)
return *reinterpret_cast<int64*>(data.value);
return static_cast<int64>(strtol((char*)data.value, NULL, 10));
}
float GetFloat() const
{
if (!data.value)
return 0.0f;
#ifdef ACORE_DEBUG
if (!IsType(MYSQL_TYPE_FLOAT))
{
sLog->outSQLDriver("Warning: GetFloat() on non-float field. Using type: %s.", FieldTypeToString(data.type));
return 0.0f;
}
#endif
if (data.raw)
return *reinterpret_cast<float*>(data.value);
return static_cast<float>(atof((char*)data.value));
}
double GetDouble() const
{
if (!data.value)
return 0.0f;
#ifdef ACORE_DEBUG
if (!IsType(MYSQL_TYPE_DOUBLE))
{
sLog->outSQLDriver("Warning: GetDouble() on non-double field. Using type: %s.", FieldTypeToString(data.type));
return 0.0f;
}
#endif
if (data.raw)
return *reinterpret_cast<double*>(data.value);
return static_cast<double>(atof((char*)data.value));
}
char const* GetCString() const
{
if (!data.value)
return NULL;
#ifdef ACORE_DEBUG
if (IsNumeric())
{
sLog->outSQLDriver("Error: GetCString() on numeric field. Using type: %s.", FieldTypeToString(data.type));
return NULL;
}
#endif
return static_cast<char const*>(data.value);
}
std::string GetString() const
{
if (!data.value)
return "";
if (data.raw)
{
char const* string = GetCString();
if (!string)
string = "";
return std::string(string, data.length);
}
return std::string((char*)data.value);
}
bool IsNull() const
{
return data.value == NULL;
}
protected:
Field();
~Field();
#if defined(__GNUC__)
#pragma pack(1)
#else
#pragma pack(push, 1)
#endif
struct
{
uint32 length; // Length (prepared strings only)
void* value; // Actual data in memory
enum_field_types type; // Field type
bool raw; // Raw bytes? (Prepared statement or ad hoc)
} data;
#if defined(__GNUC__)
#pragma pack()
#else
#pragma pack(pop)
#endif
void SetByteValue(void const* newValue, size_t const newSize, enum_field_types newType, uint32 length);
void SetStructuredValue(char* newValue, enum_field_types newType);
void CleanUp()
{
delete[] ((char*)data.value);
data.value = NULL;
}
static size_t SizeForType(MYSQL_FIELD* field)
{
switch (field->type)
{
case MYSQL_TYPE_NULL:
return 0;
case MYSQL_TYPE_TINY:
return 1;
case MYSQL_TYPE_YEAR:
case MYSQL_TYPE_SHORT:
return 2;
case MYSQL_TYPE_INT24:
case MYSQL_TYPE_LONG:
case MYSQL_TYPE_FLOAT:
return 4;
case MYSQL_TYPE_DOUBLE:
case MYSQL_TYPE_LONGLONG:
case MYSQL_TYPE_BIT:
return 8;
#ifdef ACORE_DEBUG
if (!IsType(MYSQL_TYPE_SHORT) && !IsType(MYSQL_TYPE_YEAR))
{
sLog->outSQLDriver("Warning: GetUInt16() on non-smallint field. Using type: %s.", FieldTypeToString(data.type));
case MYSQL_TYPE_TIMESTAMP:
case MYSQL_TYPE_DATE:
case MYSQL_TYPE_TIME:
case MYSQL_TYPE_DATETIME:
return sizeof(MYSQL_TIME);
case MYSQL_TYPE_TINY_BLOB:
case MYSQL_TYPE_MEDIUM_BLOB:
case MYSQL_TYPE_LONG_BLOB:
case MYSQL_TYPE_BLOB:
case MYSQL_TYPE_STRING:
case MYSQL_TYPE_VAR_STRING:
return field->max_length + 1;
case MYSQL_TYPE_DECIMAL:
case MYSQL_TYPE_NEWDECIMAL:
return 64;
case MYSQL_TYPE_GEOMETRY:
/*
Following types are not sent over the wire:
MYSQL_TYPE_ENUM:
MYSQL_TYPE_SET:
*/
default:
sLog->outSQLDriver("SQL::SizeForType(): invalid field type %u", uint32(field->type));
return 0;
}
#endif
if (data.raw)
return *reinterpret_cast<uint16*>(data.value);
return static_cast<uint16>(atol((char*)data.value));
}
}
int16 GetInt16() const
bool IsType(enum_field_types type) const
{
return data.type == type;
}
bool IsNumeric() const
{
return (data.type == MYSQL_TYPE_TINY ||
data.type == MYSQL_TYPE_SHORT ||
data.type == MYSQL_TYPE_INT24 ||
data.type == MYSQL_TYPE_LONG ||
data.type == MYSQL_TYPE_FLOAT ||
data.type == MYSQL_TYPE_DOUBLE ||
data.type == MYSQL_TYPE_LONGLONG );
}
private:
#ifdef ACORE_DEBUG
static char const* FieldTypeToString(enum_field_types type)
{
switch (type)
{
if (!data.value)
return 0;
#ifdef ACORE_DEBUG
if (!IsType(MYSQL_TYPE_SHORT) && !IsType(MYSQL_TYPE_YEAR))
{
sLog->outSQLDriver("Warning: GetInt16() on non-smallint field. Using type: %s.", FieldTypeToString(data.type));
return 0;
}
#endif
if (data.raw)
return *reinterpret_cast<int16*>(data.value);
return static_cast<int16>(atol((char*)data.value));
case MYSQL_TYPE_BIT:
return "BIT";
case MYSQL_TYPE_BLOB:
return "BLOB";
case MYSQL_TYPE_DATE:
return "DATE";
case MYSQL_TYPE_DATETIME:
return "DATETIME";
case MYSQL_TYPE_NEWDECIMAL:
return "NEWDECIMAL";
case MYSQL_TYPE_DECIMAL:
return "DECIMAL";
case MYSQL_TYPE_DOUBLE:
return "DOUBLE";
case MYSQL_TYPE_ENUM:
return "ENUM";
case MYSQL_TYPE_FLOAT:
return "FLOAT";
case MYSQL_TYPE_GEOMETRY:
return "GEOMETRY";
case MYSQL_TYPE_INT24:
return "INT24";
case MYSQL_TYPE_LONG:
return "LONG";
case MYSQL_TYPE_LONGLONG:
return "LONGLONG";
case MYSQL_TYPE_LONG_BLOB:
return "LONG_BLOB";
case MYSQL_TYPE_MEDIUM_BLOB:
return "MEDIUM_BLOB";
case MYSQL_TYPE_NEWDATE:
return "NEWDATE";
case MYSQL_TYPE_NULL:
return "NULL";
case MYSQL_TYPE_SET:
return "SET";
case MYSQL_TYPE_SHORT:
return "SHORT";
case MYSQL_TYPE_STRING:
return "STRING";
case MYSQL_TYPE_TIME:
return "TIME";
case MYSQL_TYPE_TIMESTAMP:
return "TIMESTAMP";
case MYSQL_TYPE_TINY:
return "TINY";
case MYSQL_TYPE_TINY_BLOB:
return "TINY_BLOB";
case MYSQL_TYPE_VAR_STRING:
return "VAR_STRING";
case MYSQL_TYPE_YEAR:
return "YEAR";
default:
return "-Unknown-";
}
uint32 GetUInt32() const
{
if (!data.value)
return 0;
#ifdef ACORE_DEBUG
if (!IsType(MYSQL_TYPE_INT24) && !IsType(MYSQL_TYPE_LONG))
{
sLog->outSQLDriver("Warning: GetUInt32() on non-(medium)int field. Using type: %s.", FieldTypeToString(data.type));
return 0;
}
#endif
if (data.raw)
return *reinterpret_cast<uint32*>(data.value);
return static_cast<uint32>(atol((char*)data.value));
}
int32 GetInt32() const
{
if (!data.value)
return 0;
#ifdef ACORE_DEBUG
if (!IsType(MYSQL_TYPE_INT24) && !IsType(MYSQL_TYPE_LONG))
{
sLog->outSQLDriver("Warning: GetInt32() on non-(medium)int field. Using type: %s.", FieldTypeToString(data.type));
return 0;
}
#endif
if (data.raw)
return *reinterpret_cast<int32*>(data.value);
return static_cast<int32>(atol((char*)data.value));
}
uint64 GetUInt64() const
{
if (!data.value)
return 0;
#ifdef ACORE_DEBUG
if (!IsType(MYSQL_TYPE_LONGLONG) && !IsType(MYSQL_TYPE_BIT))
{
sLog->outSQLDriver("Warning: GetUInt64() on non-bigint field. Using type: %s.", FieldTypeToString(data.type));
return 0;
}
#endif
if (data.raw)
return *reinterpret_cast<uint64*>(data.value);
return static_cast<uint64>(atol((char*)data.value));
}
int64 GetInt64() const
{
if (!data.value)
return 0;
#ifdef ACORE_DEBUG
if (!IsType(MYSQL_TYPE_LONGLONG) && !IsType(MYSQL_TYPE_BIT))
{
sLog->outSQLDriver("Warning: GetInt64() on non-bigint field. Using type: %s.", FieldTypeToString(data.type));
return 0;
}
#endif
if (data.raw)
return *reinterpret_cast<int64*>(data.value);
return static_cast<int64>(strtol((char*)data.value, NULL, 10));
}
float GetFloat() const
{
if (!data.value)
return 0.0f;
#ifdef ACORE_DEBUG
if (!IsType(MYSQL_TYPE_FLOAT))
{
sLog->outSQLDriver("Warning: GetFloat() on non-float field. Using type: %s.", FieldTypeToString(data.type));
return 0.0f;
}
#endif
if (data.raw)
return *reinterpret_cast<float*>(data.value);
return static_cast<float>(atof((char*)data.value));
}
double GetDouble() const
{
if (!data.value)
return 0.0f;
#ifdef ACORE_DEBUG
if (!IsType(MYSQL_TYPE_DOUBLE))
{
sLog->outSQLDriver("Warning: GetDouble() on non-double field. Using type: %s.", FieldTypeToString(data.type));
return 0.0f;
}
#endif
if (data.raw)
return *reinterpret_cast<double*>(data.value);
return static_cast<double>(atof((char*)data.value));
}
char const* GetCString() const
{
if (!data.value)
return NULL;
#ifdef ACORE_DEBUG
if (IsNumeric())
{
sLog->outSQLDriver("Error: GetCString() on numeric field. Using type: %s.", FieldTypeToString(data.type));
return NULL;
}
#endif
return static_cast<char const*>(data.value);
}
std::string GetString() const
{
if (!data.value)
return "";
if (data.raw)
{
char const* string = GetCString();
if (!string)
string = "";
return std::string(string, data.length);
}
return std::string((char*)data.value);
}
bool IsNull() const
{
return data.value == NULL;
}
protected:
Field();
~Field();
#if defined(__GNUC__)
#pragma pack(1)
#else
#pragma pack(push, 1)
#endif
struct
{
uint32 length; // Length (prepared strings only)
void* value; // Actual data in memory
enum_field_types type; // Field type
bool raw; // Raw bytes? (Prepared statement or ad hoc)
} data;
#if defined(__GNUC__)
#pragma pack()
#else
#pragma pack(pop)
#endif
void SetByteValue(void const* newValue, size_t const newSize, enum_field_types newType, uint32 length);
void SetStructuredValue(char* newValue, enum_field_types newType);
void CleanUp()
{
delete[] ((char*)data.value);
data.value = NULL;
}
static size_t SizeForType(MYSQL_FIELD* field)
{
switch (field->type)
{
case MYSQL_TYPE_NULL:
return 0;
case MYSQL_TYPE_TINY:
return 1;
case MYSQL_TYPE_YEAR:
case MYSQL_TYPE_SHORT:
return 2;
case MYSQL_TYPE_INT24:
case MYSQL_TYPE_LONG:
case MYSQL_TYPE_FLOAT:
return 4;
case MYSQL_TYPE_DOUBLE:
case MYSQL_TYPE_LONGLONG:
case MYSQL_TYPE_BIT:
return 8;
case MYSQL_TYPE_TIMESTAMP:
case MYSQL_TYPE_DATE:
case MYSQL_TYPE_TIME:
case MYSQL_TYPE_DATETIME:
return sizeof(MYSQL_TIME);
case MYSQL_TYPE_TINY_BLOB:
case MYSQL_TYPE_MEDIUM_BLOB:
case MYSQL_TYPE_LONG_BLOB:
case MYSQL_TYPE_BLOB:
case MYSQL_TYPE_STRING:
case MYSQL_TYPE_VAR_STRING:
return field->max_length + 1;
case MYSQL_TYPE_DECIMAL:
case MYSQL_TYPE_NEWDECIMAL:
return 64;
case MYSQL_TYPE_GEOMETRY:
/*
Following types are not sent over the wire:
MYSQL_TYPE_ENUM:
MYSQL_TYPE_SET:
*/
default:
sLog->outSQLDriver("SQL::SizeForType(): invalid field type %u", uint32(field->type));
return 0;
}
}
bool IsType(enum_field_types type) const
{
return data.type == type;
}
bool IsNumeric() const
{
return (data.type == MYSQL_TYPE_TINY ||
data.type == MYSQL_TYPE_SHORT ||
data.type == MYSQL_TYPE_INT24 ||
data.type == MYSQL_TYPE_LONG ||
data.type == MYSQL_TYPE_FLOAT ||
data.type == MYSQL_TYPE_DOUBLE ||
data.type == MYSQL_TYPE_LONGLONG );
}
private:
#ifdef ACORE_DEBUG
static char const* FieldTypeToString(enum_field_types type)
{
switch (type)
{
case MYSQL_TYPE_BIT: return "BIT";
case MYSQL_TYPE_BLOB: return "BLOB";
case MYSQL_TYPE_DATE: return "DATE";
case MYSQL_TYPE_DATETIME: return "DATETIME";
case MYSQL_TYPE_NEWDECIMAL: return "NEWDECIMAL";
case MYSQL_TYPE_DECIMAL: return "DECIMAL";
case MYSQL_TYPE_DOUBLE: return "DOUBLE";
case MYSQL_TYPE_ENUM: return "ENUM";
case MYSQL_TYPE_FLOAT: return "FLOAT";
case MYSQL_TYPE_GEOMETRY: return "GEOMETRY";
case MYSQL_TYPE_INT24: return "INT24";
case MYSQL_TYPE_LONG: return "LONG";
case MYSQL_TYPE_LONGLONG: return "LONGLONG";
case MYSQL_TYPE_LONG_BLOB: return "LONG_BLOB";
case MYSQL_TYPE_MEDIUM_BLOB: return "MEDIUM_BLOB";
case MYSQL_TYPE_NEWDATE: return "NEWDATE";
case MYSQL_TYPE_NULL: return "NULL";
case MYSQL_TYPE_SET: return "SET";
case MYSQL_TYPE_SHORT: return "SHORT";
case MYSQL_TYPE_STRING: return "STRING";
case MYSQL_TYPE_TIME: return "TIME";
case MYSQL_TYPE_TIMESTAMP: return "TIMESTAMP";
case MYSQL_TYPE_TINY: return "TINY";
case MYSQL_TYPE_TINY_BLOB: return "TINY_BLOB";
case MYSQL_TYPE_VAR_STRING: return "VAR_STRING";
case MYSQL_TYPE_YEAR: return "YEAR";
default: return "-Unknown-";
}
}
#endif
}
#endif
};
#endif

View File

@@ -148,8 +148,8 @@ void CharacterDatabaseConnection::DoPrepareStatements()
PrepareStatement(CHAR_DEL_GUILD_MEMBER, "DELETE FROM guild_member WHERE guid = ?", CONNECTION_ASYNC); // 0: uint32
PrepareStatement(CHAR_DEL_GUILD_MEMBERS, "DELETE FROM guild_member WHERE guildid = ?", CONNECTION_ASYNC); // 0: uint32
PrepareStatement(CHAR_SEL_GUILD_MEMBER_EXTENDED, "SELECT g.guildid, g.name, gr.rname, gm.pnote, gm.offnote "
"FROM guild g JOIN guild_member gm ON g.guildid = gm.guildid "
"JOIN guild_rank gr ON g.guildid = gr.guildid AND gm.`rank` = gr.rid WHERE gm.guid = ?", CONNECTION_BOTH);
"FROM guild g JOIN guild_member gm ON g.guildid = gm.guildid "
"JOIN guild_rank gr ON g.guildid = gr.guildid AND gm.`rank` = gr.rid WHERE gm.guid = ?", CONNECTION_BOTH);
// 0: uint32, 1: uint8, 3: string, 4: uint32, 5: uint32
PrepareStatement(CHAR_INS_GUILD_RANK, "INSERT INTO guild_rank (guildid, rid, rname, rights, BankMoneyPerDay) VALUES (?, ?, ?, ?, ?)", CONNECTION_ASYNC);
PrepareStatement(CHAR_DEL_GUILD_RANKS, "DELETE FROM guild_rank WHERE guildid = ?", CONNECTION_ASYNC); // 0: uint32
@@ -403,7 +403,7 @@ void CharacterDatabaseConnection::DoPrepareStatements()
PrepareStatement(CHAR_DEL_CHAR_AURA_FROZEN, "DELETE FROM character_aura WHERE spell = 9454 AND guid = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_SEL_CHAR_INVENTORY_COUNT_ITEM, "SELECT COUNT(itemEntry) FROM character_inventory ci INNER JOIN item_instance ii ON ii.guid = ci.item WHERE itemEntry = ?", CONNECTION_SYNCH);
PrepareStatement(CHAR_SEL_MAIL_COUNT_ITEM, "SELECT COUNT(itemEntry) FROM mail_items mi INNER JOIN item_instance ii ON ii.guid = mi.item_guid WHERE itemEntry = ?", CONNECTION_SYNCH);
PrepareStatement(CHAR_SEL_AUCTIONHOUSE_COUNT_ITEM,"SELECT COUNT(itemEntry) FROM auctionhouse ah INNER JOIN item_instance ii ON ii.guid = ah.itemguid WHERE itemEntry = ?", CONNECTION_SYNCH);
PrepareStatement(CHAR_SEL_AUCTIONHOUSE_COUNT_ITEM, "SELECT COUNT(itemEntry) FROM auctionhouse ah INNER JOIN item_instance ii ON ii.guid = ah.itemguid WHERE itemEntry = ?", CONNECTION_SYNCH);
PrepareStatement(CHAR_SEL_GUILD_BANK_COUNT_ITEM, "SELECT COUNT(itemEntry) FROM guild_bank_item gbi INNER JOIN item_instance ii ON ii.guid = gbi.item_guid WHERE itemEntry = ?", CONNECTION_SYNCH);
PrepareStatement(CHAR_SEL_CHAR_INVENTORY_ITEM_BY_ENTRY, "SELECT ci.item, cb.slot AS bag, ci.slot, ci.guid, c.account, c.name FROM characters c "
"INNER JOIN character_inventory ci ON ci.guid = c.guid "

View File

@@ -12,13 +12,13 @@
class CharacterDatabaseConnection : public MySQLConnection
{
public:
//- Constructors for sync and async connections
CharacterDatabaseConnection(MySQLConnectionInfo& connInfo) : MySQLConnection(connInfo) {}
CharacterDatabaseConnection(ACE_Activation_Queue* q, MySQLConnectionInfo& connInfo) : MySQLConnection(q, connInfo) {}
public:
//- Constructors for sync and async connections
CharacterDatabaseConnection(MySQLConnectionInfo& connInfo) : MySQLConnection(connInfo) {}
CharacterDatabaseConnection(ACE_Activation_Queue* q, MySQLConnectionInfo& connInfo) : MySQLConnection(q, connInfo) {}
//- Loads database type specific prepared statements
void DoPrepareStatements();
//- Loads database type specific prepared statements
void DoPrepareStatements();
};
typedef DatabaseWorkerPool<CharacterDatabaseConnection> CharacterDatabaseWorkerPool;

View File

@@ -12,13 +12,13 @@
class LoginDatabaseConnection : public MySQLConnection
{
public:
//- Constructors for sync and async connections
LoginDatabaseConnection(MySQLConnectionInfo& connInfo) : MySQLConnection(connInfo) { }
LoginDatabaseConnection(ACE_Activation_Queue* q, MySQLConnectionInfo& connInfo) : MySQLConnection(q, connInfo) { }
public:
//- Constructors for sync and async connections
LoginDatabaseConnection(MySQLConnectionInfo& connInfo) : MySQLConnection(connInfo) { }
LoginDatabaseConnection(ACE_Activation_Queue* q, MySQLConnectionInfo& connInfo) : MySQLConnection(q, connInfo) { }
//- Loads database type specific prepared statements
void DoPrepareStatements();
//- Loads database type specific prepared statements
void DoPrepareStatements();
};
typedef DatabaseWorkerPool<LoginDatabaseConnection> LoginDatabaseWorkerPool;

View File

@@ -12,13 +12,13 @@
class WorldDatabaseConnection : public MySQLConnection
{
public:
//- Constructors for sync and async connections
WorldDatabaseConnection(MySQLConnectionInfo& connInfo) : MySQLConnection(connInfo) { }
WorldDatabaseConnection(ACE_Activation_Queue* q, MySQLConnectionInfo& connInfo) : MySQLConnection(q, connInfo) { }
public:
//- Constructors for sync and async connections
WorldDatabaseConnection(MySQLConnectionInfo& connInfo) : MySQLConnection(connInfo) { }
WorldDatabaseConnection(ACE_Activation_Queue* q, MySQLConnectionInfo& connInfo) : MySQLConnection(q, connInfo) { }
//- Loads database type specific prepared statements
void DoPrepareStatements();
//- Loads database type specific prepared statements
void DoPrepareStatements();
};
typedef DatabaseWorkerPool<WorldDatabaseConnection> WorldDatabaseWorkerPool;

View File

@@ -24,23 +24,23 @@
#endif
MySQLConnection::MySQLConnection(MySQLConnectionInfo& connInfo) :
m_reconnecting(false),
m_prepareError(false),
m_queue(NULL),
m_worker(NULL),
m_Mysql(NULL),
m_connectionInfo(connInfo),
m_connectionFlags(CONNECTION_SYNCH)
m_reconnecting(false),
m_prepareError(false),
m_queue(NULL),
m_worker(NULL),
m_Mysql(NULL),
m_connectionInfo(connInfo),
m_connectionFlags(CONNECTION_SYNCH)
{
}
MySQLConnection::MySQLConnection(ACE_Activation_Queue* queue, MySQLConnectionInfo& connInfo) :
m_reconnecting(false),
m_prepareError(false),
m_queue(queue),
m_Mysql(NULL),
m_connectionInfo(connInfo),
m_connectionFlags(CONNECTION_ASYNC)
m_reconnecting(false),
m_prepareError(false),
m_queue(queue),
m_Mysql(NULL),
m_connectionInfo(connInfo),
m_connectionFlags(CONNECTION_ASYNC)
{
m_worker = new DatabaseWorker(m_queue, this);
}
@@ -63,7 +63,7 @@ void MySQLConnection::Close()
bool MySQLConnection::Open()
{
MYSQL *mysqlInit;
MYSQL* mysqlInit;
mysqlInit = mysql_init(NULL);
if (!mysqlInit)
{
@@ -77,7 +77,7 @@ bool MySQLConnection::Open()
mysql_options(mysqlInit, MYSQL_SET_CHARSET_NAME, "utf8");
//mysql_options(mysqlInit, MYSQL_OPT_READ_TIMEOUT, (char const*)&timeout);
#ifdef _WIN32
#ifdef _WIN32
if (m_connectionInfo.host == ".") // named pipe use option (Windows)
{
unsigned int opt = MYSQL_PROTOCOL_PIPE;
@@ -90,7 +90,7 @@ bool MySQLConnection::Open()
port = atoi(m_connectionInfo.port_or_socket.c_str());
unix_socket = 0;
}
#else
#else
if (m_connectionInfo.host == ".") // socket use option (Unix/Linux)
{
unsigned int opt = MYSQL_PROTOCOL_SOCKET;
@@ -104,22 +104,23 @@ bool MySQLConnection::Open()
port = atoi(m_connectionInfo.port_or_socket.c_str());
unix_socket = 0;
}
#endif
#endif
// Possible improvement for future: make ATTEMPTS and SECONDS configurable values
uint32 const ATTEMPTS = 180;
uint32 count = 0;
do {
do
{
m_Mysql = mysql_real_connect(
mysqlInit,
m_connectionInfo.host.c_str(),
m_connectionInfo.user.c_str(),
m_connectionInfo.password.c_str(),
m_connectionInfo.database.c_str(),
port,
unix_socket,
0);
mysqlInit,
m_connectionInfo.host.c_str(),
m_connectionInfo.user.c_str(),
m_connectionInfo.password.c_str(),
m_connectionInfo.database.c_str(),
port,
unix_socket,
0);
if (m_Mysql)
{
@@ -250,7 +251,7 @@ bool MySQLConnection::Execute(PreparedStatement* stmt)
}
}
bool MySQLConnection::_Query(PreparedStatement* stmt, MYSQL_RES **pResult, uint64* pRowCount, uint32* pFieldCount)
bool MySQLConnection::_Query(PreparedStatement* stmt, MYSQL_RES** pResult, uint64* pRowCount, uint32* pFieldCount)
{
if (!m_Mysql)
return false;
@@ -287,7 +288,7 @@ bool MySQLConnection::_Query(PreparedStatement* stmt, MYSQL_RES **pResult, uint6
{
uint32 lErrno = mysql_errno(m_Mysql);
sLog->outSQLDriver("SQL(p): %s\n [ERROR]: [%u] %s",
m_mStmt->getQueryString(m_queries[index].first).c_str(), lErrno, mysql_stmt_error(msql_STMT));
m_mStmt->getQueryString(m_queries[index].first).c_str(), lErrno, mysql_stmt_error(msql_STMT));
if (_HandleMySQLErrno(lErrno)) // If it returns true, an error was handled successfully (i.e. reconnection)
return _Query(stmt, pResult, pRowCount, pFieldCount); // Try again
@@ -315,8 +316,8 @@ ResultSet* MySQLConnection::Query(const char* sql)
if (!sql)
return NULL;
MYSQL_RES *result = NULL;
MYSQL_FIELD *fields = NULL;
MYSQL_RES* result = NULL;
MYSQL_FIELD* fields = NULL;
uint64 rowCount = 0;
uint32 fieldCount = 0;
@@ -326,7 +327,7 @@ ResultSet* MySQLConnection::Query(const char* sql)
return new ResultSet(result, fields, rowCount, fieldCount);
}
bool MySQLConnection::_Query(const char *sql, MYSQL_RES **pResult, MYSQL_FIELD **pFields, uint64* pRowCount, uint32* pFieldCount)
bool MySQLConnection::_Query(const char* sql, MYSQL_RES** pResult, MYSQL_FIELD** pFields, uint64* pRowCount, uint32* pFieldCount)
{
if (!m_Mysql)
return false;
@@ -401,29 +402,29 @@ bool MySQLConnection::ExecuteTransaction(SQLTransaction& transaction)
switch (itr->type)
{
case SQL_ELEMENT_PREPARED:
{
PreparedStatement* stmt = data.element.stmt;
ASSERT(stmt);
if (!Execute(stmt))
{
sLog->outSQLDriver("[Warning] Transaction aborted. %u queries not executed.", (uint32)queries.size());
RollbackTransaction();
return false;
PreparedStatement* stmt = data.element.stmt;
ASSERT(stmt);
if (!Execute(stmt))
{
sLog->outSQLDriver("[Warning] Transaction aborted. %u queries not executed.", (uint32)queries.size());
RollbackTransaction();
return false;
}
}
}
break;
break;
case SQL_ELEMENT_RAW:
{
const char* sql = data.element.query;
ASSERT(sql);
if (!Execute(sql))
{
sLog->outSQLDriver("[Warning] Transaction aborted. %u queries not executed.", (uint32)queries.size());
RollbackTransaction();
return false;
const char* sql = data.element.query;
ASSERT(sql);
if (!Execute(sql))
{
sLog->outSQLDriver("[Warning] Transaction aborted. %u queries not executed.", (uint32)queries.size());
RollbackTransaction();
return false;
}
}
}
break;
break;
}
}
@@ -442,7 +443,7 @@ MySQLPreparedStatement* MySQLConnection::GetPreparedStatement(uint32 index)
MySQLPreparedStatement* ret = m_stmts[index];
if (!ret)
sLog->outSQLDriver("ERROR: Could not fetch prepared statement %u on database `%s`, connection type: %s.",
index, m_connectionInfo.database.c_str(), (m_connectionFlags & CONNECTION_ASYNC) ? "asynchronous" : "synchronous");
index, m_connectionInfo.database.c_str(), (m_connectionFlags & CONNECTION_ASYNC) ? "asynchronous" : "synchronous");
return ret;
}
@@ -490,7 +491,7 @@ void MySQLConnection::PrepareStatement(uint32 index, const char* sql, Connection
PreparedResultSet* MySQLConnection::Query(PreparedStatement* stmt)
{
MYSQL_RES *result = NULL;
MYSQL_RES* result = NULL;
uint64 rowCount = 0;
uint32 fieldCount = 0;
@@ -514,27 +515,27 @@ bool MySQLConnection::_HandleMySQLErrno(uint32 errNo)
#if !(MARIADB_VERSION_ID >= 100200)
case CR_INVALID_CONN_HANDLE:
#endif
{
m_reconnecting = true;
uint64 oldThreadId = mysql_thread_id(GetHandle());
mysql_close(GetHandle());
if (this->Open()) // Don't remove 'this' pointer unless you want to skip loading all prepared statements....
{
sLog->outSQLDriver("Connection to the MySQL server is active.");
if (oldThreadId != mysql_thread_id(GetHandle()))
sLog->outSQLDriver("Successfully reconnected to %s @%s:%s (%s).",
m_connectionInfo.database.c_str(), m_connectionInfo.host.c_str(), m_connectionInfo.port_or_socket.c_str(),
(m_connectionFlags & CONNECTION_ASYNC) ? "asynchronous" : "synchronous");
m_reconnecting = true;
uint64 oldThreadId = mysql_thread_id(GetHandle());
mysql_close(GetHandle());
if (this->Open()) // Don't remove 'this' pointer unless you want to skip loading all prepared statements....
{
sLog->outSQLDriver("Connection to the MySQL server is active.");
if (oldThreadId != mysql_thread_id(GetHandle()))
sLog->outSQLDriver("Successfully reconnected to %s @%s:%s (%s).",
m_connectionInfo.database.c_str(), m_connectionInfo.host.c_str(), m_connectionInfo.port_or_socket.c_str(),
(m_connectionFlags & CONNECTION_ASYNC) ? "asynchronous" : "synchronous");
m_reconnecting = false;
return true;
m_reconnecting = false;
return true;
}
uint32 lErrno = mysql_errno(GetHandle()); // It's possible this attempted reconnect throws 2006 at us. To prevent crazy recursive calls, sleep here.
std::this_thread::sleep_for(3s); // Sleep 3 seconds
return _HandleMySQLErrno(lErrno); // Call self (recursive)
}
uint32 lErrno = mysql_errno(GetHandle()); // It's possible this attempted reconnect throws 2006 at us. To prevent crazy recursive calls, sleep here.
std::this_thread::sleep_for(3s); // Sleep 3 seconds
return _HandleMySQLErrno(lErrno); // Call self (recursive)
}
case ER_LOCK_DEADLOCK:
return false; // Implemented in TransactionTask::Execute and DatabaseWorkerPool<T>::DirectCommitTransaction
// Query related errors - skip query

View File

@@ -58,69 +58,69 @@ class MySQLConnection
template <class T> friend class DatabaseWorkerPool;
friend class PingOperation;
public:
MySQLConnection(MySQLConnectionInfo& connInfo); //! Constructor for synchronous connections.
MySQLConnection(ACE_Activation_Queue* queue, MySQLConnectionInfo& connInfo); //! Constructor for asynchronous connections.
virtual ~MySQLConnection();
public:
MySQLConnection(MySQLConnectionInfo& connInfo); //! Constructor for synchronous connections.
MySQLConnection(ACE_Activation_Queue* queue, MySQLConnectionInfo& connInfo); //! Constructor for asynchronous connections.
virtual ~MySQLConnection();
virtual bool Open();
void Close();
virtual bool Open();
void Close();
public:
bool Execute(const char* sql);
bool Execute(PreparedStatement* stmt);
ResultSet* Query(const char* sql);
PreparedResultSet* Query(PreparedStatement* stmt);
bool _Query(const char *sql, MYSQL_RES **pResult, MYSQL_FIELD **pFields, uint64* pRowCount, uint32* pFieldCount);
bool _Query(PreparedStatement* stmt, MYSQL_RES **pResult, uint64* pRowCount, uint32* pFieldCount);
public:
bool Execute(const char* sql);
bool Execute(PreparedStatement* stmt);
ResultSet* Query(const char* sql);
PreparedResultSet* Query(PreparedStatement* stmt);
bool _Query(const char* sql, MYSQL_RES** pResult, MYSQL_FIELD** pFields, uint64* pRowCount, uint32* pFieldCount);
bool _Query(PreparedStatement* stmt, MYSQL_RES** pResult, uint64* pRowCount, uint32* pFieldCount);
void BeginTransaction();
void RollbackTransaction();
void CommitTransaction();
bool ExecuteTransaction(SQLTransaction& transaction);
void BeginTransaction();
void RollbackTransaction();
void CommitTransaction();
bool ExecuteTransaction(SQLTransaction& transaction);
operator bool () const { return m_Mysql != NULL; }
void Ping() { mysql_ping(m_Mysql); }
operator bool () const { return m_Mysql != NULL; }
void Ping() { mysql_ping(m_Mysql); }
uint32 GetLastError() { return mysql_errno(m_Mysql); }
uint32 GetLastError() { return mysql_errno(m_Mysql); }
protected:
bool LockIfReady()
{
/// Tries to acquire lock. If lock is acquired by another thread
/// the calling parent will just try another connection
return m_Mutex.tryacquire() != -1;
}
protected:
bool LockIfReady()
{
/// Tries to acquire lock. If lock is acquired by another thread
/// the calling parent will just try another connection
return m_Mutex.tryacquire() != -1;
}
void Unlock()
{
/// Called by parent databasepool. Will let other threads access this connection
m_Mutex.release();
}
void Unlock()
{
/// Called by parent databasepool. Will let other threads access this connection
m_Mutex.release();
}
MYSQL* GetHandle() { return m_Mysql; }
MySQLPreparedStatement* GetPreparedStatement(uint32 index);
void PrepareStatement(uint32 index, const char* sql, ConnectionFlags flags);
MYSQL* GetHandle() { return m_Mysql; }
MySQLPreparedStatement* GetPreparedStatement(uint32 index);
void PrepareStatement(uint32 index, const char* sql, ConnectionFlags flags);
bool PrepareStatements();
virtual void DoPrepareStatements() = 0;
bool PrepareStatements();
virtual void DoPrepareStatements() = 0;
protected:
std::vector<MySQLPreparedStatement*> m_stmts; //! PreparedStatements storage
PreparedStatementMap m_queries; //! Query storage
bool m_reconnecting; //! Are we reconnecting?
bool m_prepareError; //! Was there any error while preparing statements?
protected:
std::vector<MySQLPreparedStatement*> m_stmts; //! PreparedStatements storage
PreparedStatementMap m_queries; //! Query storage
bool m_reconnecting; //! Are we reconnecting?
bool m_prepareError; //! Was there any error while preparing statements?
private:
bool _HandleMySQLErrno(uint32 errNo);
private:
bool _HandleMySQLErrno(uint32 errNo);
private:
ACE_Activation_Queue* m_queue; //! Queue shared with other asynchronous connections.
DatabaseWorker* m_worker; //! Core worker task.
MYSQL * m_Mysql; //! MySQL Handle.
MySQLConnectionInfo& m_connectionInfo; //! Connection info (used for logging)
ConnectionFlags m_connectionFlags; //! Connection flags (for preparing relevant statements)
ACE_Thread_Mutex m_Mutex;
private:
ACE_Activation_Queue* m_queue; //! Queue shared with other asynchronous connections.
DatabaseWorker* m_worker; //! Core worker task.
MYSQL* m_Mysql; //! MySQL Handle.
MySQLConnectionInfo& m_connectionInfo; //! Connection info (used for logging)
ConnectionFlags m_connectionFlags; //! Connection flags (for preparing relevant statements)
ACE_Thread_Mutex m_Mutex;
};
#endif

View File

@@ -11,37 +11,37 @@
class MySQL
{
public:
/*! Create a thread on the MySQL server to mirrior the calling thread,
initializes thread-specific variables and allows thread-specific
operations without concurrence from other threads.
This should only be called if multiple core threads are running
on the same MySQL connection. Seperate MySQL connections implicitly
create a mirror thread.
*/
static void Thread_Init()
{
mysql_thread_init();
}
public:
/*! Create a thread on the MySQL server to mirrior the calling thread,
initializes thread-specific variables and allows thread-specific
operations without concurrence from other threads.
This should only be called if multiple core threads are running
on the same MySQL connection. Seperate MySQL connections implicitly
create a mirror thread.
*/
static void Thread_Init()
{
mysql_thread_init();
}
/*! Shuts down MySQL thread and frees resources, should only be called
when we terminate. MySQL threads and connections are not configurable
during runtime.
*/
static void Thread_End()
{
mysql_thread_end();
}
/*! Shuts down MySQL thread and frees resources, should only be called
when we terminate. MySQL threads and connections are not configurable
during runtime.
*/
static void Thread_End()
{
mysql_thread_end();
}
static void Library_Init()
{
mysql_library_init(-1, NULL, NULL);
}
static void Library_Init()
{
mysql_library_init(-1, NULL, NULL);
}
static void Library_End()
{
mysql_library_end();
}
static void Library_End()
{
mysql_library_end();
}
};
#endif

View File

@@ -9,8 +9,8 @@
#include "Log.h"
PreparedStatement::PreparedStatement(uint32 index) :
m_stmt(NULL),
m_index(index)
m_stmt(NULL),
m_index(index)
{
}
@@ -68,17 +68,17 @@ void PreparedStatement::BindParameters()
break;
}
}
#ifdef _DEBUG
#ifdef _DEBUG
if (i < m_stmt->m_paramCount)
sLog->outSQLDriver("[WARNING]: BindParameters() for statement %u did not bind all allocated parameters", m_index);
#endif
#endif
}
//- Bind to buffer
void PreparedStatement::setBool(const uint8 index, const bool value)
{
if (index >= statement_data.size())
statement_data.resize(index+1);
statement_data.resize(index + 1);
statement_data[index].data.boolean = value;
statement_data[index].type = TYPE_BOOL;
@@ -87,7 +87,7 @@ void PreparedStatement::setBool(const uint8 index, const bool value)
void PreparedStatement::setUInt8(const uint8 index, const uint8 value)
{
if (index >= statement_data.size())
statement_data.resize(index+1);
statement_data.resize(index + 1);
statement_data[index].data.ui8 = value;
statement_data[index].type = TYPE_UI8;
@@ -96,7 +96,7 @@ void PreparedStatement::setUInt8(const uint8 index, const uint8 value)
void PreparedStatement::setUInt16(const uint8 index, const uint16 value)
{
if (index >= statement_data.size())
statement_data.resize(index+1);
statement_data.resize(index + 1);
statement_data[index].data.ui16 = value;
statement_data[index].type = TYPE_UI16;
@@ -105,7 +105,7 @@ void PreparedStatement::setUInt16(const uint8 index, const uint16 value)
void PreparedStatement::setUInt32(const uint8 index, const uint32 value)
{
if (index >= statement_data.size())
statement_data.resize(index+1);
statement_data.resize(index + 1);
statement_data[index].data.ui32 = value;
statement_data[index].type = TYPE_UI32;
@@ -114,7 +114,7 @@ void PreparedStatement::setUInt32(const uint8 index, const uint32 value)
void PreparedStatement::setUInt64(const uint8 index, const uint64 value)
{
if (index >= statement_data.size())
statement_data.resize(index+1);
statement_data.resize(index + 1);
statement_data[index].data.ui64 = value;
statement_data[index].type = TYPE_UI64;
@@ -123,7 +123,7 @@ void PreparedStatement::setUInt64(const uint8 index, const uint64 value)
void PreparedStatement::setInt8(const uint8 index, const int8 value)
{
if (index >= statement_data.size())
statement_data.resize(index+1);
statement_data.resize(index + 1);
statement_data[index].data.i8 = value;
statement_data[index].type = TYPE_I8;
@@ -132,7 +132,7 @@ void PreparedStatement::setInt8(const uint8 index, const int8 value)
void PreparedStatement::setInt16(const uint8 index, const int16 value)
{
if (index >= statement_data.size())
statement_data.resize(index+1);
statement_data.resize(index + 1);
statement_data[index].data.i16 = value;
statement_data[index].type = TYPE_I16;
@@ -141,7 +141,7 @@ void PreparedStatement::setInt16(const uint8 index, const int16 value)
void PreparedStatement::setInt32(const uint8 index, const int32 value)
{
if (index >= statement_data.size())
statement_data.resize(index+1);
statement_data.resize(index + 1);
statement_data[index].data.i32 = value;
statement_data[index].type = TYPE_I32;
@@ -150,7 +150,7 @@ void PreparedStatement::setInt32(const uint8 index, const int32 value)
void PreparedStatement::setInt64(const uint8 index, const int64 value)
{
if (index >= statement_data.size())
statement_data.resize(index+1);
statement_data.resize(index + 1);
statement_data[index].data.i64 = value;
statement_data[index].type = TYPE_I64;
@@ -159,7 +159,7 @@ void PreparedStatement::setInt64(const uint8 index, const int64 value)
void PreparedStatement::setFloat(const uint8 index, const float value)
{
if (index >= statement_data.size())
statement_data.resize(index+1);
statement_data.resize(index + 1);
statement_data[index].data.f = value;
statement_data[index].type = TYPE_FLOAT;
@@ -168,7 +168,7 @@ void PreparedStatement::setFloat(const uint8 index, const float value)
void PreparedStatement::setDouble(const uint8 index, const double value)
{
if (index >= statement_data.size())
statement_data.resize(index+1);
statement_data.resize(index + 1);
statement_data[index].data.d = value;
statement_data[index].type = TYPE_DOUBLE;
@@ -177,7 +177,7 @@ void PreparedStatement::setDouble(const uint8 index, const double value)
void PreparedStatement::setString(const uint8 index, const std::string& value)
{
if (index >= statement_data.size())
statement_data.resize(index+1);
statement_data.resize(index + 1);
statement_data[index].str = value;
statement_data[index].type = TYPE_STRING;
@@ -186,15 +186,15 @@ void PreparedStatement::setString(const uint8 index, const std::string& value)
void PreparedStatement::setNull(const uint8 index)
{
if (index >= statement_data.size())
statement_data.resize(index+1);
statement_data.resize(index + 1);
statement_data[index].type = TYPE_NULL;
}
MySQLPreparedStatement::MySQLPreparedStatement(MYSQL_STMT* stmt) :
m_stmt(NULL),
m_Mstmt(stmt),
m_bind(NULL)
m_stmt(NULL),
m_Mstmt(stmt),
m_bind(NULL)
{
/// Initialize variable parameters
m_paramCount = mysql_stmt_param_count(stmt);
@@ -221,7 +221,7 @@ MySQLPreparedStatement::~MySQLPreparedStatement()
void MySQLPreparedStatement::ClearParameters()
{
for (uint32 i=0; i < m_paramCount; ++i)
for (uint32 i = 0; i < m_paramCount; ++i)
{
delete m_bind[i].length;
m_bind[i].length = NULL;
@@ -339,12 +339,12 @@ void MySQLPreparedStatement::setString(const uint8 index, const char* value)
MYSQL_BIND* param = &m_bind[index];
size_t len = strlen(value) + 1;
param->buffer_type = MYSQL_TYPE_VAR_STRING;
delete [] static_cast<char *>(param->buffer);
delete [] static_cast<char*>(param->buffer);
param->buffer = new char[len];
param->buffer_length = len;
param->is_null_value = 0;
delete param->length;
param->length = new unsigned long(len-1);
param->length = new unsigned long(len - 1);
memcpy(param->buffer, value, len);
}
@@ -355,7 +355,7 @@ void MySQLPreparedStatement::setNull(const uint8 index)
m_paramsSet[index] = true;
MYSQL_BIND* param = &m_bind[index];
param->buffer_type = MYSQL_TYPE_NULL;
delete [] static_cast<char *>(param->buffer);
delete [] static_cast<char*>(param->buffer);
param->buffer = NULL;
param->buffer_length = 0;
param->is_null_value = 1;
@@ -366,7 +366,7 @@ void MySQLPreparedStatement::setNull(const uint8 index)
void MySQLPreparedStatement::setValue(MYSQL_BIND* param, enum_field_types type, const void* value, uint32 len, bool isUnsigned)
{
param->buffer_type = type;
delete [] static_cast<char *>(param->buffer);
delete [] static_cast<char*>(param->buffer);
param->buffer = new char[len];
param->buffer_length = 0;
param->is_null_value = 0;
@@ -439,15 +439,15 @@ std::string MySQLPreparedStatement::getQueryString(std::string const& sqlPattern
//- Execution
PreparedStatementTask::PreparedStatementTask(PreparedStatement* stmt) :
m_stmt(stmt),
m_has_result(false)
m_stmt(stmt),
m_has_result(false)
{
}
PreparedStatementTask::PreparedStatementTask(PreparedStatement* stmt, PreparedQueryResultFuture result) :
m_stmt(stmt),
m_has_result(true),
m_result(result)
m_stmt(stmt),
m_has_result(true),
m_result(result)
{
}

View File

@@ -65,31 +65,31 @@ class PreparedStatement
friend class MySQLPreparedStatement;
friend class MySQLConnection;
public:
explicit PreparedStatement(uint32 index);
~PreparedStatement();
public:
explicit PreparedStatement(uint32 index);
~PreparedStatement();
void setBool(const uint8 index, const bool value);
void setUInt8(const uint8 index, const uint8 value);
void setUInt16(const uint8 index, const uint16 value);
void setUInt32(const uint8 index, const uint32 value);
void setUInt64(const uint8 index, const uint64 value);
void setInt8(const uint8 index, const int8 value);
void setInt16(const uint8 index, const int16 value);
void setInt32(const uint8 index, const int32 value);
void setInt64(const uint8 index, const int64 value);
void setFloat(const uint8 index, const float value);
void setDouble(const uint8 index, const double value);
void setString(const uint8 index, const std::string& value);
void setNull(const uint8 index);
void setBool(const uint8 index, const bool value);
void setUInt8(const uint8 index, const uint8 value);
void setUInt16(const uint8 index, const uint16 value);
void setUInt32(const uint8 index, const uint32 value);
void setUInt64(const uint8 index, const uint64 value);
void setInt8(const uint8 index, const int8 value);
void setInt16(const uint8 index, const int16 value);
void setInt32(const uint8 index, const int32 value);
void setInt64(const uint8 index, const int64 value);
void setFloat(const uint8 index, const float value);
void setDouble(const uint8 index, const double value);
void setString(const uint8 index, const std::string& value);
void setNull(const uint8 index);
protected:
void BindParameters();
protected:
void BindParameters();
protected:
MySQLPreparedStatement* m_stmt;
uint32 m_index;
std::vector<PreparedStatementData> statement_data; //- Buffer of parameters, not tied to MySQL in any way yet
protected:
MySQLPreparedStatement* m_stmt;
uint32 m_index;
std::vector<PreparedStatementData> statement_data; //- Buffer of parameters, not tied to MySQL in any way yet
};
//- Class of which the instances are unique per MySQLConnection
@@ -100,40 +100,40 @@ class MySQLPreparedStatement
friend class MySQLConnection;
friend class PreparedStatement;
public:
MySQLPreparedStatement(MYSQL_STMT* stmt);
~MySQLPreparedStatement();
public:
MySQLPreparedStatement(MYSQL_STMT* stmt);
~MySQLPreparedStatement();
void setBool(const uint8 index, const bool value);
void setUInt8(const uint8 index, const uint8 value);
void setUInt16(const uint8 index, const uint16 value);
void setUInt32(const uint8 index, const uint32 value);
void setUInt64(const uint8 index, const uint64 value);
void setInt8(const uint8 index, const int8 value);
void setInt16(const uint8 index, const int16 value);
void setInt32(const uint8 index, const int32 value);
void setInt64(const uint8 index, const int64 value);
void setFloat(const uint8 index, const float value);
void setDouble(const uint8 index, const double value);
void setString(const uint8 index, const char* value);
void setNull(const uint8 index);
void setBool(const uint8 index, const bool value);
void setUInt8(const uint8 index, const uint8 value);
void setUInt16(const uint8 index, const uint16 value);
void setUInt32(const uint8 index, const uint32 value);
void setUInt64(const uint8 index, const uint64 value);
void setInt8(const uint8 index, const int8 value);
void setInt16(const uint8 index, const int16 value);
void setInt32(const uint8 index, const int32 value);
void setInt64(const uint8 index, const int64 value);
void setFloat(const uint8 index, const float value);
void setDouble(const uint8 index, const double value);
void setString(const uint8 index, const char* value);
void setNull(const uint8 index);
protected:
MYSQL_STMT* GetSTMT() { return m_Mstmt; }
MYSQL_BIND* GetBind() { return m_bind; }
PreparedStatement* m_stmt;
void ClearParameters();
bool CheckValidIndex(uint8 index);
std::string getQueryString(std::string const& sqlPattern) const;
protected:
MYSQL_STMT* GetSTMT() { return m_Mstmt; }
MYSQL_BIND* GetBind() { return m_bind; }
PreparedStatement* m_stmt;
void ClearParameters();
bool CheckValidIndex(uint8 index);
std::string getQueryString(std::string const& sqlPattern) const;
private:
void setValue(MYSQL_BIND* param, enum_field_types type, const void* value, uint32 len, bool isUnsigned);
private:
void setValue(MYSQL_BIND* param, enum_field_types type, const void* value, uint32 len, bool isUnsigned);
private:
MYSQL_STMT* m_Mstmt;
uint32 m_paramCount;
std::vector<bool> m_paramsSet;
MYSQL_BIND* m_bind;
private:
MYSQL_STMT* m_Mstmt;
uint32 m_paramCount;
std::vector<bool> m_paramsSet;
MYSQL_BIND* m_bind;
};
typedef ACE_Future<PreparedQueryResult> PreparedQueryResultFuture;
@@ -141,16 +141,16 @@ typedef ACE_Future<PreparedQueryResult> PreparedQueryResultFuture;
//- Lower-level class, enqueuable operation
class PreparedStatementTask : public SQLOperation
{
public:
PreparedStatementTask(PreparedStatement* stmt);
PreparedStatementTask(PreparedStatement* stmt, PreparedQueryResultFuture result);
~PreparedStatementTask();
public:
PreparedStatementTask(PreparedStatement* stmt);
PreparedStatementTask(PreparedStatement* stmt, PreparedQueryResultFuture result);
~PreparedStatementTask();
bool Execute();
bool Execute();
protected:
PreparedStatement* m_stmt;
bool m_has_result;
PreparedQueryResultFuture m_result;
protected:
PreparedStatement* m_stmt;
bool m_has_result;
PreparedQueryResultFuture m_result;
};
#endif

View File

@@ -9,7 +9,7 @@
#include "PreparedStatement.h"
#include "Log.h"
bool SQLQueryHolder::SetQuery(size_t index, const char *sql)
bool SQLQueryHolder::SetQuery(size_t index, const char* sql)
{
if (m_queries.size() <= index)
{
@@ -29,7 +29,7 @@ bool SQLQueryHolder::SetQuery(size_t index, const char *sql)
return true;
}
bool SQLQueryHolder::SetPQuery(size_t index, const char *format, ...)
bool SQLQueryHolder::SetPQuery(size_t index, const char* format, ...)
{
if (!format)
{
@@ -165,7 +165,7 @@ bool SQLQueryHolderTask::Execute()
return false;
/// we can do this, we are friends
std::vector<SQLQueryHolder::SQLResultPair> &queries = m_holder->m_queries;
std::vector<SQLQueryHolder::SQLResultPair>& queries = m_holder->m_queries;
for (size_t i = 0; i < queries.size(); i++)
{
@@ -175,19 +175,19 @@ bool SQLQueryHolderTask::Execute()
switch (data->type)
{
case SQL_ELEMENT_RAW:
{
char const* sql = data->element.query;
if (sql)
m_holder->SetResult(i, m_conn->Query(sql));
break;
}
{
char const* sql = data->element.query;
if (sql)
m_holder->SetResult(i, m_conn->Query(sql));
break;
}
case SQL_ELEMENT_PREPARED:
{
PreparedStatement* stmt = data->element.stmt;
if (stmt)
m_holder->SetPreparedResult(i, m_conn->Query(stmt));
break;
}
{
PreparedStatement* stmt = data->element.stmt;
if (stmt)
m_holder->SetPreparedResult(i, m_conn->Query(stmt));
break;
}
}
}
}

View File

@@ -12,34 +12,34 @@
class SQLQueryHolder
{
friend class SQLQueryHolderTask;
private:
typedef std::pair<SQLElementData, SQLResultSetUnion> SQLResultPair;
std::vector<SQLResultPair> m_queries;
public:
SQLQueryHolder() { }
~SQLQueryHolder();
bool SetQuery(size_t index, const char *sql);
bool SetPQuery(size_t index, const char *format, ...) ATTR_PRINTF(3, 4);
bool SetPreparedQuery(size_t index, PreparedStatement* stmt);
void SetSize(size_t size);
QueryResult GetResult(size_t index);
PreparedQueryResult GetPreparedResult(size_t index);
void SetResult(size_t index, ResultSet* result);
void SetPreparedResult(size_t index, PreparedResultSet* result);
private:
typedef std::pair<SQLElementData, SQLResultSetUnion> SQLResultPair;
std::vector<SQLResultPair> m_queries;
public:
SQLQueryHolder() { }
~SQLQueryHolder();
bool SetQuery(size_t index, const char* sql);
bool SetPQuery(size_t index, const char* format, ...) ATTR_PRINTF(3, 4);
bool SetPreparedQuery(size_t index, PreparedStatement* stmt);
void SetSize(size_t size);
QueryResult GetResult(size_t index);
PreparedQueryResult GetPreparedResult(size_t index);
void SetResult(size_t index, ResultSet* result);
void SetPreparedResult(size_t index, PreparedResultSet* result);
};
typedef ACE_Future<SQLQueryHolder*> QueryResultHolderFuture;
class SQLQueryHolderTask : public SQLOperation
{
private:
SQLQueryHolder * m_holder;
QueryResultHolderFuture m_result;
private:
SQLQueryHolder* m_holder;
QueryResultHolderFuture m_result;
public:
SQLQueryHolderTask(SQLQueryHolder *holder, QueryResultHolderFuture res)
: m_holder(holder), m_result(res){ };
bool Execute();
public:
SQLQueryHolderTask(SQLQueryHolder* holder, QueryResultHolderFuture res)
: m_holder(holder), m_result(res) { };
bool Execute();
};

View File

@@ -7,25 +7,25 @@
#include "DatabaseEnv.h"
#include "Log.h"
ResultSet::ResultSet(MYSQL_RES *result, MYSQL_FIELD *fields, uint64 rowCount, uint32 fieldCount) :
_rowCount(rowCount),
_fieldCount(fieldCount),
_result(result),
_fields(fields)
ResultSet::ResultSet(MYSQL_RES* result, MYSQL_FIELD* fields, uint64 rowCount, uint32 fieldCount) :
_rowCount(rowCount),
_fieldCount(fieldCount),
_result(result),
_fields(fields)
{
_currentRow = new Field[_fieldCount];
ASSERT(_currentRow);
}
PreparedResultSet::PreparedResultSet(MYSQL_STMT* stmt, MYSQL_RES *result, uint64 rowCount, uint32 fieldCount) :
m_rowCount(rowCount),
m_rowPosition(0),
m_fieldCount(fieldCount),
m_rBind(NULL),
m_stmt(stmt),
m_res(result),
m_isNull(NULL),
m_length(NULL)
PreparedResultSet::PreparedResultSet(MYSQL_STMT* stmt, MYSQL_RES* result, uint64 rowCount, uint32 fieldCount) :
m_rowCount(rowCount),
m_rowPosition(0),
m_fieldCount(fieldCount),
m_rBind(NULL),
m_stmt(stmt),
m_res(result),
m_isNull(NULL),
m_length(NULL)
{
if (!m_res)
return;
@@ -94,9 +94,9 @@ m_length(NULL)
{
if (!*m_rBind[fIndex].is_null)
m_rows[uint32(m_rowPosition)][fIndex].SetByteValue( m_rBind[fIndex].buffer,
m_rBind[fIndex].buffer_length,
m_rBind[fIndex].buffer_type,
*m_rBind[fIndex].length );
m_rBind[fIndex].buffer_length,
m_rBind[fIndex].buffer_type,
*m_rBind[fIndex].length );
else
switch (m_rBind[fIndex].buffer_type)
{
@@ -106,16 +106,16 @@ m_length(NULL)
case MYSQL_TYPE_BLOB:
case MYSQL_TYPE_STRING:
case MYSQL_TYPE_VAR_STRING:
m_rows[uint32(m_rowPosition)][fIndex].SetByteValue( "",
m_rBind[fIndex].buffer_length,
m_rBind[fIndex].buffer_type,
*m_rBind[fIndex].length );
break;
m_rows[uint32(m_rowPosition)][fIndex].SetByteValue( "",
m_rBind[fIndex].buffer_length,
m_rBind[fIndex].buffer_type,
*m_rBind[fIndex].length );
break;
default:
m_rows[uint32(m_rowPosition)][fIndex].SetByteValue( 0,
m_rBind[fIndex].buffer_length,
m_rBind[fIndex].buffer_type,
*m_rBind[fIndex].length );
m_rows[uint32(m_rowPosition)][fIndex].SetByteValue( 0,
m_rBind[fIndex].buffer_length,
m_rBind[fIndex].buffer_type,
*m_rBind[fIndex].length );
}
}
m_rowPosition++;

View File

@@ -14,7 +14,7 @@
#include "Field.h"
#ifdef _WIN32
#include <winsock2.h>
#include <winsock2.h>
#endif
#include <mysql.h>
@@ -24,76 +24,76 @@ typedef bool my_bool;
class ResultSet
{
public:
ResultSet(MYSQL_RES* result, MYSQL_FIELD* fields, uint64 rowCount, uint32 fieldCount);
~ResultSet();
public:
ResultSet(MYSQL_RES* result, MYSQL_FIELD* fields, uint64 rowCount, uint32 fieldCount);
~ResultSet();
bool NextRow();
uint64 GetRowCount() const { return _rowCount; }
uint32 GetFieldCount() const { return _fieldCount; }
bool NextRow();
uint64 GetRowCount() const { return _rowCount; }
uint32 GetFieldCount() const { return _fieldCount; }
#ifdef ELUNA
std::string GetFieldName(uint32 index) const;
std::string GetFieldName(uint32 index) const;
#endif
Field* Fetch() const { return _currentRow; }
const Field & operator [] (uint32 index) const
{
ASSERT(index < _fieldCount);
return _currentRow[index];
}
Field* Fetch() const { return _currentRow; }
const Field& operator [] (uint32 index) const
{
ASSERT(index < _fieldCount);
return _currentRow[index];
}
protected:
uint64 _rowCount;
Field* _currentRow;
uint32 _fieldCount;
protected:
uint64 _rowCount;
Field* _currentRow;
uint32 _fieldCount;
private:
void CleanUp();
MYSQL_RES* _result;
MYSQL_FIELD* _fields;
private:
void CleanUp();
MYSQL_RES* _result;
MYSQL_FIELD* _fields;
};
typedef acore::AutoPtr<ResultSet, ACE_Thread_Mutex> QueryResult;
class PreparedResultSet
{
public:
PreparedResultSet(MYSQL_STMT* stmt, MYSQL_RES* result, uint64 rowCount, uint32 fieldCount);
~PreparedResultSet();
public:
PreparedResultSet(MYSQL_STMT* stmt, MYSQL_RES* result, uint64 rowCount, uint32 fieldCount);
~PreparedResultSet();
bool NextRow();
uint64 GetRowCount() const { return m_rowCount; }
uint32 GetFieldCount() const { return m_fieldCount; }
bool NextRow();
uint64 GetRowCount() const { return m_rowCount; }
uint32 GetFieldCount() const { return m_fieldCount; }
Field* Fetch() const
{
ASSERT(m_rowPosition < m_rowCount);
return m_rows[uint32(m_rowPosition)];
}
Field* Fetch() const
{
ASSERT(m_rowPosition < m_rowCount);
return m_rows[uint32(m_rowPosition)];
}
const Field & operator [] (uint32 index) const
{
ASSERT(m_rowPosition < m_rowCount);
ASSERT(index < m_fieldCount);
return m_rows[uint32(m_rowPosition)][index];
}
const Field& operator [] (uint32 index) const
{
ASSERT(m_rowPosition < m_rowCount);
ASSERT(index < m_fieldCount);
return m_rows[uint32(m_rowPosition)][index];
}
protected:
std::vector<Field*> m_rows;
uint64 m_rowCount;
uint64 m_rowPosition;
uint32 m_fieldCount;
protected:
std::vector<Field*> m_rows;
uint64 m_rowCount;
uint64 m_rowPosition;
uint32 m_fieldCount;
private:
MYSQL_BIND* m_rBind;
MYSQL_STMT* m_stmt;
MYSQL_RES* m_res;
private:
MYSQL_BIND* m_rBind;
MYSQL_STMT* m_stmt;
MYSQL_RES* m_res;
my_bool* m_isNull;
unsigned long* m_length;
my_bool* m_isNull;
unsigned long* m_length;
void FreeBindBuffer();
void CleanUp();
bool _NextRow();
void FreeBindBuffer();
void CleanUp();
bool _NextRow();
};

View File

@@ -47,17 +47,17 @@ class MySQLConnection;
class SQLOperation : public ACE_Method_Request
{
public:
SQLOperation(): m_conn(NULL) { }
virtual int call()
{
Execute();
return 0;
}
virtual bool Execute() = 0;
virtual void SetConnection(MySQLConnection* con) { m_conn = con; }
public:
SQLOperation(): m_conn(NULL) { }
virtual int call()
{
Execute();
return 0;
}
virtual bool Execute() = 0;
virtual void SetConnection(MySQLConnection* con) { m_conn = con; }
MySQLConnection* m_conn;
MySQLConnection* m_conn;
};
#endif

View File

@@ -44,15 +44,15 @@ void Transaction::Cleanup()
while (!m_queries.empty())
{
SQLElementData const &data = m_queries.front();
SQLElementData const& data = m_queries.front();
switch (data.type)
{
case SQL_ELEMENT_PREPARED:
delete data.element.stmt;
break;
break;
case SQL_ELEMENT_RAW:
free((void*)(data.element.query));
break;
break;
}
m_queries.pop_front();

View File

@@ -21,22 +21,22 @@ class Transaction
template <typename T>
friend class DatabaseWorkerPool;
public:
Transaction() : _cleanedUp(false) { }
~Transaction() { Cleanup(); }
public:
Transaction() : _cleanedUp(false) { }
~Transaction() { Cleanup(); }
void Append(PreparedStatement* statement);
void Append(const char* sql);
void PAppend(const char* sql, ...);
void Append(PreparedStatement* statement);
void Append(const char* sql);
void PAppend(const char* sql, ...);
size_t GetSize() const { return m_queries.size(); }
size_t GetSize() const { return m_queries.size(); }
protected:
void Cleanup();
std::list<SQLElementData> m_queries;
protected:
void Cleanup();
std::list<SQLElementData> m_queries;
private:
bool _cleanedUp;
private:
bool _cleanedUp;
};
typedef acore::AutoPtr<Transaction, ACE_Thread_Mutex> SQLTransaction;
@@ -47,14 +47,14 @@ class TransactionTask : public SQLOperation
template <class T> friend class DatabaseWorkerPool;
friend class DatabaseWorker;
public:
TransactionTask(SQLTransaction trans) : m_trans(trans) { } ;
~TransactionTask(){ };
public:
TransactionTask(SQLTransaction trans) : m_trans(trans) { } ;
~TransactionTask() { };
protected:
bool Execute();
protected:
bool Execute();
SQLTransaction m_trans;
SQLTransaction m_trans;
};
#endif

View File

@@ -57,73 +57,73 @@ namespace
namespace acore
{
void Assert(char const* file, int line, char const* function, std::string const& debugInfo, char const* message)
{
std::string formattedMessage = acore::StringFormat("\n%s:%i in %s ASSERTION FAILED:\n %s\n", file, line, function, message) + debugInfo + '\n';
fprintf(stderr, "%s", formattedMessage.c_str());
fflush(stderr);
Crash(formattedMessage.c_str());
}
void Assert(char const* file, int line, char const* function, std::string const& debugInfo, char const* message)
{
std::string formattedMessage = acore::StringFormat("\n%s:%i in %s ASSERTION FAILED:\n %s\n", file, line, function, message) + debugInfo + '\n';
fprintf(stderr, "%s", formattedMessage.c_str());
fflush(stderr);
Crash(formattedMessage.c_str());
}
void Assert(char const* file, int line, char const* function, std::string const& debugInfo, char const* message, char const* format, ...)
{
va_list args;
va_start(args, format);
void Assert(char const* file, int line, char const* function, std::string const& debugInfo, char const* message, char const* format, ...)
{
va_list args;
va_start(args, format);
std::string formattedMessage = acore::StringFormat("\n%s:%i in %s ASSERTION FAILED:\n %s\n", file, line, function, message) + FormatAssertionMessage(format, args) + '\n' + debugInfo + '\n';
va_end(args);
std::string formattedMessage = acore::StringFormat("\n%s:%i in %s ASSERTION FAILED:\n %s\n", file, line, function, message) + FormatAssertionMessage(format, args) + '\n' + debugInfo + '\n';
va_end(args);
fprintf(stderr, "%s", formattedMessage.c_str());
fflush(stderr);
fprintf(stderr, "%s", formattedMessage.c_str());
fflush(stderr);
Crash(formattedMessage.c_str());
}
Crash(formattedMessage.c_str());
}
void Fatal(char const* file, int line, char const* function, char const* message, ...)
{
va_list args;
va_start(args, message);
void Fatal(char const* file, int line, char const* function, char const* message, ...)
{
va_list args;
va_start(args, message);
std::string formattedMessage = acore::StringFormat("\n%s:%i in %s FATAL ERROR:\n", file, line, function) + FormatAssertionMessage(message, args) + '\n';
va_end(args);
std::string formattedMessage = acore::StringFormat("\n%s:%i in %s FATAL ERROR:\n", file, line, function) + FormatAssertionMessage(message, args) + '\n';
va_end(args);
fprintf(stderr, "%s", formattedMessage.c_str());
fflush(stderr);
fprintf(stderr, "%s", formattedMessage.c_str());
fflush(stderr);
std::this_thread::sleep_for(std::chrono::seconds(10));
Crash(formattedMessage.c_str());
}
std::this_thread::sleep_for(std::chrono::seconds(10));
Crash(formattedMessage.c_str());
}
void Error(char const* file, int line, char const* function, char const* message)
{
std::string formattedMessage = acore::StringFormat("\n%s:%i in %s ERROR:\n %s\n", file, line, function, message);
fprintf(stderr, "%s", formattedMessage.c_str());
fflush(stderr);
Crash(formattedMessage.c_str());
}
void Error(char const* file, int line, char const* function, char const* message)
{
std::string formattedMessage = acore::StringFormat("\n%s:%i in %s ERROR:\n %s\n", file, line, function, message);
fprintf(stderr, "%s", formattedMessage.c_str());
fflush(stderr);
Crash(formattedMessage.c_str());
}
void Warning(char const* file, int line, char const* function, char const* message)
{
fprintf(stderr, "\n%s:%i in %s WARNING:\n %s\n",
file, line, function, message);
}
void Warning(char const* file, int line, char const* function, char const* message)
{
fprintf(stderr, "\n%s:%i in %s WARNING:\n %s\n",
file, line, function, message);
}
void Abort(char const* file, int line, char const* function)
{
std::string formattedMessage = acore::StringFormat("\n%s:%i in %s ABORTED.\n", file, line, function);
fprintf(stderr, "%s", formattedMessage.c_str());
fflush(stderr);
Crash(formattedMessage.c_str());
}
void Abort(char const* file, int line, char const* function)
{
std::string formattedMessage = acore::StringFormat("\n%s:%i in %s ABORTED.\n", file, line, function);
fprintf(stderr, "%s", formattedMessage.c_str());
fflush(stderr);
Crash(formattedMessage.c_str());
}
void AbortHandler(int sigval)
{
// nothing useful to log here, no way to pass args
std::string formattedMessage = acore::StringFormat("Caught signal %i\n", sigval);
fprintf(stderr, "%s", formattedMessage.c_str());
fflush(stderr);
Crash(formattedMessage.c_str());
}
void AbortHandler(int sigval)
{
// nothing useful to log here, no way to pass args
std::string formattedMessage = acore::StringFormat("Caught signal %i\n", sigval);
fprintf(stderr, "%s", formattedMessage.c_str());
fflush(stderr);
Crash(formattedMessage.c_str());
}
} // namespace acore

View File

@@ -33,13 +33,13 @@ inline LPTSTR ErrorMessage(DWORD dw)
{
LPVOID lpMsgBuf;
DWORD formatResult = FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM,
NULL,
dw,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR) &lpMsgBuf,
0, NULL);
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM,
NULL,
dw,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR) &lpMsgBuf,
0, NULL);
if (formatResult != 0)
return (LPTSTR)lpMsgBuf;
else
@@ -110,7 +110,7 @@ WheatyExceptionReport::~WheatyExceptionReport()
// Entry point where control comes on an unhandled exception
//===========================================================
LONG WINAPI WheatyExceptionReport::WheatyUnhandledExceptionFilter(
PEXCEPTION_POINTERS pExceptionInfo)
PEXCEPTION_POINTERS pExceptionInfo)
{
std::unique_lock<std::mutex> guard(alreadyCrashedLock);
// Handle only 1 exception in the whole process lifetime
@@ -141,26 +141,26 @@ PEXCEPTION_POINTERS pExceptionInfo)
SYSTEMTIME systime;
GetLocalTime(&systime);
sprintf(m_szDumpFileName, "%s\\%s_%s_[%u-%u_%u-%u-%u].dmp",
crash_folder_path, GitRevision::GetHash(), pos, systime.wDay, systime.wMonth, systime.wHour, systime.wMinute, systime.wSecond);
crash_folder_path, GitRevision::GetHash(), pos, systime.wDay, systime.wMonth, systime.wHour, systime.wMinute, systime.wSecond);
sprintf(m_szLogFileName, "%s\\%s_%s_[%u-%u_%u-%u-%u].txt",
crash_folder_path, GitRevision::GetHash(), pos, systime.wDay, systime.wMonth, systime.wHour, systime.wMinute, systime.wSecond);
crash_folder_path, GitRevision::GetHash(), pos, systime.wDay, systime.wMonth, systime.wHour, systime.wMinute, systime.wSecond);
m_hDumpFile = CreateFile(m_szDumpFileName,
GENERIC_WRITE,
0,
0,
OPEN_ALWAYS,
FILE_FLAG_WRITE_THROUGH,
0);
GENERIC_WRITE,
0,
0,
OPEN_ALWAYS,
FILE_FLAG_WRITE_THROUGH,
0);
m_hReportFile = CreateFile(m_szLogFileName,
GENERIC_WRITE,
0,
0,
OPEN_ALWAYS,
FILE_FLAG_WRITE_THROUGH,
0);
GENERIC_WRITE,
0,
0,
OPEN_ALWAYS,
FILE_FLAG_WRITE_THROUGH,
0);
if (m_hDumpFile)
{
@@ -183,7 +183,7 @@ PEXCEPTION_POINTERS pExceptionInfo)
}
MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(),
m_hDumpFile, MiniDumpWithIndirectlyReferencedMemory, &info, &additionalStreamInfo, 0);
m_hDumpFile, MiniDumpWithIndirectlyReferencedMemory, &info, &additionalStreamInfo, 0);
CloseHandle(m_hDumpFile);
}
@@ -217,13 +217,13 @@ BOOL WheatyExceptionReport::_GetProcessorName(TCHAR* sProcessorName, DWORD maxco
HKEY hKey;
LONG lRet;
lRet = ::RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0"),
0, KEY_QUERY_VALUE, &hKey);
0, KEY_QUERY_VALUE, &hKey);
if (lRet != ERROR_SUCCESS)
return FALSE;
TCHAR szTmp[2048];
DWORD cntBytes = sizeof(szTmp);
lRet = ::RegQueryValueEx(hKey, _T("ProcessorNameString"), NULL, NULL,
(LPBYTE)szTmp, &cntBytes);
(LPBYTE)szTmp, &cntBytes);
if (lRet != ERROR_SUCCESS)
return FALSE;
::RegCloseKey(hKey);
@@ -271,150 +271,150 @@ BOOL WheatyExceptionReport::_GetWindowsVersion(TCHAR* szVersion, DWORD cntMax)
{
// Windows NT product family.
case VER_PLATFORM_WIN32_NT:
{
#if WINVER < 0x0500
BYTE suiteMask = osvi.wReserved[0];
BYTE productType = osvi.wReserved[1];
#else
WORD suiteMask = osvi.wSuiteMask;
BYTE productType = osvi.wProductType;
#endif // WINVER < 0x0500
{
#if WINVER < 0x0500
BYTE suiteMask = osvi.wReserved[0];
BYTE productType = osvi.wReserved[1];
#else
WORD suiteMask = osvi.wSuiteMask;
BYTE productType = osvi.wProductType;
#endif // WINVER < 0x0500
// Test for the specific product family.
if (osvi.dwMajorVersion == 10)
{
if (productType == VER_NT_WORKSTATION)
_tcsncat(szVersion, _T("Windows 10 "), cntMax);
else
_tcsncat(szVersion, _T("Windows Server 2016 "), cntMax);
}
else if (osvi.dwMajorVersion == 6)
{
if (productType == VER_NT_WORKSTATION)
// Test for the specific product family.
if (osvi.dwMajorVersion == 10)
{
if (osvi.dwMinorVersion == 3)
_tcsncat(szVersion, _T("Windows 8.1 "), cntMax);
if (productType == VER_NT_WORKSTATION)
_tcsncat(szVersion, _T("Windows 10 "), cntMax);
else
_tcsncat(szVersion, _T("Windows Server 2016 "), cntMax);
}
else if (osvi.dwMajorVersion == 6)
{
if (productType == VER_NT_WORKSTATION)
{
if (osvi.dwMinorVersion == 3)
_tcsncat(szVersion, _T("Windows 8.1 "), cntMax);
else if (osvi.dwMinorVersion == 2)
_tcsncat(szVersion, _T("Windows 8 "), cntMax);
else if (osvi.dwMinorVersion == 1)
_tcsncat(szVersion, _T("Windows 7 "), cntMax);
else
_tcsncat(szVersion, _T("Windows Vista "), cntMax);
}
else if (osvi.dwMinorVersion == 3)
_tcsncat(szVersion, _T("Windows Server 2012 R2 "), cntMax);
else if (osvi.dwMinorVersion == 2)
_tcsncat(szVersion, _T("Windows 8 "), cntMax);
_tcsncat(szVersion, _T("Windows Server 2012 "), cntMax);
else if (osvi.dwMinorVersion == 1)
_tcsncat(szVersion, _T("Windows 7 "), cntMax);
_tcsncat(szVersion, _T("Windows Server 2008 R2 "), cntMax);
else
_tcsncat(szVersion, _T("Windows Vista "), cntMax);
_tcsncat(szVersion, _T("Windows Server 2008 "), cntMax);
}
else if (osvi.dwMinorVersion == 3)
_tcsncat(szVersion, _T("Windows Server 2012 R2 "), cntMax);
else if (osvi.dwMinorVersion == 2)
_tcsncat(szVersion, _T("Windows Server 2012 "), cntMax);
else if (osvi.dwMinorVersion == 1)
_tcsncat(szVersion, _T("Windows Server 2008 R2 "), cntMax);
else
_tcsncat(szVersion, _T("Windows Server 2008 "), cntMax);
}
else if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 2)
_tcsncat(szVersion, _T("Microsoft Windows Server 2003 "), cntMax);
else if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 1)
_tcsncat(szVersion, _T("Microsoft Windows XP "), cntMax);
else if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 0)
_tcsncat(szVersion, _T("Microsoft Windows 2000 "), cntMax);
else if (osvi.dwMajorVersion <= 4)
_tcsncat(szVersion, _T("Microsoft Windows NT "), cntMax);
else if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 2)
_tcsncat(szVersion, _T("Microsoft Windows Server 2003 "), cntMax);
else if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 1)
_tcsncat(szVersion, _T("Microsoft Windows XP "), cntMax);
else if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 0)
_tcsncat(szVersion, _T("Microsoft Windows 2000 "), cntMax);
else if (osvi.dwMajorVersion <= 4)
_tcsncat(szVersion, _T("Microsoft Windows NT "), cntMax);
// Test for specific product on Windows NT 4.0 SP6 and later.
if (bVersionEx >= 0)
{
// Test for the workstation type.
if (productType == VER_NT_WORKSTATION)
// Test for specific product on Windows NT 4.0 SP6 and later.
if (bVersionEx >= 0)
{
if (osvi.dwMajorVersion == 4)
_tcsncat(szVersion, _T("Workstation 4.0 "), cntMax);
else if (suiteMask & VER_SUITE_PERSONAL)
_tcsncat(szVersion, _T("Home Edition "), cntMax);
else if (suiteMask & VER_SUITE_EMBEDDEDNT)
_tcsncat(szVersion, _T("Embedded "), cntMax);
// Test for the workstation type.
if (productType == VER_NT_WORKSTATION)
{
if (osvi.dwMajorVersion == 4)
_tcsncat(szVersion, _T("Workstation 4.0 "), cntMax);
else if (suiteMask & VER_SUITE_PERSONAL)
_tcsncat(szVersion, _T("Home Edition "), cntMax);
else if (suiteMask & VER_SUITE_EMBEDDEDNT)
_tcsncat(szVersion, _T("Embedded "), cntMax);
else
_tcsncat(szVersion, _T("Professional "), cntMax);
}
// Test for the server type.
else if (productType == VER_NT_SERVER)
{
if (osvi.dwMajorVersion == 6 || osvi.dwMajorVersion == 10)
{
if (suiteMask & VER_SUITE_SMALLBUSINESS_RESTRICTED)
_tcsncat(szVersion, _T("Essentials "), cntMax);
else if (suiteMask & VER_SUITE_DATACENTER)
_tcsncat(szVersion, _T("Datacenter "), cntMax);
else if (suiteMask & VER_SUITE_ENTERPRISE)
_tcsncat(szVersion, _T("Enterprise "), cntMax);
else
_tcsncat(szVersion, _T("Standard "), cntMax);
}
else if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 2)
{
if (suiteMask & VER_SUITE_DATACENTER)
_tcsncat(szVersion, _T("Datacenter Edition "), cntMax);
else if (suiteMask & VER_SUITE_ENTERPRISE)
_tcsncat(szVersion, _T("Enterprise Edition "), cntMax);
else if (suiteMask == VER_SUITE_BLADE)
_tcsncat(szVersion, _T("Web Edition "), cntMax);
else
_tcsncat(szVersion, _T("Standard Edition "), cntMax);
}
else if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 0)
{
if (suiteMask & VER_SUITE_DATACENTER)
_tcsncat(szVersion, _T("Datacenter Server "), cntMax);
else if (suiteMask & VER_SUITE_ENTERPRISE)
_tcsncat(szVersion, _T("Advanced Server "), cntMax);
else
_tcsncat(szVersion, _T("Server "), cntMax);
}
else // Windows NT 4.0
{
if (suiteMask & VER_SUITE_ENTERPRISE)
_tcsncat(szVersion, _T("Server 4.0, Enterprise Edition "), cntMax);
else
_tcsncat(szVersion, _T("Server 4.0 "), cntMax);
}
}
}
// Display service pack (if any) and build number.
if (osvi.dwMajorVersion == 4 && _tcsicmp(szCSDVersion, _T("Service Pack 6")) == 0)
{
HKEY hKey;
LONG lRet;
// Test for SP6 versus SP6a.
lRet = ::RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Hotfix\\Q246009"), 0, KEY_QUERY_VALUE, &hKey);
if (lRet == ERROR_SUCCESS)
{
_stprintf(wszTmp, _T("Service Pack 6a (Version %d.%d, Build %d)"),
osvi.dwMajorVersion, osvi.dwMinorVersion, osvi.dwBuildNumber & 0xFFFF);
_tcsncat(szVersion, wszTmp, cntMax);
}
else // Windows NT 4.0 prior to SP6a
{
_stprintf(wszTmp, _T("%s (Version %d.%d, Build %d)"),
szCSDVersion, osvi.dwMajorVersion, osvi.dwMinorVersion, osvi.dwBuildNumber & 0xFFFF);
_tcsncat(szVersion, wszTmp, cntMax);
}
::RegCloseKey(hKey);
}
else // Windows NT 3.51 and earlier or Windows 2000 and later
{
if (!_tcslen(szCSDVersion))
_stprintf(wszTmp, _T("(Version %d.%d, Build %d)"),
osvi.dwMajorVersion, osvi.dwMinorVersion, osvi.dwBuildNumber & 0xFFFF);
else
_tcsncat(szVersion, _T("Professional "), cntMax);
}
// Test for the server type.
else if (productType == VER_NT_SERVER)
{
if (osvi.dwMajorVersion == 6 || osvi.dwMajorVersion == 10)
{
if (suiteMask & VER_SUITE_SMALLBUSINESS_RESTRICTED)
_tcsncat(szVersion, _T("Essentials "), cntMax);
else if (suiteMask & VER_SUITE_DATACENTER)
_tcsncat(szVersion, _T("Datacenter "), cntMax);
else if (suiteMask & VER_SUITE_ENTERPRISE)
_tcsncat(szVersion, _T("Enterprise "), cntMax);
else
_tcsncat(szVersion, _T("Standard "), cntMax);
}
else if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 2)
{
if (suiteMask & VER_SUITE_DATACENTER)
_tcsncat(szVersion, _T("Datacenter Edition "), cntMax);
else if (suiteMask & VER_SUITE_ENTERPRISE)
_tcsncat(szVersion, _T("Enterprise Edition "), cntMax);
else if (suiteMask == VER_SUITE_BLADE)
_tcsncat(szVersion, _T("Web Edition "), cntMax);
else
_tcsncat(szVersion, _T("Standard Edition "), cntMax);
}
else if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 0)
{
if (suiteMask & VER_SUITE_DATACENTER)
_tcsncat(szVersion, _T("Datacenter Server "), cntMax);
else if (suiteMask & VER_SUITE_ENTERPRISE)
_tcsncat(szVersion, _T("Advanced Server "), cntMax);
else
_tcsncat(szVersion, _T("Server "), cntMax);
}
else // Windows NT 4.0
{
if (suiteMask & VER_SUITE_ENTERPRISE)
_tcsncat(szVersion, _T("Server 4.0, Enterprise Edition "), cntMax);
else
_tcsncat(szVersion, _T("Server 4.0 "), cntMax);
}
}
}
// Display service pack (if any) and build number.
if (osvi.dwMajorVersion == 4 && _tcsicmp(szCSDVersion, _T("Service Pack 6")) == 0)
{
HKEY hKey;
LONG lRet;
// Test for SP6 versus SP6a.
lRet = ::RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Hotfix\\Q246009"), 0, KEY_QUERY_VALUE, &hKey);
if (lRet == ERROR_SUCCESS)
{
_stprintf(wszTmp, _T("Service Pack 6a (Version %d.%d, Build %d)"),
osvi.dwMajorVersion, osvi.dwMinorVersion, osvi.dwBuildNumber & 0xFFFF);
_stprintf(wszTmp, _T("%s (Version %d.%d, Build %d)"),
szCSDVersion, osvi.dwMajorVersion, osvi.dwMinorVersion, osvi.dwBuildNumber & 0xFFFF);
_tcsncat(szVersion, wszTmp, cntMax);
}
else // Windows NT 4.0 prior to SP6a
{
_stprintf(wszTmp, _T("%s (Version %d.%d, Build %d)"),
szCSDVersion, osvi.dwMajorVersion, osvi.dwMinorVersion, osvi.dwBuildNumber & 0xFFFF);
_tcsncat(szVersion, wszTmp, cntMax);
}
::RegCloseKey(hKey);
break;
}
else // Windows NT 3.51 and earlier or Windows 2000 and later
{
if (!_tcslen(szCSDVersion))
_stprintf(wszTmp, _T("(Version %d.%d, Build %d)"),
osvi.dwMajorVersion, osvi.dwMinorVersion, osvi.dwBuildNumber & 0xFFFF);
else
_stprintf(wszTmp, _T("%s (Version %d.%d, Build %d)"),
szCSDVersion, osvi.dwMajorVersion, osvi.dwMinorVersion, osvi.dwBuildNumber & 0xFFFF);
_tcsncat(szVersion, wszTmp, cntMax);
}
break;
}
default:
_stprintf(wszTmp, _T("%s (Version %d.%d, Build %d)"),
szCSDVersion, osvi.dwMajorVersion, osvi.dwMinorVersion, osvi.dwBuildNumber & 0xFFFF);
szCSDVersion, osvi.dwMajorVersion, osvi.dwMinorVersion, osvi.dwBuildNumber & 0xFFFF);
_tcsncat(szVersion, wszTmp, cntMax);
break;
}
@@ -434,10 +434,10 @@ void WheatyExceptionReport::PrintSystemInfo()
Log(_T("//=====================================================\r\n"));
if (_GetProcessorName(sString, countof(sString)))
Log(_T("*** Hardware ***\r\nProcessor: %s\r\nNumber Of Processors: %d\r\nPhysical Memory: %d KB (Available: %d KB)\r\nCommit Charge Limit: %d KB\r\n"),
sString, SystemInfo.dwNumberOfProcessors, MemoryStatus.dwTotalPhys/0x400, MemoryStatus.dwAvailPhys/0x400, MemoryStatus.dwTotalPageFile/0x400);
sString, SystemInfo.dwNumberOfProcessors, MemoryStatus.dwTotalPhys / 0x400, MemoryStatus.dwAvailPhys / 0x400, MemoryStatus.dwTotalPageFile / 0x400);
else
Log(_T("*** Hardware ***\r\nProcessor: <unknown>\r\nNumber Of Processors: %d\r\nPhysical Memory: %d KB (Available: %d KB)\r\nCommit Charge Limit: %d KB\r\n"),
SystemInfo.dwNumberOfProcessors, MemoryStatus.dwTotalPhys/0x400, MemoryStatus.dwAvailPhys/0x400, MemoryStatus.dwTotalPageFile/0x400);
SystemInfo.dwNumberOfProcessors, MemoryStatus.dwTotalPhys / 0x400, MemoryStatus.dwAvailPhys / 0x400, MemoryStatus.dwTotalPageFile / 0x400);
if (_GetWindowsVersion(sString, countof(sString)))
Log(_T("\r\n*** Operation System ***\r\n%s\r\n"), sString);
@@ -448,48 +448,48 @@ void WheatyExceptionReport::PrintSystemInfo()
//===========================================================================
void WheatyExceptionReport::printTracesForAllThreads(bool bWriteVariables)
{
THREADENTRY32 te32;
THREADENTRY32 te32;
DWORD dwOwnerPID = GetCurrentProcessId();
m_hProcess = GetCurrentProcess();
// Take a snapshot of all running threads
HANDLE hThreadSnap = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
if (hThreadSnap == INVALID_HANDLE_VALUE)
return;
DWORD dwOwnerPID = GetCurrentProcessId();
m_hProcess = GetCurrentProcess();
// Take a snapshot of all running threads
HANDLE hThreadSnap = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
if (hThreadSnap == INVALID_HANDLE_VALUE)
return;
// Fill in the size of the structure before using it.
te32.dwSize = sizeof(THREADENTRY32);
// Fill in the size of the structure before using it.
te32.dwSize = sizeof(THREADENTRY32);
// Retrieve information about the first thread,
// and exit if unsuccessful
if (!Thread32First(hThreadSnap, &te32))
{
CloseHandle(hThreadSnap); // Must clean up the
// snapshot object!
return;
}
// Now walk the thread list of the system,
// and display information about each thread
// associated with the specified process
do
{
if (te32.th32OwnerProcessID == dwOwnerPID)
// Retrieve information about the first thread,
// and exit if unsuccessful
if (!Thread32First(hThreadSnap, &te32))
{
CONTEXT context;
context.ContextFlags = 0xffffffff;
HANDLE threadHandle = OpenThread(THREAD_GET_CONTEXT | THREAD_QUERY_INFORMATION, false, te32.th32ThreadID);
if (threadHandle)
{
if (GetThreadContext(threadHandle, &context))
WriteStackDetails(&context, bWriteVariables, threadHandle);
CloseHandle(threadHandle);
}
CloseHandle(hThreadSnap); // Must clean up the
// snapshot object!
return;
}
} while (Thread32Next(hThreadSnap, &te32));
// Don't forget to clean up the snapshot object.
CloseHandle(hThreadSnap);
// Now walk the thread list of the system,
// and display information about each thread
// associated with the specified process
do
{
if (te32.th32OwnerProcessID == dwOwnerPID)
{
CONTEXT context;
context.ContextFlags = 0xffffffff;
HANDLE threadHandle = OpenThread(THREAD_GET_CONTEXT | THREAD_QUERY_INFORMATION, false, te32.th32ThreadID);
if (threadHandle)
{
if (GetThreadContext(threadHandle, &context))
WriteStackDetails(&context, bWriteVariables, threadHandle);
CloseHandle(threadHandle);
}
}
} while (Thread32Next(hThreadSnap, &te32));
// Don't forget to clean up the snapshot object.
CloseHandle(hThreadSnap);
}
//===========================================================================
@@ -497,7 +497,7 @@ void WheatyExceptionReport::printTracesForAllThreads(bool bWriteVariables)
// WheatyUnhandledExceptionFilter
//===========================================================================
void WheatyExceptionReport::GenerateExceptionReport(
PEXCEPTION_POINTERS pExceptionInfo)
PEXCEPTION_POINTERS pExceptionInfo)
{
__try
{
@@ -526,9 +526,9 @@ PEXCEPTION_POINTERS pExceptionInfo)
DWORD section;
DWORD_PTR offset;
GetLogicalAddress(pExceptionRecord->ExceptionAddress,
szFaultingModule,
sizeof(szFaultingModule),
section, offset);
szFaultingModule,
sizeof(szFaultingModule),
section, offset);
#ifdef _M_IX86
Log(_T("Fault address: %08X %02X:%08X %s\r\n"),
@@ -612,11 +612,11 @@ PEXCEPTION_POINTERS pExceptionInfo)
//======================================================================
LPTSTR WheatyExceptionReport::GetExceptionString(DWORD dwCode)
{
#define EXCEPTION(x) case EXCEPTION_##x: return _T(#x);
#define EXCEPTION(x) case EXCEPTION_##x: return _T(#x);
switch (dwCode)
{
EXCEPTION(ACCESS_VIOLATION)
EXCEPTION(ACCESS_VIOLATION)
EXCEPTION(DATATYPE_MISALIGNMENT)
EXCEPTION(BREAKPOINT)
EXCEPTION(SINGLE_STEP)
@@ -646,8 +646,8 @@ LPTSTR WheatyExceptionReport::GetExceptionString(DWORD dwCode)
static TCHAR szBuffer[512] = { 0 };
FormatMessage(FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_HMODULE,
GetModuleHandle(_T("NTDLL.DLL")),
dwCode, 0, szBuffer, sizeof(szBuffer), 0);
GetModuleHandle(_T("NTDLL.DLL")),
dwCode, 0, szBuffer, sizeof(szBuffer), 0);
return szBuffer;
}
@@ -660,7 +660,7 @@ LPTSTR WheatyExceptionReport::GetExceptionString(DWORD dwCode)
// by the len parameter (in characters!)
//=============================================================================
BOOL WheatyExceptionReport::GetLogicalAddress(
PVOID addr, PTSTR szModule, DWORD len, DWORD& section, DWORD_PTR& offset)
PVOID addr, PTSTR szModule, DWORD len, DWORD& section, DWORD_PTR& offset)
{
MEMORY_BASIC_INFORMATION mbi;
@@ -688,12 +688,12 @@ PVOID addr, PTSTR szModule, DWORD len, DWORD& section, DWORD_PTR& offset)
// Iterate through the section table, looking for the one that encompasses
// the linear address.
for (unsigned i = 0;
i < pNtHdr->FileHeader.NumberOfSections;
i++, pSection++)
i < pNtHdr->FileHeader.NumberOfSections;
i++, pSection++)
{
DWORD_PTR sectionStart = pSection->VirtualAddress;
DWORD_PTR sectionEnd = sectionStart
+ DWORD_PTR(std::max(pSection->SizeOfRawData, pSection->Misc.VirtualSize));
+ DWORD_PTR(std::max(pSection->SizeOfRawData, pSection->Misc.VirtualSize));
// Is the address in this section???
if ((rva >= sectionStart) && (rva <= sectionEnd))
@@ -701,7 +701,7 @@ PVOID addr, PTSTR szModule, DWORD len, DWORD& section, DWORD_PTR& offset)
// Yes, address is in the section. Calculate section and offset,
// and store in the "section" & "offset" params, which were
// passed by reference.
section = i+1;
section = i + 1;
offset = rva - sectionStart;
return TRUE;
}
@@ -725,8 +725,8 @@ struct CSymbolInfoPackage : public SYMBOL_INFO_PACKAGE
// Walks the stack, and writes the results to the report file
//============================================================
void WheatyExceptionReport::WriteStackDetails(
PCONTEXT pContext,
bool bWriteVariables, HANDLE pThreadHandle) // true if local/params should be output
PCONTEXT pContext,
bool bWriteVariables, HANDLE pThreadHandle) // true if local/params should be output
{
Log(_T("\r\nCall stack:\r\n"));
@@ -738,7 +738,7 @@ bool bWriteVariables, HANDLE pThreadHandle)
STACKFRAME64 sf;
memset(&sf, 0, sizeof(sf));
#ifdef _M_IX86
#ifdef _M_IX86
// Initialize the STACKFRAME structure for the first call. This is only
// necessary for Intel CPUs, and isn't mentioned in the documentation.
sf.AddrPC.Offset = pContext->Eip;
@@ -749,7 +749,7 @@ bool bWriteVariables, HANDLE pThreadHandle)
sf.AddrFrame.Mode = AddrModeFlat;
dwMachineType = IMAGE_FILE_MACHINE_I386;
#endif
#endif
#ifdef _M_X64
sf.AddrPC.Offset = pContext->Rip;
@@ -765,14 +765,14 @@ bool bWriteVariables, HANDLE pThreadHandle)
{
// Get the next stack frame
if (! StackWalk64(dwMachineType,
m_hProcess,
pThreadHandle != NULL ? pThreadHandle : GetCurrentThread(),
&sf,
pContext,
0,
SymFunctionTableAccess64,
SymGetModuleBase64,
0))
m_hProcess,
pThreadHandle != NULL ? pThreadHandle : GetCurrentThread(),
&sf,
pContext,
0,
SymFunctionTableAccess64,
SymGetModuleBase64,
0))
break;
if (0 == sf.AddrFrame.Offset) // Basic sanity check to make sure
break; // the frame is OK. Bail if not.
@@ -789,10 +789,10 @@ bool bWriteVariables, HANDLE pThreadHandle)
// Get the name of the function for this stack frame entry
CSymbolInfoPackage sip;
if (SymFromAddr(
m_hProcess, // Process handle of the current process
sf.AddrPC.Offset, // Symbol address
&symDisplacement, // Address of the variable that will receive the displacement
&sip.si)) // Address of the SYMBOL_INFO structure (inside "sip" object)
m_hProcess, // Process handle of the current process
sf.AddrPC.Offset, // Symbol address
&symDisplacement, // Address of the variable that will receive the displacement
&sip.si)) // Address of the SYMBOL_INFO structure (inside "sip" object)
{
Log(_T("%hs+%I64X"), sip.si.Name, symDisplacement);
@@ -804,7 +804,7 @@ bool bWriteVariables, HANDLE pThreadHandle)
DWORD_PTR offset = 0;
GetLogicalAddress((PVOID)sf.AddrPC.Offset,
szModule, sizeof(szModule), section, offset);
szModule, sizeof(szModule), section, offset);
#ifdef _M_IX86
Log(_T("%04X:%08X %s"), section, offset, szModule);
#endif
@@ -817,7 +817,7 @@ bool bWriteVariables, HANDLE pThreadHandle)
IMAGEHLP_LINE64 lineInfo = { sizeof(IMAGEHLP_LINE64) };
DWORD dwLineDisplacement;
if (SymGetLineFromAddr64(m_hProcess, sf.AddrPC.Offset,
&dwLineDisplacement, &lineInfo))
&dwLineDisplacement, &lineInfo))
{
Log(_T(" %s line %u"), lineInfo.FileName, lineInfo.LineNumber);
}
@@ -847,9 +847,9 @@ bool bWriteVariables, HANDLE pThreadHandle)
BOOL CALLBACK
WheatyExceptionReport::EnumerateSymbolsCallback(
PSYMBOL_INFO pSymInfo,
ULONG /*SymbolSize*/,
PVOID UserContext)
PSYMBOL_INFO pSymInfo,
ULONG /*SymbolSize*/,
PVOID UserContext)
{
__try
{
@@ -871,8 +871,8 @@ PVOID UserContext)
// values.
//////////////////////////////////////////////////////////////////////////////
bool WheatyExceptionReport::FormatSymbolValue(
PSYMBOL_INFO pSym,
STACKFRAME64 * sf)
PSYMBOL_INFO pSym,
STACKFRAME64* sf)
{
// If it's a function, don't do anything.
if (pSym->Tag == SymTagFunction) // SymTagFunction from CVCONST.H from the DIA SDK
@@ -883,7 +883,8 @@ STACKFRAME64 * sf)
if (pSym->Flags & IMAGEHLP_SYMBOL_INFO_REGRELATIVE)
{
// if (pSym->Register == 8) // EBP is the value 8 (in DBGHELP 5.1)
{ // This may change!!!
{
// This may change!!!
#ifdef _M_IX86
pVariable = sf->AddrFrame.Offset;
#elif _M_X64
@@ -942,14 +943,14 @@ STACKFRAME64 * sf)
// bHandled = false, so that FormatSymbolValue() will format them.
//////////////////////////////////////////////////////////////////////////////
void WheatyExceptionReport::DumpTypeIndex(
DWORD64 modBase,
DWORD dwTypeIndex,
DWORD_PTR offset,
bool & bHandled,
char const* Name,
char* /*suffix*/,
bool newSymbol,
bool logChildren)
DWORD64 modBase,
DWORD dwTypeIndex,
DWORD_PTR offset,
bool& bHandled,
char const* Name,
char* /*suffix*/,
bool newSymbol,
bool logChildren)
{
bHandled = false;
@@ -962,9 +963,9 @@ bool logChildren)
// Get the name of the symbol. This will either be a Type name (if a UDT),
// or the structure member name.
WCHAR * pwszTypeName;
WCHAR* pwszTypeName;
if (SymGetTypeInfo(m_hProcess, modBase, dwTypeIndex, TI_GET_SYMNAME,
&pwszTypeName))
&pwszTypeName))
{
// handle special cases
if (wcscmp(pwszTypeName, L"std::basic_string<char,std::char_traits<char>,std::allocator<char> >") == 0)
@@ -1085,17 +1086,17 @@ bool logChildren)
if (symbolDetails.size() >= WER_MAX_NESTING_LEVEL)
logChildren = false;
DumpTypeIndex(modBase, innerTypeID,
offset, bHandled, symbolDetails.top().Name.c_str(), "", false, logChildren);
offset, bHandled, symbolDetails.top().Name.c_str(), "", false, logChildren);
break;
case SymTagPointerType:
if (Name != NULL && Name[0] != '\0')
symbolDetails.top().Name = Name;
DumpTypeIndex(modBase, innerTypeID,
offset, bHandled, symbolDetails.top().Name.c_str(), "", false, logChildren);
offset, bHandled, symbolDetails.top().Name.c_str(), "", false, logChildren);
break;
case SymTagArrayType:
DumpTypeIndex(modBase, innerTypeID,
offset, bHandled, symbolDetails.top().Name.c_str(), "", false, logChildren);
offset, bHandled, symbolDetails.top().Name.c_str(), "", false, logChildren);
break;
default:
break;
@@ -1109,7 +1110,7 @@ bool logChildren)
BasicType basicType = btNoType;
DumpTypeIndex(modBase, innerTypeID,
offset, bHandled, Name, "", false, false);
offset, bHandled, Name, "", false, false);
// Set Value back to an empty string since the Array object itself has no value, only its elements have
std::string firstElementValue = symbolDetails.top().Value;
@@ -1196,16 +1197,16 @@ bool logChildren)
// TI_FINDCHILDREN_PARAMS struct has. Use derivation to accomplish this.
struct FINDCHILDREN : TI_FINDCHILDREN_PARAMS
{
ULONG MoreChildIds[1024*2];
FINDCHILDREN(){Count = sizeof(MoreChildIds) / sizeof(MoreChildIds[0]);}
ULONG MoreChildIds[1024 * 2];
FINDCHILDREN() {Count = sizeof(MoreChildIds) / sizeof(MoreChildIds[0]);}
} children;
children.Count = dwChildrenCount;
children.Start= 0;
children.Start = 0;
// Get the array of TypeIds, one for each child type
if (!SymGetTypeInfo(m_hProcess, modBase, dwTypeIndex, TI_FINDCHILDREN,
&children))
&children))
{
return;
}
@@ -1217,17 +1218,17 @@ bool logChildren)
SymGetTypeInfo(m_hProcess, modBase, children.ChildId[i], TI_GET_SYMTAG, &symTag);
if (symTag == SymTagFunction ||
symTag == SymTagEnum ||
symTag == SymTagTypedef ||
symTag == SymTagVTable)
symTag == SymTagEnum ||
symTag == SymTagTypedef ||
symTag == SymTagVTable)
continue;
// Ignore static fields
DWORD dataKind;
SymGetTypeInfo(m_hProcess, modBase, children.ChildId[i], TI_GET_DATAKIND, &dataKind);
if (dataKind == DataIsStaticLocal ||
dataKind == DataIsGlobal ||
dataKind == DataIsStaticMember)
dataKind == DataIsGlobal ||
dataKind == DataIsStaticMember)
continue;
@@ -1245,14 +1246,14 @@ bool logChildren)
// Get the offset of the child member, relative to its parent
DWORD dwMemberOffset;
SymGetTypeInfo(m_hProcess, modBase, children.ChildId[i],
TI_GET_OFFSET, &dwMemberOffset);
TI_GET_OFFSET, &dwMemberOffset);
// Calculate the address of the member
DWORD_PTR dwFinalOffset = offset + dwMemberOffset;
DumpTypeIndex(modBase,
children.ChildId[i],
dwFinalOffset, bHandled2, ""/*Name */, "", true, true);
children.ChildId[i],
dwFinalOffset, bHandled2, ""/*Name */, "", true, true);
// If the child wasn't a UDT, format it appropriately
if (!bHandled2)
@@ -1264,7 +1265,7 @@ bool logChildren)
// SymGetTypeInfo(TI_GET_TYPEID) call below.
DWORD typeId;
SymGetTypeInfo(m_hProcess, modBase, children.ChildId[i],
TI_GET_TYPEID, &typeId);
TI_GET_TYPEID, &typeId);
// Get the size of the child member
ULONG64 length;
@@ -1282,39 +1283,39 @@ bool logChildren)
return;
}
void WheatyExceptionReport::FormatOutputValue(char * pszCurrBuffer,
BasicType basicType,
DWORD64 length,
PVOID pAddress,
size_t bufferSize,
size_t countOverride)
void WheatyExceptionReport::FormatOutputValue(char* pszCurrBuffer,
BasicType basicType,
DWORD64 length,
PVOID pAddress,
size_t bufferSize,
size_t countOverride)
{
__try
{
switch (basicType)
{
case btChar:
{
// Special case handling for char[] type
if (countOverride != 0)
length = countOverride;
else
length = strlen((char*)pAddress);
if (length > bufferSize - 6)
pszCurrBuffer += sprintf(pszCurrBuffer, "\"%.*s...\"", (DWORD)(bufferSize - 6), (char*)pAddress);
else
pszCurrBuffer += sprintf(pszCurrBuffer, "\"%.*s\"", (DWORD)length, (char*)pAddress);
break;
}
{
// Special case handling for char[] type
if (countOverride != 0)
length = countOverride;
else
length = strlen((char*)pAddress);
if (length > bufferSize - 6)
pszCurrBuffer += sprintf(pszCurrBuffer, "\"%.*s...\"", (DWORD)(bufferSize - 6), (char*)pAddress);
else
pszCurrBuffer += sprintf(pszCurrBuffer, "\"%.*s\"", (DWORD)length, (char*)pAddress);
break;
}
case btStdString:
{
std::string* value = static_cast<std::string*>(pAddress);
if (value->length() > bufferSize - 6)
pszCurrBuffer += sprintf(pszCurrBuffer, "\"%.*s...\"", (DWORD)(bufferSize - 6), value->c_str());
else
pszCurrBuffer += sprintf(pszCurrBuffer, "\"%s\"", value->c_str());
break;
}
{
std::string* value = static_cast<std::string*>(pAddress);
if (value->length() > bufferSize - 6)
pszCurrBuffer += sprintf(pszCurrBuffer, "\"%.*s...\"", (DWORD)(bufferSize - 6), value->c_str());
else
pszCurrBuffer += sprintf(pszCurrBuffer, "\"%s\"", value->c_str());
break;
}
default:
// Format appropriately (assuming it's a 1, 2, or 4 bytes (!!!)
if (length == 1)
@@ -1333,19 +1334,19 @@ size_t countOverride)
if (basicType == btFloat)
{
pszCurrBuffer += sprintf(pszCurrBuffer, "%f",
*(double *)pAddress);
*(double*)pAddress);
}
else
pszCurrBuffer += sprintf(pszCurrBuffer, "0x%I64X",
*(DWORD64*)pAddress);
*(DWORD64*)pAddress);
}
else
{
#if _WIN64
#if _WIN64
pszCurrBuffer += sprintf(pszCurrBuffer, "0x%I64X", (DWORD64)pAddress);
#else
#else
pszCurrBuffer += sprintf(pszCurrBuffer, "0x%X", (DWORD)pAddress);
#endif
#endif
}
break;
}
@@ -1365,7 +1366,7 @@ WheatyExceptionReport::GetBasicType(DWORD typeIndex, DWORD64 modBase)
{
BasicType basicType;
if (SymGetTypeInfo(m_hProcess, modBase, typeIndex,
TI_GET_BASETYPE, &basicType))
TI_GET_BASETYPE, &basicType))
{
return basicType;
}
@@ -1376,7 +1377,7 @@ WheatyExceptionReport::GetBasicType(DWORD typeIndex, DWORD64 modBase)
if (SymGetTypeInfo(m_hProcess, modBase, typeIndex, TI_GET_TYPEID, &typeId))
{
if (SymGetTypeInfo(m_hProcess, modBase, typeId, TI_GET_BASETYPE,
&basicType))
&basicType))
{
return basicType;
}
@@ -1401,12 +1402,12 @@ DWORD_PTR WheatyExceptionReport::DereferenceUnsafePointer(DWORD_PTR address)
// Helper function that writes to the report file, and allows the user to use
// printf style formating
//============================================================================
int __cdecl WheatyExceptionReport::Log(const TCHAR * format, ...)
int __cdecl WheatyExceptionReport::Log(const TCHAR* format, ...)
{
int retValue;
va_list argptr;
va_start(argptr, format);
if (stackOverflowException)
retValue = HeapLog(format, argptr);
else
@@ -1417,7 +1418,7 @@ int __cdecl WheatyExceptionReport::Log(const TCHAR * format, ...)
return retValue;
}
int __cdecl WheatyExceptionReport::StackLog(const TCHAR * format, va_list argptr)
int __cdecl WheatyExceptionReport::StackLog(const TCHAR* format, va_list argptr)
{
int retValue;
DWORD cbWritten;
@@ -1429,7 +1430,7 @@ int __cdecl WheatyExceptionReport::StackLog(const TCHAR * format, va_list argptr
return retValue;
}
int __cdecl WheatyExceptionReport::HeapLog(const TCHAR * format, va_list argptr)
int __cdecl WheatyExceptionReport::HeapLog(const TCHAR* format, va_list argptr)
{
int retValue = 0;
DWORD cbWritten;

View File

@@ -103,7 +103,7 @@ struct SymbolPair
bool operator<(SymbolPair const& other) const
{
return _offset < other._offset ||
(_offset == other._offset && _type < other._type);
(_offset == other._offset && _type < other._type);
}
DWORD _type;
@@ -133,69 +133,69 @@ struct SymbolDetail
class WheatyExceptionReport
{
public:
public:
WheatyExceptionReport();
~WheatyExceptionReport();
WheatyExceptionReport();
~WheatyExceptionReport();
// entry point where control comes on an unhandled exception
static LONG WINAPI WheatyUnhandledExceptionFilter(
PEXCEPTION_POINTERS pExceptionInfo);
// entry point where control comes on an unhandled exception
static LONG WINAPI WheatyUnhandledExceptionFilter(
PEXCEPTION_POINTERS pExceptionInfo);
static void __cdecl WheatyCrtHandler(wchar_t const* expression, wchar_t const* function, wchar_t const* file, unsigned int line, uintptr_t pReserved);
static void __cdecl WheatyCrtHandler(wchar_t const* expression, wchar_t const* function, wchar_t const* file, unsigned int line, uintptr_t pReserved);
static void printTracesForAllThreads(bool);
private:
// where report info is extracted and generated
static void GenerateExceptionReport(PEXCEPTION_POINTERS pExceptionInfo);
static void PrintSystemInfo();
static BOOL _GetWindowsVersion(TCHAR* szVersion, DWORD cntMax);
static BOOL _GetProcessorName(TCHAR* sProcessorName, DWORD maxcount);
static void printTracesForAllThreads(bool);
private:
// where report info is extracted and generated
static void GenerateExceptionReport(PEXCEPTION_POINTERS pExceptionInfo);
static void PrintSystemInfo();
static BOOL _GetWindowsVersion(TCHAR* szVersion, DWORD cntMax);
static BOOL _GetProcessorName(TCHAR* sProcessorName, DWORD maxcount);
// Helper functions
static LPTSTR GetExceptionString(DWORD dwCode);
static BOOL GetLogicalAddress(PVOID addr, PTSTR szModule, DWORD len,
DWORD& section, DWORD_PTR& offset);
// Helper functions
static LPTSTR GetExceptionString(DWORD dwCode);
static BOOL GetLogicalAddress(PVOID addr, PTSTR szModule, DWORD len,
DWORD& section, DWORD_PTR& offset);
static void WriteStackDetails(PCONTEXT pContext, bool bWriteVariables, HANDLE pThreadHandle);
static void WriteStackDetails(PCONTEXT pContext, bool bWriteVariables, HANDLE pThreadHandle);
static BOOL CALLBACK EnumerateSymbolsCallback(PSYMBOL_INFO, ULONG, PVOID);
static BOOL CALLBACK EnumerateSymbolsCallback(PSYMBOL_INFO, ULONG, PVOID);
static bool FormatSymbolValue(PSYMBOL_INFO, STACKFRAME64 *);
static bool FormatSymbolValue(PSYMBOL_INFO, STACKFRAME64*);
static void DumpTypeIndex(DWORD64, DWORD, DWORD_PTR, bool &, char const*, char*, bool, bool);
static void DumpTypeIndex(DWORD64, DWORD, DWORD_PTR, bool&, char const*, char*, bool, bool);
static void FormatOutputValue(char * pszCurrBuffer, BasicType basicType, DWORD64 length, PVOID pAddress, size_t bufferSize, size_t countOverride = 0);
static void FormatOutputValue(char* pszCurrBuffer, BasicType basicType, DWORD64 length, PVOID pAddress, size_t bufferSize, size_t countOverride = 0);
static BasicType GetBasicType(DWORD typeIndex, DWORD64 modBase);
static DWORD_PTR DereferenceUnsafePointer(DWORD_PTR address);
static BasicType GetBasicType(DWORD typeIndex, DWORD64 modBase);
static DWORD_PTR DereferenceUnsafePointer(DWORD_PTR address);
static int __cdecl Log(const TCHAR * format, ...);
static int __cdecl StackLog(const TCHAR * format, va_list argptr);
static int __cdecl HeapLog(const TCHAR * format, va_list argptr);
static int __cdecl Log(const TCHAR* format, ...);
static int __cdecl StackLog(const TCHAR* format, va_list argptr);
static int __cdecl HeapLog(const TCHAR* format, va_list argptr);
static bool StoreSymbol(DWORD type , DWORD_PTR offset);
static void ClearSymbols();
static bool StoreSymbol(DWORD type, DWORD_PTR offset);
static void ClearSymbols();
// Variables used by the class
static TCHAR m_szLogFileName[MAX_PATH];
static TCHAR m_szDumpFileName[MAX_PATH];
static LPTOP_LEVEL_EXCEPTION_FILTER m_previousFilter;
static _invalid_parameter_handler m_previousCrtHandler;
static HANDLE m_hReportFile;
static HANDLE m_hDumpFile;
static HANDLE m_hProcess;
static SymbolPairs symbols;
static std::stack<SymbolDetail> symbolDetails;
static bool stackOverflowException;
static bool alreadyCrashed;
static std::mutex alreadyCrashedLock;
typedef NTSTATUS(NTAPI* pRtlGetVersion)(PRTL_OSVERSIONINFOW lpVersionInformation);
static pRtlGetVersion RtlGetVersion;
// Variables used by the class
static TCHAR m_szLogFileName[MAX_PATH];
static TCHAR m_szDumpFileName[MAX_PATH];
static LPTOP_LEVEL_EXCEPTION_FILTER m_previousFilter;
static _invalid_parameter_handler m_previousCrtHandler;
static HANDLE m_hReportFile;
static HANDLE m_hDumpFile;
static HANDLE m_hProcess;
static SymbolPairs symbols;
static std::stack<SymbolDetail> symbolDetails;
static bool stackOverflowException;
static bool alreadyCrashed;
static std::mutex alreadyCrashedLock;
typedef NTSTATUS(NTAPI* pRtlGetVersion)(PRTL_OSVERSIONINFOW lpVersionInformation);
static pRtlGetVersion RtlGetVersion;
static void PushSymbolDetail();
static void PopSymbolDetail();
static void PrintSymbolDetail();
static void PushSymbolDetail();
static void PopSymbolDetail();
static void PrintSymbolDetail();
};

View File

@@ -41,9 +41,9 @@ private:
template<class T>
class Permissible
{
public:
virtual ~Permissible() { }
virtual int Permit(const T *) const = 0;
public:
virtual ~Permissible() { }
virtual int Permit(const T*) const = 0;
};
#endif

View File

@@ -15,218 +15,236 @@ class LinkedListHead;
class LinkedListElement
{
private:
friend class LinkedListHead;
private:
friend class LinkedListHead;
LinkedListElement* iNext;
LinkedListElement* iPrev;
public:
LinkedListElement(): iNext(NULL), iPrev(NULL) { }
~LinkedListElement() { delink(); }
LinkedListElement* iNext;
LinkedListElement* iPrev;
public:
LinkedListElement(): iNext(NULL), iPrev(NULL) { }
~LinkedListElement() { delink(); }
bool hasNext() const { return(iNext && iNext->iNext != NULL); }
bool hasPrev() const { return(iPrev && iPrev->iPrev != NULL); }
bool isInList() const { return(iNext != NULL && iPrev != NULL); }
bool hasNext() const { return(iNext && iNext->iNext != NULL); }
bool hasPrev() const { return(iPrev && iPrev->iPrev != NULL); }
bool isInList() const { return(iNext != NULL && iPrev != NULL); }
LinkedListElement * next() { return hasNext() ? iNext : NULL; }
LinkedListElement const* next() const { return hasNext() ? iNext : NULL; }
LinkedListElement * prev() { return hasPrev() ? iPrev : NULL; }
LinkedListElement const* prev() const { return hasPrev() ? iPrev : NULL; }
LinkedListElement* next() { return hasNext() ? iNext : NULL; }
LinkedListElement const* next() const { return hasNext() ? iNext : NULL; }
LinkedListElement* prev() { return hasPrev() ? iPrev : NULL; }
LinkedListElement const* prev() const { return hasPrev() ? iPrev : NULL; }
LinkedListElement * nocheck_next() { return iNext; }
LinkedListElement const* nocheck_next() const { return iNext; }
LinkedListElement * nocheck_prev() { return iPrev; }
LinkedListElement const* nocheck_prev() const { return iPrev; }
LinkedListElement* nocheck_next() { return iNext; }
LinkedListElement const* nocheck_next() const { return iNext; }
LinkedListElement* nocheck_prev() { return iPrev; }
LinkedListElement const* nocheck_prev() const { return iPrev; }
void delink()
void delink()
{
if (isInList())
{
if (isInList())
{
iNext->iPrev = iPrev; iPrev->iNext = iNext; iNext = NULL; iPrev = NULL;
}
iNext->iPrev = iPrev;
iPrev->iNext = iNext;
iNext = NULL;
iPrev = NULL;
}
}
void insertBefore(LinkedListElement* pElem)
{
pElem->iNext = this;
pElem->iPrev = iPrev;
iPrev->iNext = pElem;
iPrev = pElem;
}
void insertBefore(LinkedListElement* pElem)
{
pElem->iNext = this;
pElem->iPrev = iPrev;
iPrev->iNext = pElem;
iPrev = pElem;
}
void insertAfter(LinkedListElement* pElem)
{
pElem->iPrev = this;
pElem->iNext = iNext;
iNext->iPrev = pElem;
iNext = pElem;
}
void insertAfter(LinkedListElement* pElem)
{
pElem->iPrev = this;
pElem->iNext = iNext;
iNext->iPrev = pElem;
iNext = pElem;
}
};
//============================================
class LinkedListHead
{
private:
LinkedListElement iFirst;
LinkedListElement iLast;
uint32 iSize;
public:
LinkedListHead(): iSize(0)
private:
LinkedListElement iFirst;
LinkedListElement iLast;
uint32 iSize;
public:
LinkedListHead(): iSize(0)
{
// create empty list
iFirst.iNext = &iLast;
iLast.iPrev = &iFirst;
}
bool isEmpty() const { return(!iFirst.iNext->isInList()); }
LinkedListElement* getFirst() { return(isEmpty() ? NULL : iFirst.iNext); }
LinkedListElement const* getFirst() const { return(isEmpty() ? NULL : iFirst.iNext); }
LinkedListElement* getLast() { return(isEmpty() ? NULL : iLast.iPrev); }
LinkedListElement const* getLast() const { return(isEmpty() ? NULL : iLast.iPrev); }
void insertFirst(LinkedListElement* pElem)
{
iFirst.insertAfter(pElem);
}
void insertLast(LinkedListElement* pElem)
{
iLast.insertBefore(pElem);
}
uint32 getSize() const
{
if (!iSize)
{
// create empty list
iFirst.iNext = &iLast;
iLast.iPrev = &iFirst;
}
bool isEmpty() const { return(!iFirst.iNext->isInList()); }
LinkedListElement * getFirst() { return(isEmpty() ? NULL : iFirst.iNext); }
LinkedListElement const* getFirst() const { return(isEmpty() ? NULL : iFirst.iNext); }
LinkedListElement * getLast() { return(isEmpty() ? NULL : iLast.iPrev); }
LinkedListElement const* getLast() const { return(isEmpty() ? NULL : iLast.iPrev); }
void insertFirst(LinkedListElement* pElem)
{
iFirst.insertAfter(pElem);
}
void insertLast(LinkedListElement* pElem)
{
iLast.insertBefore(pElem);
}
uint32 getSize() const
{
if (!iSize)
uint32 result = 0;
LinkedListElement const* e = getFirst();
while (e)
{
uint32 result = 0;
LinkedListElement const* e = getFirst();
while (e)
{
++result;
e = e->next();
}
return result;
++result;
e = e->next();
}
else
return iSize;
return result;
}
else
return iSize;
}
void incSize() { ++iSize; }
void decSize() { --iSize; }
template<class _Ty>
class Iterator
{
public:
typedef std::bidirectional_iterator_tag iterator_category;
typedef _Ty value_type;
typedef ptrdiff_t difference_type;
typedef ptrdiff_t distance_type;
typedef _Ty* pointer;
typedef _Ty const* const_pointer;
typedef _Ty& reference;
typedef _Ty const& const_reference;
Iterator() : _Ptr(0)
{
// construct with null node pointer
}
void incSize() { ++iSize; }
void decSize() { --iSize; }
template<class _Ty>
class Iterator
Iterator(pointer _Pnode) : _Ptr(_Pnode)
{
public:
typedef std::bidirectional_iterator_tag iterator_category;
typedef _Ty value_type;
typedef ptrdiff_t difference_type;
typedef ptrdiff_t distance_type;
typedef _Ty* pointer;
typedef _Ty const* const_pointer;
typedef _Ty& reference;
typedef _Ty const & const_reference;
// construct with node pointer _Pnode
}
Iterator() : _Ptr(0)
{ // construct with null node pointer
}
Iterator& operator=(Iterator const& _Right)
{
_Ptr = _Right._Ptr;
return *this;
}
Iterator(pointer _Pnode) : _Ptr(_Pnode)
{ // construct with node pointer _Pnode
}
Iterator& operator=(const_pointer const& _Right)
{
_Ptr = pointer(_Right);
return *this;
}
Iterator& operator=(Iterator const &_Right)
{
_Ptr = _Right._Ptr;
return *this;
}
reference operator*()
{
// return designated value
return *_Ptr;
}
Iterator& operator=(const_pointer const &_Right)
{
_Ptr = pointer(_Right);
return *this;
}
pointer operator->()
{
// return pointer to class object
return _Ptr;
}
reference operator*()
{ // return designated value
return *_Ptr;
}
Iterator& operator++()
{
// preincrement
_Ptr = _Ptr->next();
return (*this);
}
pointer operator->()
{ // return pointer to class object
return _Ptr;
}
Iterator operator++(int)
{
// postincrement
iterator _Tmp = *this;
++*this;
return (_Tmp);
}
Iterator& operator++()
{ // preincrement
_Ptr = _Ptr->next();
return (*this);
}
Iterator& operator--()
{
// predecrement
_Ptr = _Ptr->prev();
return (*this);
}
Iterator operator++(int)
{ // postincrement
iterator _Tmp = *this;
++*this;
return (_Tmp);
}
Iterator operator--(int)
{
// postdecrement
iterator _Tmp = *this;
--*this;
return (_Tmp);
}
Iterator& operator--()
{ // predecrement
_Ptr = _Ptr->prev();
return (*this);
}
bool operator==(Iterator const& _Right) const
{
// test for iterator equality
return (_Ptr == _Right._Ptr);
}
Iterator operator--(int)
{ // postdecrement
iterator _Tmp = *this;
--*this;
return (_Tmp);
}
bool operator!=(Iterator const& _Right) const
{
// test for iterator inequality
return (!(*this == _Right));
}
bool operator==(Iterator const &_Right) const
{ // test for iterator equality
return (_Ptr == _Right._Ptr);
}
bool operator==(pointer const& _Right) const
{
// test for pointer equality
return (_Ptr != _Right);
}
bool operator!=(Iterator const &_Right) const
{ // test for iterator inequality
return (!(*this == _Right));
}
bool operator!=(pointer const& _Right) const
{
// test for pointer equality
return (!(*this == _Right));
}
bool operator==(pointer const &_Right) const
{ // test for pointer equality
return (_Ptr != _Right);
}
bool operator==(const_reference _Right) const
{
// test for reference equality
return (_Ptr == &_Right);
}
bool operator!=(pointer const &_Right) const
{ // test for pointer equality
return (!(*this == _Right));
}
bool operator!=(const_reference _Right) const
{
// test for reference equality
return (_Ptr != &_Right);
}
bool operator==(const_reference _Right) const
{ // test for reference equality
return (_Ptr == &_Right);
}
pointer _Mynode()
{
// return node pointer
return (_Ptr);
}
bool operator!=(const_reference _Right) const
{ // test for reference equality
return (_Ptr != &_Right);
}
protected:
pointer _Ptr; // pointer to node
};
pointer _Mynode()
{ // return node pointer
return (_Ptr);
}
protected:
pointer _Ptr; // pointer to node
};
typedef Iterator<LinkedListElement> iterator;
typedef Iterator<LinkedListElement> iterator;
};
//============================================

View File

@@ -13,30 +13,30 @@
template <class TO, class FROM> class RefManager : public LinkedListHead
{
public:
typedef LinkedListHead::Iterator< Reference<TO, FROM> > iterator;
RefManager() { }
virtual ~RefManager() { clearReferences(); }
public:
typedef LinkedListHead::Iterator< Reference<TO, FROM> > iterator;
RefManager() { }
virtual ~RefManager() { clearReferences(); }
Reference<TO, FROM>* getFirst() { return ((Reference<TO, FROM>*) LinkedListHead::getFirst()); }
Reference<TO, FROM> const* getFirst() const { return ((Reference<TO, FROM> const*) LinkedListHead::getFirst()); }
Reference<TO, FROM>* getLast() { return ((Reference<TO, FROM>*) LinkedListHead::getLast()); }
Reference<TO, FROM> const* getLast() const { return ((Reference<TO, FROM> const*) LinkedListHead::getLast()); }
Reference<TO, FROM>* getFirst() { return ((Reference<TO, FROM>*) LinkedListHead::getFirst()); }
Reference<TO, FROM> const* getFirst() const { return ((Reference<TO, FROM> const*) LinkedListHead::getFirst()); }
Reference<TO, FROM>* getLast() { return ((Reference<TO, FROM>*) LinkedListHead::getLast()); }
Reference<TO, FROM> const* getLast() const { return ((Reference<TO, FROM> const*) LinkedListHead::getLast()); }
iterator begin() { return iterator(getFirst()); }
iterator end() { return iterator(NULL); }
iterator rbegin() { return iterator(getLast()); }
iterator rend() { return iterator(NULL); }
iterator begin() { return iterator(getFirst()); }
iterator end() { return iterator(NULL); }
iterator rbegin() { return iterator(getLast()); }
iterator rend() { return iterator(NULL); }
void clearReferences()
void clearReferences()
{
LinkedListElement* ref;
while ((ref = getFirst()) != NULL)
{
LinkedListElement* ref;
while ((ref = getFirst()) != NULL)
{
((Reference<TO, FROM>*) ref)->invalidate();
ref->delink(); // the delink might be already done by invalidate(), but doing it here again does not hurt and insures an empty list
}
((Reference<TO, FROM>*) ref)->invalidate();
ref->delink(); // the delink might be already done by invalidate(), but doing it here again does not hurt and insures an empty list
}
}
};
//=====================================================

View File

@@ -14,74 +14,74 @@
template <class TO, class FROM> class Reference : public LinkedListElement
{
private:
TO* iRefTo;
FROM* iRefFrom;
protected:
// Tell our refTo (target) object that we have a link
virtual void targetObjectBuildLink() = 0;
private:
TO* iRefTo;
FROM* iRefFrom;
protected:
// Tell our refTo (target) object that we have a link
virtual void targetObjectBuildLink() = 0;
// Tell our refTo (taget) object, that the link is cut
virtual void targetObjectDestroyLink() = 0;
// Tell our refTo (taget) object, that the link is cut
virtual void targetObjectDestroyLink() = 0;
// Tell our refFrom (source) object, that the link is cut (Target destroyed)
virtual void sourceObjectDestroyLink() = 0;
public:
Reference() { iRefTo = NULL; iRefFrom = NULL; }
virtual ~Reference() { }
// Tell our refFrom (source) object, that the link is cut (Target destroyed)
virtual void sourceObjectDestroyLink() = 0;
public:
Reference() { iRefTo = NULL; iRefFrom = NULL; }
virtual ~Reference() { }
// Create new link
void link(TO* toObj, FROM* fromObj)
// Create new link
void link(TO* toObj, FROM* fromObj)
{
ASSERT(fromObj); // fromObj MUST not be NULL
if (isValid())
unlink();
if (toObj != NULL)
{
ASSERT(fromObj); // fromObj MUST not be NULL
if (isValid())
unlink();
if (toObj != NULL)
{
iRefTo = toObj;
iRefFrom = fromObj;
targetObjectBuildLink();
}
iRefTo = toObj;
iRefFrom = fromObj;
targetObjectBuildLink();
}
}
// We don't need the reference anymore. Call comes from the refFrom object
// Tell our refTo object, that the link is cut
void unlink()
{
targetObjectDestroyLink();
delink();
iRefTo = NULL;
iRefFrom = NULL;
}
// We don't need the reference anymore. Call comes from the refFrom object
// Tell our refTo object, that the link is cut
void unlink()
{
targetObjectDestroyLink();
delink();
iRefTo = NULL;
iRefFrom = NULL;
}
// Link is invalid due to destruction of referenced target object. Call comes from the refTo object
// Tell our refFrom object, that the link is cut
void invalidate() // the iRefFrom MUST remain!!
{
sourceObjectDestroyLink();
delink();
iRefTo = NULL;
}
// Link is invalid due to destruction of referenced target object. Call comes from the refTo object
// Tell our refFrom object, that the link is cut
void invalidate() // the iRefFrom MUST remain!!
{
sourceObjectDestroyLink();
delink();
iRefTo = NULL;
}
bool isValid() const // Only check the iRefTo
{
return iRefTo != NULL;
}
bool isValid() const // Only check the iRefTo
{
return iRefTo != NULL;
}
Reference<TO, FROM> * next() { return((Reference<TO, FROM> *) LinkedListElement::next()); }
Reference<TO, FROM> const* next() const { return((Reference<TO, FROM> const*) LinkedListElement::next()); }
Reference<TO, FROM> * prev() { return((Reference<TO, FROM> *) LinkedListElement::prev()); }
Reference<TO, FROM> const* prev() const { return((Reference<TO, FROM> const*) LinkedListElement::prev()); }
Reference<TO, FROM>* next() { return((Reference<TO, FROM>*) LinkedListElement::next()); }
Reference<TO, FROM> const* next() const { return((Reference<TO, FROM> const*) LinkedListElement::next()); }
Reference<TO, FROM>* prev() { return((Reference<TO, FROM>*) LinkedListElement::prev()); }
Reference<TO, FROM> const* prev() const { return((Reference<TO, FROM> const*) LinkedListElement::prev()); }
Reference<TO, FROM> * nocheck_next() { return((Reference<TO, FROM> *) LinkedListElement::nocheck_next()); }
Reference<TO, FROM> const* nocheck_next() const { return((Reference<TO, FROM> const*) LinkedListElement::nocheck_next()); }
Reference<TO, FROM> * nocheck_prev() { return((Reference<TO, FROM> *) LinkedListElement::nocheck_prev()); }
Reference<TO, FROM> const* nocheck_prev() const { return((Reference<TO, FROM> const*) LinkedListElement::nocheck_prev()); }
Reference<TO, FROM>* nocheck_next() { return((Reference<TO, FROM>*) LinkedListElement::nocheck_next()); }
Reference<TO, FROM> const* nocheck_next() const { return((Reference<TO, FROM> const*) LinkedListElement::nocheck_next()); }
Reference<TO, FROM>* nocheck_prev() { return((Reference<TO, FROM>*) LinkedListElement::nocheck_prev()); }
Reference<TO, FROM> const* nocheck_prev() const { return((Reference<TO, FROM> const*) LinkedListElement::nocheck_prev()); }
TO* operator ->() const { return iRefTo; }
TO* getTarget() const { return iRefTo; }
TO* operator ->() const { return iRefTo; }
TO* getTarget() const { return iRefTo; }
FROM* GetSource() const { return iRefFrom; }
FROM* GetSource() const { return iRefFrom; }
};
//=====================================================

View File

@@ -18,81 +18,81 @@
template<class T, class Key = std::string>
class ObjectRegistry
{
public:
typedef std::map<Key, T *> RegistryMapType;
public:
typedef std::map<Key, T*> RegistryMapType;
/// Returns a registry item
const T* GetRegistryItem(Key key) const
/// Returns a registry item
const T* GetRegistryItem(Key key) const
{
typename RegistryMapType::const_iterator iter = i_registeredObjects.find(key);
return( iter == i_registeredObjects.end() ? NULL : iter->second );
}
static ObjectRegistry<T, Key>* instance()
{
static ObjectRegistry<T, Key>* instance = new ObjectRegistry<T, Key>();
return instance;
}
/// Inserts a registry item
bool InsertItem(T* obj, Key key, bool override = false)
{
typename RegistryMapType::iterator iter = i_registeredObjects.find(key);
if ( iter != i_registeredObjects.end() )
{
typename RegistryMapType::const_iterator iter = i_registeredObjects.find(key);
return( iter == i_registeredObjects.end() ? NULL : iter->second );
if ( !override )
return false;
delete iter->second;
i_registeredObjects.erase(iter);
}
static ObjectRegistry<T, Key>* instance()
{
static ObjectRegistry<T, Key>* instance = new ObjectRegistry<T, Key>();
return instance;
}
i_registeredObjects[key] = obj;
return true;
}
/// Inserts a registry item
bool InsertItem(T *obj, Key key, bool override = false)
/// Removes a registry item
void RemoveItem(Key key, bool delete_object = true)
{
typename RegistryMapType::iterator iter = i_registeredObjects.find(key);
if ( iter != i_registeredObjects.end() )
{
typename RegistryMapType::iterator iter = i_registeredObjects.find(key);
if ( iter != i_registeredObjects.end() )
{
if ( !override )
return false;
if ( delete_object )
delete iter->second;
i_registeredObjects.erase(iter);
}
i_registeredObjects[key] = obj;
return true;
i_registeredObjects.erase(iter);
}
}
/// Removes a registry item
void RemoveItem(Key key, bool delete_object = true)
{
typename RegistryMapType::iterator iter = i_registeredObjects.find(key);
if ( iter != i_registeredObjects.end() )
{
if ( delete_object )
delete iter->second;
i_registeredObjects.erase(iter);
}
}
/// Returns true if registry contains an item
bool HasItem(Key key) const
{
return (i_registeredObjects.find(key) != i_registeredObjects.end());
}
/// Returns true if registry contains an item
bool HasItem(Key key) const
{
return (i_registeredObjects.find(key) != i_registeredObjects.end());
}
/// Inefficiently return a vector of registered items
unsigned int GetRegisteredItems(std::vector<Key>& l) const
{
unsigned int sz = l.size();
l.resize(sz + i_registeredObjects.size());
for (typename RegistryMapType::const_iterator iter = i_registeredObjects.begin(); iter != i_registeredObjects.end(); ++iter)
l[sz++] = iter->first;
return i_registeredObjects.size();
}
/// Inefficiently return a vector of registered items
unsigned int GetRegisteredItems(std::vector<Key> &l) const
{
unsigned int sz = l.size();
l.resize(sz + i_registeredObjects.size());
for (typename RegistryMapType::const_iterator iter = i_registeredObjects.begin(); iter != i_registeredObjects.end(); ++iter)
l[sz++] = iter->first;
return i_registeredObjects.size();
}
/// Return the map of registered items
RegistryMapType const& GetRegisteredItems() const
{
return i_registeredObjects;
}
/// Return the map of registered items
RegistryMapType const &GetRegisteredItems() const
{
return i_registeredObjects;
}
ObjectRegistry() { }
~ObjectRegistry()
{
for (typename RegistryMapType::iterator iter=i_registeredObjects.begin(); iter != i_registeredObjects.end(); ++iter)
delete iter->second;
i_registeredObjects.clear();
}
private:
RegistryMapType i_registeredObjects;
ObjectRegistry() { }
~ObjectRegistry()
{
for (typename RegistryMapType::iterator iter = i_registeredObjects.begin(); iter != i_registeredObjects.end(); ++iter)
delete iter->second;
i_registeredObjects.clear();
}
private:
RegistryMapType i_registeredObjects;
};
#endif

View File

@@ -85,28 +85,28 @@ template<class H, class T> struct ContainerList<TypeList<H, T> >
template<class OBJECT_TYPES>
class TypeMapContainer
{
public:
template<class SPECIFIC_TYPE> size_t Count() const { return acore::Count(i_elements, (SPECIFIC_TYPE*)NULL); }
public:
template<class SPECIFIC_TYPE> size_t Count() const { return acore::Count(i_elements, (SPECIFIC_TYPE*)NULL); }
/// inserts a specific object into the container
template<class SPECIFIC_TYPE> bool insert(SPECIFIC_TYPE *obj)
{
SPECIFIC_TYPE* t = acore::Insert(i_elements, obj);
return (t != NULL);
}
/// inserts a specific object into the container
template<class SPECIFIC_TYPE> bool insert(SPECIFIC_TYPE* obj)
{
SPECIFIC_TYPE* t = acore::Insert(i_elements, obj);
return (t != NULL);
}
/// Removes the object from the container, and returns the removed object
//template<class SPECIFIC_TYPE> bool remove(SPECIFIC_TYPE* obj)
//{
// SPECIFIC_TYPE* t = acore::Remove(i_elements, obj);
// return (t != NULL);
//}
/// Removes the object from the container, and returns the removed object
//template<class SPECIFIC_TYPE> bool remove(SPECIFIC_TYPE* obj)
//{
// SPECIFIC_TYPE* t = acore::Remove(i_elements, obj);
// return (t != NULL);
//}
ContainerMapList<OBJECT_TYPES> & GetElements(void) { return i_elements; }
const ContainerMapList<OBJECT_TYPES> & GetElements(void) const { return i_elements;}
ContainerMapList<OBJECT_TYPES>& GetElements(void) { return i_elements; }
const ContainerMapList<OBJECT_TYPES>& GetElements(void) const { return i_elements;}
private:
ContainerMapList<OBJECT_TYPES> i_elements;
private:
ContainerMapList<OBJECT_TYPES> i_elements;
};
#endif

View File

@@ -21,54 +21,54 @@ namespace acore
{
/* ContainerMapList Helpers */
// count functions
template<class SPECIFIC_TYPE> size_t Count(const ContainerMapList<SPECIFIC_TYPE> &elements, SPECIFIC_TYPE* /*fake*/)
template<class SPECIFIC_TYPE> size_t Count(const ContainerMapList<SPECIFIC_TYPE>& elements, SPECIFIC_TYPE* /*fake*/)
{
return elements._element.getSize();
}
template<class SPECIFIC_TYPE> size_t Count(const ContainerMapList<TypeNull> &/*elements*/, SPECIFIC_TYPE* /*fake*/)
template<class SPECIFIC_TYPE> size_t Count(const ContainerMapList<TypeNull>& /*elements*/, SPECIFIC_TYPE* /*fake*/)
{
return 0;
}
template<class SPECIFIC_TYPE, class T> size_t Count(const ContainerMapList<T> &/*elements*/, SPECIFIC_TYPE* /*fake*/)
template<class SPECIFIC_TYPE, class T> size_t Count(const ContainerMapList<T>& /*elements*/, SPECIFIC_TYPE* /*fake*/)
{
return 0;
}
template<class SPECIFIC_TYPE, class T> size_t Count(const ContainerMapList<TypeList<SPECIFIC_TYPE, T> >&elements, SPECIFIC_TYPE* fake)
template<class SPECIFIC_TYPE, class T> size_t Count(const ContainerMapList<TypeList<SPECIFIC_TYPE, T> >& elements, SPECIFIC_TYPE* fake)
{
return Count(elements._elements, fake);
}
template<class SPECIFIC_TYPE, class H, class T> size_t Count(const ContainerMapList<TypeList<H, T> >&elements, SPECIFIC_TYPE* fake)
template<class SPECIFIC_TYPE, class H, class T> size_t Count(const ContainerMapList<TypeList<H, T> >& elements, SPECIFIC_TYPE* fake)
{
return Count(elements._TailElements, fake);
}
// non-const insert functions
template<class SPECIFIC_TYPE> SPECIFIC_TYPE* Insert(ContainerMapList<SPECIFIC_TYPE> &elements, SPECIFIC_TYPE *obj)
template<class SPECIFIC_TYPE> SPECIFIC_TYPE* Insert(ContainerMapList<SPECIFIC_TYPE>& elements, SPECIFIC_TYPE* obj)
{
//elements._element[hdl] = obj;
obj->AddToGrid(elements._element);
return obj;
}
template<class SPECIFIC_TYPE> SPECIFIC_TYPE* Insert(ContainerMapList<TypeNull> &/*elements*/, SPECIFIC_TYPE * /*obj*/)
template<class SPECIFIC_TYPE> SPECIFIC_TYPE* Insert(ContainerMapList<TypeNull>& /*elements*/, SPECIFIC_TYPE* /*obj*/)
{
return NULL;
}
// this is a missed
template<class SPECIFIC_TYPE, class T> SPECIFIC_TYPE* Insert(ContainerMapList<T> &/*elements*/, SPECIFIC_TYPE * /*obj*/)
template<class SPECIFIC_TYPE, class T> SPECIFIC_TYPE* Insert(ContainerMapList<T>& /*elements*/, SPECIFIC_TYPE* /*obj*/)
{
return NULL; // a missed
}
// Recursion
template<class SPECIFIC_TYPE, class H, class T> SPECIFIC_TYPE* Insert(ContainerMapList<TypeList<H, T> >&elements, SPECIFIC_TYPE *obj)
template<class SPECIFIC_TYPE, class H, class T> SPECIFIC_TYPE* Insert(ContainerMapList<TypeList<H, T> >& elements, SPECIFIC_TYPE* obj)
{
SPECIFIC_TYPE* t= Insert(elements._elements, obj);
SPECIFIC_TYPE* t = Insert(elements._elements, obj);
return (t != NULL ? t : Insert(elements._TailElements, obj));
}

View File

@@ -47,48 +47,48 @@ namespace acore
// }
// non-const find functions
template<class SPECIFIC_TYPE> CountedPtr<SPECIFIC_TYPE>& Find(ContainerMapList<SPECIFIC_TYPE> &elements, OBJECT_HANDLE hdl, CountedPtr<SPECIFIC_TYPE>* /*fake*/)
template<class SPECIFIC_TYPE> CountedPtr<SPECIFIC_TYPE>& Find(ContainerMapList<SPECIFIC_TYPE>& elements, OBJECT_HANDLE hdl, CountedPtr<SPECIFIC_TYPE>* /*fake*/)
{
typename std::map<OBJECT_HANDLE, CountedPtr<SPECIFIC_TYPE> >::iterator iter = elements._element.find(hdl);
return (iter == elements._element.end() ? NullPtr<SPECIFIC_TYPE>((SPECIFIC_TYPE*)NULL) : iter->second);
};
template<class SPECIFIC_TYPE> CountedPtr<SPECIFIC_TYPE>& Find(ContainerMapList<TypeNull> &elements, OBJECT_HANDLE hdl, CountedPtr<SPECIFIC_TYPE>* /*fake*/)
template<class SPECIFIC_TYPE> CountedPtr<SPECIFIC_TYPE>& Find(ContainerMapList<TypeNull>& elements, OBJECT_HANDLE hdl, CountedPtr<SPECIFIC_TYPE>* /*fake*/)
{
return NullPtr<SPECIFIC_TYPE>((SPECIFIC_TYPE*)NULL);// terminate recursion
}
template<class SPECIFIC_TYPE, class T> CountedPtr<SPECIFIC_TYPE>& Find(ContainerMapList<T> &elements, OBJECT_HANDLE hdl, CountedPtr<SPECIFIC_TYPE>* /*fake*/)
template<class SPECIFIC_TYPE, class T> CountedPtr<SPECIFIC_TYPE>& Find(ContainerMapList<T>& elements, OBJECT_HANDLE hdl, CountedPtr<SPECIFIC_TYPE>* /*fake*/)
{
return NullPtr<SPECIFIC_TYPE>((SPECIFIC_TYPE*)NULL);// this is a missed
}
template<class SPECIFIC_TYPE, class H, class T> CountedPtr<SPECIFIC_TYPE>& Find(ContainerMapList<TypeList<H, T> >&elements, OBJECT_HANDLE hdl, CountedPtr<SPECIFIC_TYPE>* fake)
template<class SPECIFIC_TYPE, class H, class T> CountedPtr<SPECIFIC_TYPE>& Find(ContainerMapList<TypeList<H, T> >& elements, OBJECT_HANDLE hdl, CountedPtr<SPECIFIC_TYPE>* fake)
{
CountedPtr<SPECIFIC_TYPE> &t = Find(elements._elements, hdl, fake);
CountedPtr<SPECIFIC_TYPE>& t = Find(elements._elements, hdl, fake);
return (!t ? Find(elements._TailElements, hdl, fake) : t);
}
// const find functions
template<class SPECIFIC_TYPE> const CountedPtr<SPECIFIC_TYPE>& Find(const ContainerMapList<SPECIFIC_TYPE> &elements, OBJECT_HANDLE hdl, CountedPtr<SPECIFIC_TYPE>* /*fake*/)
template<class SPECIFIC_TYPE> const CountedPtr<SPECIFIC_TYPE>& Find(const ContainerMapList<SPECIFIC_TYPE>& elements, OBJECT_HANDLE hdl, CountedPtr<SPECIFIC_TYPE>* /*fake*/)
{
typename CountedPtr<SPECIFIC_TYPE>::iterator iter = elements._element.find(hdl);
return (iter == elements._element.end() ? NullPtr<SPECIFIC_TYPE>((SPECIFIC_TYPE*)NULL) : iter->second);
};
template<class SPECIFIC_TYPE> const CountedPtr<SPECIFIC_TYPE>& Find(const ContainerMapList<TypeNull> &elements, OBJECT_HANDLE hdl, CountedPtr<SPECIFIC_TYPE>* /*fake*/)
template<class SPECIFIC_TYPE> const CountedPtr<SPECIFIC_TYPE>& Find(const ContainerMapList<TypeNull>& elements, OBJECT_HANDLE hdl, CountedPtr<SPECIFIC_TYPE>* /*fake*/)
{
return NullPtr<SPECIFIC_TYPE>((SPECIFIC_TYPE*)NULL);
}
template<class SPECIFIC_TYPE, class T> const CountedPtr<SPECIFIC_TYPE>& Find(const ContainerMapList<T> &elements, OBJECT_HANDLE hdl, CountedPtr<SPECIFIC_TYPE>* /*fake*/)
template<class SPECIFIC_TYPE, class T> const CountedPtr<SPECIFIC_TYPE>& Find(const ContainerMapList<T>& elements, OBJECT_HANDLE hdl, CountedPtr<SPECIFIC_TYPE>* /*fake*/)
{
return NullPtr<SPECIFIC_TYPE>((SPECIFIC_TYPE*)NULL);
}
template<class SPECIFIC_TYPE, class H, class T> CountedPtr<SPECIFIC_TYPE>& Find(const ContainerMapList<TypeList<H, T> >&elements, OBJECT_HANDLE hdl, CountedPtr<SPECIFIC_TYPE>* fake)
template<class SPECIFIC_TYPE, class H, class T> CountedPtr<SPECIFIC_TYPE>& Find(const ContainerMapList<TypeList<H, T> >& elements, OBJECT_HANDLE hdl, CountedPtr<SPECIFIC_TYPE>* fake)
{
CountedPtr<SPECIFIC_TYPE> &t = Find(elements._elements, hdl, fake);
CountedPtr<SPECIFIC_TYPE>& t = Find(elements._elements, hdl, fake);
if (!t)
t = Find(elements._TailElement, hdl, fake);
@@ -96,32 +96,32 @@ namespace acore
}
// non-const insert functions
template<class SPECIFIC_TYPE> CountedPtr<SPECIFIC_TYPE>& Insert(ContainerMapList<SPECIFIC_TYPE> &elements, CountedPtr<SPECIFIC_TYPE> &obj, OBJECT_HANDLE hdl)
template<class SPECIFIC_TYPE> CountedPtr<SPECIFIC_TYPE>& Insert(ContainerMapList<SPECIFIC_TYPE>& elements, CountedPtr<SPECIFIC_TYPE>& obj, OBJECT_HANDLE hdl)
{
elements._element[hdl] = obj;
return obj;
};
template<class SPECIFIC_TYPE> CountedPtr<SPECIFIC_TYPE>& Insert(ContainerMapList<TypeNull> &elements, CountedPtr<SPECIFIC_TYPE> &obj, OBJECT_HANDLE hdl)
template<class SPECIFIC_TYPE> CountedPtr<SPECIFIC_TYPE>& Insert(ContainerMapList<TypeNull>& elements, CountedPtr<SPECIFIC_TYPE>& obj, OBJECT_HANDLE hdl)
{
return NullPtr<SPECIFIC_TYPE>((SPECIFIC_TYPE*)NULL);
}
// this is a missed
template<class SPECIFIC_TYPE, class T> CountedPtr<SPECIFIC_TYPE>& Insert(ContainerMapList<T> &elements, CountedPtr<SPECIFIC_TYPE> &obj, OBJECT_HANDLE hdl)
template<class SPECIFIC_TYPE, class T> CountedPtr<SPECIFIC_TYPE>& Insert(ContainerMapList<T>& elements, CountedPtr<SPECIFIC_TYPE>& obj, OBJECT_HANDLE hdl)
{
return NullPtr<SPECIFIC_TYPE>((SPECIFIC_TYPE*)NULL);// a missed
}
// Recursion
template<class SPECIFIC_TYPE, class H, class T> CountedPtr<SPECIFIC_TYPE>& Insert(ContainerMapList<TypeList<H, T> >&elements, CountedPtr<SPECIFIC_TYPE> &obj, OBJECT_HANDLE hdl)
template<class SPECIFIC_TYPE, class H, class T> CountedPtr<SPECIFIC_TYPE>& Insert(ContainerMapList<TypeList<H, T> >& elements, CountedPtr<SPECIFIC_TYPE>& obj, OBJECT_HANDLE hdl)
{
CountedPtr<SPECIFIC_TYPE> &t= Insert(elements._elements, obj, hdl);
CountedPtr<SPECIFIC_TYPE>& t = Insert(elements._elements, obj, hdl);
return (!t ? Insert(elements._TailElements, obj, hdl) : t);
}
// non-const remove method
template<class SPECIFIC_TYPE> bool Remove(ContainerMapList<SPECIFIC_TYPE> &elements, CountedPtr<SPECIFIC_TYPE> &obj, OBJECT_HANDLE hdl)
template<class SPECIFIC_TYPE> bool Remove(ContainerMapList<SPECIFIC_TYPE>& elements, CountedPtr<SPECIFIC_TYPE>& obj, OBJECT_HANDLE hdl)
{
typename std::map<OBJECT_HANDLE, CountedPtr<SPECIFIC_TYPE> >::iterator iter = elements._element.find(hdl);
if ( iter != elements._element.end() )
@@ -133,18 +133,18 @@ namespace acore
return false; // found... terminate the search
}
template<class SPECIFIC_TYPE> bool Remove(ContainerMapList<TypeNull> &elements, CountedPtr<SPECIFIC_TYPE> &obj, OBJECT_HANDLE hdl)
template<class SPECIFIC_TYPE> bool Remove(ContainerMapList<TypeNull>& elements, CountedPtr<SPECIFIC_TYPE>& obj, OBJECT_HANDLE hdl)
{
return false;
}
// this is a missed
template<class SPECIFIC_TYPE, class T> bool Remove(ContainerMapList<T> &elements, CountedPtr<SPECIFIC_TYPE> &obj, OBJECT_HANDLE hdl)
template<class SPECIFIC_TYPE, class T> bool Remove(ContainerMapList<T>& elements, CountedPtr<SPECIFIC_TYPE>& obj, OBJECT_HANDLE hdl)
{
return false;
}
template<class SPECIFIC_TYPE, class T, class H> bool Remove(ContainerMapList<TypeList<H, T> > &elements, CountedPtr<SPECIFIC_TYPE> &obj, OBJECT_HANDLE hdl)
template<class SPECIFIC_TYPE, class T, class H> bool Remove(ContainerMapList<TypeList<H, T> >& elements, CountedPtr<SPECIFIC_TYPE>& obj, OBJECT_HANDLE hdl)
{
// The head element is bad
bool t = Remove(elements._elements, obj, hdl);

View File

@@ -20,58 +20,58 @@
template<class T, class Y> class TypeContainerVisitor;
// visitor helper
template<class VISITOR, class TYPE_CONTAINER> void VisitorHelper(VISITOR &v, TYPE_CONTAINER &c)
template<class VISITOR, class TYPE_CONTAINER> void VisitorHelper(VISITOR& v, TYPE_CONTAINER& c)
{
v.Visit(c);
}
// terminate condition for container list
template<class VISITOR> void VisitorHelper(VISITOR &/*v*/, ContainerList<TypeNull> &/*c*/) { }
template<class VISITOR> void VisitorHelper(VISITOR& /*v*/, ContainerList<TypeNull>& /*c*/) { }
template<class VISITOR, class T> void VisitorHelper(VISITOR &v, ContainerList<T> &c)
template<class VISITOR, class T> void VisitorHelper(VISITOR& v, ContainerList<T>& c)
{
v.Visit(c._element);
}
// recursion for container list
template<class VISITOR, class H, class T> void VisitorHelper(VISITOR &v, ContainerList<TypeList<H, T> > &c)
template<class VISITOR, class H, class T> void VisitorHelper(VISITOR& v, ContainerList<TypeList<H, T> >& c)
{
VisitorHelper(v, c._elements);
VisitorHelper(v, c._TailElements);
}
// terminate condition container map list
template<class VISITOR> void VisitorHelper(VISITOR &/*v*/, ContainerMapList<TypeNull> &/*c*/) { }
template<class VISITOR> void VisitorHelper(VISITOR& /*v*/, ContainerMapList<TypeNull>& /*c*/) { }
template<class VISITOR, class T> void VisitorHelper(VISITOR &v, ContainerMapList<T> &c)
template<class VISITOR, class T> void VisitorHelper(VISITOR& v, ContainerMapList<T>& c)
{
v.Visit(c._element);
}
// recursion container map list
template<class VISITOR, class H, class T> void VisitorHelper(VISITOR &v, ContainerMapList<TypeList<H, T> > &c)
template<class VISITOR, class H, class T> void VisitorHelper(VISITOR& v, ContainerMapList<TypeList<H, T> >& c)
{
VisitorHelper(v, c._elements);
VisitorHelper(v, c._TailElements);
}
// array list
template<class VISITOR, class T> void VisitorHelper(VISITOR &v, ContainerArrayList<T> &c)
template<class VISITOR, class T> void VisitorHelper(VISITOR& v, ContainerArrayList<T>& c)
{
v.Visit(c._element);
}
template<class VISITOR> void VisitorHelper(VISITOR &/*v*/, ContainerArrayList<TypeNull> &/*c*/) { }
template<class VISITOR> void VisitorHelper(VISITOR& /*v*/, ContainerArrayList<TypeNull>& /*c*/) { }
// recursion
template<class VISITOR, class H, class T> void VisitorHelper(VISITOR &v, ContainerArrayList<TypeList<H, T> > &c)
template<class VISITOR, class H, class T> void VisitorHelper(VISITOR& v, ContainerArrayList<TypeList<H, T> >& c)
{
VisitorHelper(v, c._elements);
VisitorHelper(v, c._TailElements);
}
// for TypeMapContainer
template<class VISITOR, class OBJECT_TYPES> void VisitorHelper(VISITOR &v, TypeMapContainer<OBJECT_TYPES> &c)
template<class VISITOR, class OBJECT_TYPES> void VisitorHelper(VISITOR& v, TypeMapContainer<OBJECT_TYPES>& c)
{
VisitorHelper(v, c.GetElements());
}
@@ -79,21 +79,21 @@ template<class VISITOR, class OBJECT_TYPES> void VisitorHelper(VISITOR &v, TypeM
template<class VISITOR, class TYPE_CONTAINER>
class TypeContainerVisitor
{
public:
TypeContainerVisitor(VISITOR &v) : i_visitor(v) { }
public:
TypeContainerVisitor(VISITOR& v) : i_visitor(v) { }
void Visit(TYPE_CONTAINER &c)
{
VisitorHelper(i_visitor, c);
}
void Visit(TYPE_CONTAINER& c)
{
VisitorHelper(i_visitor, c);
}
void Visit(const TYPE_CONTAINER &c) const
{
VisitorHelper(i_visitor, c);
}
void Visit(const TYPE_CONTAINER& c) const
{
VisitorHelper(i_visitor, c);
}
private:
VISITOR &i_visitor;
private:
VISITOR& i_visitor;
};
#endif

View File

@@ -71,7 +71,7 @@ Log* Log::instance()
return &instance;
}
void Log::SetLogLevel(char *Level)
void Log::SetLogLevel(char* Level)
{
int32 NewLevel = atoi((char*)Level);
if (NewLevel < 0)
@@ -81,7 +81,7 @@ void Log::SetLogLevel(char *Level)
outString("LogLevel is %u", m_logLevel);
}
void Log::SetLogFileLevel(char *Level)
void Log::SetLogFileLevel(char* Level)
{
int32 NewLevel = atoi((char*)Level);
if (NewLevel < 0)
@@ -126,7 +126,7 @@ void Log::Initialize()
bool m_gmlog_timestamp = sConfigMgr->GetBoolDefault("GmLogTimestamp", false, false);
size_t dot_pos = m_gmlog_filename_format.find_last_of('.');
if (dot_pos!=m_gmlog_filename_format.npos)
if (dot_pos != m_gmlog_filename_format.npos)
{
if (m_gmlog_timestamp)
m_gmlog_filename_format.insert(dot_pos, m_logsTimestamp);
@@ -151,7 +151,7 @@ void Log::Initialize()
chatLogfile = openLogFile("ChatLogFile", "ChatLogTimestamp", "a");
sqlLogFile = openLogFile("SQLDriverLogFile", NULL, "a");
sqlDevLogFile = openLogFile("SQLDeveloperLogFile", NULL, "a");
miscLogFile = fopen((m_logsDir+"Misc.log").c_str(), "a");
miscLogFile = fopen((m_logsDir + "Misc.log").c_str(), "a");
// Main log file settings
m_logLevel = sConfigMgr->GetIntDefault("LogLevel", LOGL_NORMAL, false);
@@ -184,20 +184,20 @@ void Log::ReloadConfig()
FILE* Log::openLogFile(char const* configFileName, char const* configTimeStampFlag, char const* mode)
{
std::string logfn=sConfigMgr->GetStringDefault(configFileName, "", false);
std::string logfn = sConfigMgr->GetStringDefault(configFileName, "", false);
if (logfn.empty())
return NULL;
if (configTimeStampFlag && sConfigMgr->GetBoolDefault(configTimeStampFlag, false, false))
{
size_t dot_pos = logfn.find_last_of(".");
if (dot_pos!=logfn.npos)
if (dot_pos != logfn.npos)
logfn.insert(dot_pos, m_logsTimestamp);
else
logfn += m_logsTimestamp;
}
return fopen((m_logsDir+logfn).c_str(), mode);
return fopen((m_logsDir + logfn).c_str(), mode);
}
FILE* Log::openGmlogPerAccount(uint32 account)
@@ -220,7 +220,7 @@ void Log::outTimestamp(FILE* file)
// HH hour (2 digits 00-23)
// MM minutes (2 digits 00-59)
// SS seconds (2 digits 00-59)
fprintf(file, "%-4d-%02d-%02d %02d:%02d:%02d ", aTm->tm_year+1900, aTm->tm_mon+1, aTm->tm_mday, aTm->tm_hour, aTm->tm_min, aTm->tm_sec);
fprintf(file, "%-4d-%02d-%02d %02d:%02d:%02d ", aTm->tm_year + 1900, aTm->tm_mon + 1, aTm->tm_mday, aTm->tm_hour, aTm->tm_min, aTm->tm_sec);
}
void Log::InitColors(const std::string& str)
@@ -254,7 +254,7 @@ void Log::InitColors(const std::string& str)
void Log::SetColor(bool stdout_stream, ColorTypes color)
{
#if AC_PLATFORM == AC_PLATFORM_WINDOWS
#if AC_PLATFORM == AC_PLATFORM_WINDOWS
static WORD WinColorFG[Colors] =
{
0, // BLACK
@@ -265,41 +265,41 @@ void Log::SetColor(bool stdout_stream, ColorTypes color)
FOREGROUND_RED | FOREGROUND_BLUE, // MAGENTA
FOREGROUND_GREEN | FOREGROUND_BLUE, // CYAN
FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE, // WHITE
// YELLOW
// YELLOW
FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY,
// RED_BOLD
// RED_BOLD
FOREGROUND_RED | FOREGROUND_INTENSITY,
// GREEN_BOLD
// GREEN_BOLD
FOREGROUND_GREEN | FOREGROUND_INTENSITY,
FOREGROUND_BLUE | FOREGROUND_INTENSITY, // BLUE_BOLD
// MAGENTA_BOLD
// MAGENTA_BOLD
FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_INTENSITY,
// CYAN_BOLD
// CYAN_BOLD
FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY,
// WHITE_BOLD
// WHITE_BOLD
FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY
};
HANDLE hConsole = GetStdHandle(stdout_stream ? STD_OUTPUT_HANDLE : STD_ERROR_HANDLE );
SetConsoleTextAttribute(hConsole, WinColorFG[color]);
#else
#else
enum ANSITextAttr
{
TA_NORMAL=0,
TA_BOLD=1,
TA_BLINK=5,
TA_REVERSE=7
TA_NORMAL = 0,
TA_BOLD = 1,
TA_BLINK = 5,
TA_REVERSE = 7
};
enum ANSIFgTextAttr
{
FG_BLACK=30, FG_RED, FG_GREEN, FG_BROWN, FG_BLUE,
FG_BLACK = 30, FG_RED, FG_GREEN, FG_BROWN, FG_BLUE,
FG_MAGENTA, FG_CYAN, FG_WHITE, FG_YELLOW
};
enum ANSIBgTextAttr
{
BG_BLACK=40, BG_RED, BG_GREEN, BG_BROWN, BG_BLUE,
BG_BLACK = 40, BG_RED, BG_GREEN, BG_BROWN, BG_BLUE,
BG_MAGENTA, BG_CYAN, BG_WHITE
};
@@ -322,18 +322,18 @@ void Log::SetColor(bool stdout_stream, ColorTypes color)
FG_WHITE // LWHITE
};
fprintf((stdout_stream? stdout : stderr), "\x1b[%d%sm", UnixColorFG[color], (color >= YELLOW && color < Colors ? ";1" : ""));
#endif
fprintf((stdout_stream ? stdout : stderr), "\x1b[%d%sm", UnixColorFG[color], (color >= YELLOW && color < Colors ? ";1" : ""));
#endif
}
void Log::ResetColor(bool stdout_stream)
{
#if AC_PLATFORM == AC_PLATFORM_WINDOWS
#if AC_PLATFORM == AC_PLATFORM_WINDOWS
HANDLE hConsole = GetStdHandle(stdout_stream ? STD_OUTPUT_HANDLE : STD_ERROR_HANDLE );
SetConsoleTextAttribute(hConsole, FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED );
#else
#else
fprintf(( stdout_stream ? stdout : stderr ), "\x1b[0m");
#endif
#endif
}
std::string Log::GetTimestampStr()
@@ -348,7 +348,7 @@ std::string Log::GetTimestampStr()
// MM minutes (2 digits 00-59)
// SS seconds (2 digits 00-59)
char buf[20];
int ret = snprintf(buf, 20, "%04d-%02d-%02d_%02d-%02d-%02d", aTm.tm_year+1900, aTm.tm_mon+1, aTm.tm_mday, aTm.tm_hour, aTm.tm_min, aTm.tm_sec);
int ret = snprintf(buf, 20, "%04d-%02d-%02d_%02d-%02d-%02d", aTm.tm_year + 1900, aTm.tm_mon + 1, aTm.tm_mday, aTm.tm_hour, aTm.tm_min, aTm.tm_sec);
if (ret < 0)
{
@@ -358,7 +358,7 @@ std::string Log::GetTimestampStr()
return std::string(buf);
}
void Log::outDB(LogTypes type, const char * str)
void Log::outDB(LogTypes type, const char* str)
{
if(!str || std::string(str).empty() || type >= MAX_LOG_TYPES)
return;
@@ -367,10 +367,10 @@ void Log::outDB(LogTypes type, const char * str)
LoginDatabase.EscapeString(new_str);
LoginDatabase.PExecute("INSERT INTO logs (time, realm, type, string) "
"VALUES (" UI64FMTD ", %u, %u, '%s');", uint64(time(0)), realm, (uint32)type, new_str.c_str());
"VALUES (" UI64FMTD ", %u, %u, '%s');", uint64(time(0)), realm, (uint32)type, new_str.c_str());
}
void Log::outString(const char * str, ...)
void Log::outString(const char* str, ...)
{
if (!str)
return;
@@ -423,7 +423,7 @@ void Log::outString()
fflush(stdout);
}
void Log::outCrash(const char * err, ...)
void Log::outCrash(const char* err, ...)
{
if (!err)
return;
@@ -466,7 +466,7 @@ void Log::outCrash(const char * err, ...)
fflush(stderr);
}
void Log::outError(const char * err, ...)
void Log::outError(const char* err, ...)
{
if (!err)
return;
@@ -537,7 +537,7 @@ void Log::outSQLDriver(const char* str, ...)
fflush(stdout);
}
void Log::outErrorDb(const char * err, ...)
void Log::outErrorDb(const char* err, ...)
{
if (!err)
return;
@@ -592,7 +592,7 @@ void Log::outErrorDb(const char * err, ...)
fflush(stderr);
}
void Log::outBasic(const char * str, ...)
void Log::outBasic(const char* str, ...)
{
if (!str)
return;
@@ -636,7 +636,7 @@ void Log::outBasic(const char * str, ...)
fflush(stdout);
}
void Log::outDetail(const char * str, ...)
void Log::outDetail(const char* str, ...)
{
if (!str)
return;
@@ -708,7 +708,7 @@ void Log::outSQLDev(const char* str, ...)
fflush(stdout);
}
void Log::outDebug(DebugLogFilters f, const char * str, ...)
void Log::outDebug(DebugLogFilters f, const char* str, ...)
{
if (!(m_DebugLogMask & f))
return;
@@ -756,7 +756,7 @@ void Log::outDebug(DebugLogFilters f, const char * str, ...)
fflush(stdout);
}
void Log::outStaticDebug(const char * str, ...)
void Log::outStaticDebug(const char* str, ...)
{
if (!str)
return;
@@ -801,7 +801,7 @@ void Log::outStaticDebug(const char * str, ...)
fflush(stdout);
}
void Log::outStringInLine(const char * str, ...)
void Log::outStringInLine(const char* str, ...)
{
if (!str)
return;
@@ -820,7 +820,7 @@ void Log::outStringInLine(const char * str, ...)
}
}
void Log::outCommand(uint32 account, const char * str, ...)
void Log::outCommand(uint32 account, const char* str, ...)
{
if (!str)
return;
@@ -890,7 +890,7 @@ void Log::outCommand(uint32 account, const char * str, ...)
fflush(stdout);
}
void Log::outChar(const char * str, ...)
void Log::outChar(const char* str, ...)
{
if (!str)
return;
@@ -917,7 +917,7 @@ void Log::outChar(const char * str, ...)
}
}
void Log::outCharDump(const char * str, uint32 account_id, uint32 guid, const char * name)
void Log::outCharDump(const char* str, uint32 account_id, uint32 guid, const char* name)
{
FILE* file = NULL;
if (m_charLog_Dump_Separate)
@@ -933,14 +933,14 @@ void Log::outCharDump(const char * str, uint32 account_id, uint32 guid, const ch
if (file)
{
fprintf(file, "== START DUMP == (account: %u guid: %u name: %s )\n%s\n== END DUMP ==\n",
account_id, guid, name, str);
account_id, guid, name, str);
fflush(file);
if (m_charLog_Dump_Separate)
fclose(file);
}
}
void Log::outChat(const char * str, ...)
void Log::outChat(const char* str, ...)
{
if (!str)
return;
@@ -967,7 +967,7 @@ void Log::outChat(const char * str, ...)
}
}
void Log::outRemote(const char * str, ...)
void Log::outRemote(const char* str, ...)
{
if (!str)
return;
@@ -994,7 +994,7 @@ void Log::outRemote(const char * str, ...)
}
}
void Log::outMisc(const char * str, ...)
void Log::outMisc(const char* str, ...)
{
if (!str)
return;

View File

@@ -58,7 +58,7 @@ enum LogTypes
LOG_TYPE_CRASH = 9,
LOG_TYPE_CHAT = 10,
LOG_TYPE_PERF = 11,
LOG_TYPE_MULTITH= 12,
LOG_TYPE_MULTITH = 12,
MAX_LOG_TYPES
};
@@ -70,7 +70,7 @@ enum LogLevel
LOGL_DEBUG
};
const int LogLevels = int(LOGL_DEBUG)+1;
const int LogLevels = int(LOGL_DEBUG) + 1;
enum ColorTypes
{
@@ -91,110 +91,110 @@ enum ColorTypes
WHITE
};
const int Colors = int(WHITE)+1;
const int Colors = int(WHITE) + 1;
class Log
{
private:
Log();
~Log();
Log(Log const&) = delete;
Log(Log&&) = delete;
Log& operator=(Log const&) = delete;
Log& operator=(Log&&) = delete;
private:
Log();
~Log();
Log(Log const&) = delete;
Log(Log&&) = delete;
Log& operator=(Log const&) = delete;
Log& operator=(Log&&) = delete;
public:
static Log* instance();
void Initialize();
public:
static Log* instance();
void ReloadConfig();
void Initialize();
void InitColors(const std::string& init_str);
void SetColor(bool stdout_stream, ColorTypes color);
void ResetColor(bool stdout_stream);
void ReloadConfig();
void outDB(LogTypes type, const char * str);
void outString(const char * str, ...) ATTR_PRINTF(2, 3);
void outString();
void outStringInLine(const char * str, ...) ATTR_PRINTF(2, 3);
void outError(const char * err, ...) ATTR_PRINTF(2, 3);
void outCrash(const char * err, ...) ATTR_PRINTF(2, 3);
void outBasic(const char * str, ...) ATTR_PRINTF(2, 3);
void outDetail(const char * str, ...) ATTR_PRINTF(2, 3);
void outSQLDev(const char * str, ...) ATTR_PRINTF(2, 3);
void outDebug(DebugLogFilters f, const char* str, ...) ATTR_PRINTF(3, 4);
void outStaticDebug(const char * str, ...) ATTR_PRINTF(2, 3);
void outErrorDb(const char * str, ...) ATTR_PRINTF(2, 3);
void outChar(const char * str, ...) ATTR_PRINTF(2, 3);
void outCommand(uint32 account, const char * str, ...) ATTR_PRINTF(3, 4);
void outChat(const char * str, ...) ATTR_PRINTF(2, 3);
void outRemote(const char * str, ...) ATTR_PRINTF(2, 3);
void outSQLDriver(const char* str, ...) ATTR_PRINTF(2, 3);
void outMisc(const char * str, ...) ATTR_PRINTF(2, 3); // pussywizard
void outCharDump(const char * str, uint32 account_id, uint32 guid, const char * name);
void InitColors(const std::string& init_str);
void SetColor(bool stdout_stream, ColorTypes color);
void ResetColor(bool stdout_stream);
static void outTimestamp(FILE* file);
static std::string GetTimestampStr();
void outDB(LogTypes type, const char* str);
void outString(const char* str, ...) ATTR_PRINTF(2, 3);
void outString();
void outStringInLine(const char* str, ...) ATTR_PRINTF(2, 3);
void outError(const char* err, ...) ATTR_PRINTF(2, 3);
void outCrash(const char* err, ...) ATTR_PRINTF(2, 3);
void outBasic(const char* str, ...) ATTR_PRINTF(2, 3);
void outDetail(const char* str, ...) ATTR_PRINTF(2, 3);
void outSQLDev(const char* str, ...) ATTR_PRINTF(2, 3);
void outDebug(DebugLogFilters f, const char* str, ...) ATTR_PRINTF(3, 4);
void outStaticDebug(const char* str, ...) ATTR_PRINTF(2, 3);
void outErrorDb(const char* str, ...) ATTR_PRINTF(2, 3);
void outChar(const char* str, ...) ATTR_PRINTF(2, 3);
void outCommand(uint32 account, const char* str, ...) ATTR_PRINTF(3, 4);
void outChat(const char* str, ...) ATTR_PRINTF(2, 3);
void outRemote(const char* str, ...) ATTR_PRINTF(2, 3);
void outSQLDriver(const char* str, ...) ATTR_PRINTF(2, 3);
void outMisc(const char* str, ...) ATTR_PRINTF(2, 3); // pussywizard
void outCharDump(const char* str, uint32 account_id, uint32 guid, const char* name);
void SetLogLevel(char * Level);
void SetLogFileLevel(char * Level);
void SetSQLDriverQueryLogging(bool newStatus) { m_sqlDriverQueryLogging = newStatus; }
void SetRealmID(uint32 id) { realm = id; }
static void outTimestamp(FILE* file);
static std::string GetTimestampStr();
bool IsOutDebug() const { return m_logLevel > 2 || (m_logFileLevel > 2 && logfile); }
bool IsOutCharDump() const { return m_charLog_Dump; }
void SetLogLevel(char* Level);
void SetLogFileLevel(char* Level);
void SetSQLDriverQueryLogging(bool newStatus) { m_sqlDriverQueryLogging = newStatus; }
void SetRealmID(uint32 id) { realm = id; }
bool GetLogDB() const { return m_enableLogDB; }
void SetLogDB(bool enable) { m_enableLogDB = enable; }
bool GetSQLDriverQueryLogging() const { return m_sqlDriverQueryLogging; }
private:
FILE* openLogFile(char const* configFileName, char const* configTimeStampFlag, char const* mode);
FILE* openGmlogPerAccount(uint32 account);
bool IsOutDebug() const { return m_logLevel > 2 || (m_logFileLevel > 2 && logfile); }
bool IsOutCharDump() const { return m_charLog_Dump; }
FILE* raLogfile;
FILE* logfile;
FILE* gmLogfile;
FILE* charLogfile;
FILE* dberLogfile;
FILE* chatLogfile;
FILE* sqlLogFile;
FILE* sqlDevLogFile;
FILE* miscLogFile;
bool GetLogDB() const { return m_enableLogDB; }
void SetLogDB(bool enable) { m_enableLogDB = enable; }
bool GetSQLDriverQueryLogging() const { return m_sqlDriverQueryLogging; }
private:
FILE* openLogFile(char const* configFileName, char const* configTimeStampFlag, char const* mode);
FILE* openGmlogPerAccount(uint32 account);
// cache values for after initilization use (like gm log per account case)
std::string m_logsDir;
std::string m_logsTimestamp;
FILE* raLogfile;
FILE* logfile;
FILE* gmLogfile;
FILE* charLogfile;
FILE* dberLogfile;
FILE* chatLogfile;
FILE* sqlLogFile;
FILE* sqlDevLogFile;
FILE* miscLogFile;
// gm log control
bool m_gmlog_per_account;
std::string m_gmlog_filename_format;
// cache values for after initilization use (like gm log per account case)
std::string m_logsDir;
std::string m_logsTimestamp;
bool m_enableLogDB;
uint32 realm;
// gm log control
bool m_gmlog_per_account;
std::string m_gmlog_filename_format;
// log coloring
bool m_colored;
ColorTypes m_colors[4];
bool m_enableLogDB;
uint32 realm;
// log levels:
// false: errors only, true: full query logging
bool m_sqlDriverQueryLogging;
// log coloring
bool m_colored;
ColorTypes m_colors[4];
// log levels:
// 0 minimum/string, 1 basic/error, 2 detail, 3 full/debug
uint8 m_dbLogLevel;
uint8 m_logLevel;
uint8 m_logFileLevel;
bool m_dbChar;
bool m_dbRA;
bool m_dbGM;
bool m_dbChat;
bool m_charLog_Dump;
bool m_charLog_Dump_Separate;
std::string m_dumpsDir;
// log levels:
// false: errors only, true: full query logging
bool m_sqlDriverQueryLogging;
DebugLogFilters m_DebugLogMask;
// log levels:
// 0 minimum/string, 1 basic/error, 2 detail, 3 full/debug
uint8 m_dbLogLevel;
uint8 m_logLevel;
uint8 m_logFileLevel;
bool m_dbChar;
bool m_dbRA;
bool m_dbGM;
bool m_dbChat;
bool m_charLog_Dump;
bool m_charLog_Dump_Separate;
std::string m_dumpsDir;
DebugLogFilters m_DebugLogMask;
};
#define sLog Log::instance()

View File

@@ -12,7 +12,7 @@
#include <sstream>
ByteBufferPositionException::ByteBufferPositionException(bool add, size_t pos,
size_t size, size_t valueSize)
size_t size, size_t valueSize)
{
std::ostringstream ss;
@@ -24,7 +24,7 @@ ByteBufferPositionException::ByteBufferPositionException(bool add, size_t pos,
}
ByteBufferSourceException::ByteBufferSourceException(size_t pos, size_t size,
size_t valueSize)
size_t valueSize)
{
std::ostringstream ss;

View File

@@ -27,7 +27,7 @@ public:
char const* what() const throw() { return msg_.c_str(); }
protected:
std::string & message() throw() { return msg_; }
std::string& message() throw() { return msg_; }
private:
std::string msg_;
@@ -51,466 +51,466 @@ public:
class ByteBuffer
{
public:
const static size_t DEFAULT_SIZE = 0x1000;
public:
const static size_t DEFAULT_SIZE = 0x1000;
// constructor
ByteBuffer() : _rpos(0), _wpos(0)
// constructor
ByteBuffer() : _rpos(0), _wpos(0)
{
_storage.reserve(DEFAULT_SIZE);
}
ByteBuffer(size_t reserve) : _rpos(0), _wpos(0)
{
_storage.reserve(reserve);
}
// copy constructor
ByteBuffer(const ByteBuffer& buf) : _rpos(buf._rpos), _wpos(buf._wpos),
_storage(buf._storage)
{
}
/* requried as of C++ 11 */
#if __cplusplus >= 201103L
ByteBuffer(ByteBuffer&&) = default;
ByteBuffer& operator=(const ByteBuffer&) = default;
ByteBuffer& operator=(ByteBuffer&&) = default;
#endif
void clear()
{
_storage.clear();
_rpos = _wpos = 0;
}
template <typename T> void append(T value)
{
EndianConvert(value);
append((uint8*)&value, sizeof(value));
}
template <typename T> void put(size_t pos, T value)
{
EndianConvert(value);
put(pos, (uint8*)&value, sizeof(value));
}
ByteBuffer& operator<<(uint8 value)
{
append<uint8>(value);
return *this;
}
ByteBuffer& operator<<(uint16 value)
{
append<uint16>(value);
return *this;
}
ByteBuffer& operator<<(uint32 value)
{
append<uint32>(value);
return *this;
}
ByteBuffer& operator<<(uint64 value)
{
append<uint64>(value);
return *this;
}
// signed as in 2e complement
ByteBuffer& operator<<(int8 value)
{
append<int8>(value);
return *this;
}
ByteBuffer& operator<<(int16 value)
{
append<int16>(value);
return *this;
}
ByteBuffer& operator<<(int32 value)
{
append<int32>(value);
return *this;
}
ByteBuffer& operator<<(int64 value)
{
append<int64>(value);
return *this;
}
// floating points
ByteBuffer& operator<<(float value)
{
append<float>(value);
return *this;
}
ByteBuffer& operator<<(double value)
{
append<double>(value);
return *this;
}
ByteBuffer& operator<<(const std::string& value)
{
if (size_t len = value.length())
append((uint8 const*)value.c_str(), len);
append((uint8)0);
return *this;
}
ByteBuffer& operator<<(const char* str)
{
if (size_t len = (str ? strlen(str) : 0))
append((uint8 const*)str, len);
append((uint8)0);
return *this;
}
ByteBuffer& operator>>(bool& value)
{
value = (read<char>() > 0);
return *this;
}
ByteBuffer& operator>>(uint8& value)
{
value = read<uint8>();
return *this;
}
ByteBuffer& operator>>(uint16& value)
{
value = read<uint16>();
return *this;
}
ByteBuffer& operator>>(uint32& value)
{
value = read<uint32>();
return *this;
}
ByteBuffer& operator>>(uint64& value)
{
value = read<uint64>();
return *this;
}
//signed as in 2e complement
ByteBuffer& operator>>(int8& value)
{
value = read<int8>();
return *this;
}
ByteBuffer& operator>>(int16& value)
{
value = read<int16>();
return *this;
}
ByteBuffer& operator>>(int32& value)
{
value = read<int32>();
return *this;
}
ByteBuffer& operator>>(int64& value)
{
value = read<int64>();
return *this;
}
ByteBuffer& operator>>(float& value)
{
value = read<float>();
if (!myisfinite(value))
{
_storage.reserve(DEFAULT_SIZE);
value = 0.0f;
//throw ByteBufferException();
}
return *this;
}
ByteBuffer(size_t reserve) : _rpos(0), _wpos(0)
ByteBuffer& operator>>(double& value)
{
value = read<double>();
if (!myisfinite(value))
{
_storage.reserve(reserve);
value = 0.0f;
//throw ByteBufferException();
}
return *this;
}
// copy constructor
ByteBuffer(const ByteBuffer &buf) : _rpos(buf._rpos), _wpos(buf._wpos),
_storage(buf._storage)
ByteBuffer& operator>>(std::string& value)
{
value.clear();
while (rpos() < size()) // prevent crash at wrong string format in packet
{
char c = read<char>();
if (c == 0)
break;
value += c;
}
/* requried as of C++ 11 */
#if __cplusplus >= 201103L
ByteBuffer(ByteBuffer&&) = default;
ByteBuffer& operator=(const ByteBuffer&) = default;
ByteBuffer& operator=(ByteBuffer&&) = default;
#endif
return *this;
}
void clear()
{
_storage.clear();
_rpos = _wpos = 0;
}
uint8& operator[](size_t const pos)
{
if (pos >= size())
throw ByteBufferPositionException(false, pos, 1, size());
return _storage[pos];
}
template <typename T> void append(T value)
{
EndianConvert(value);
append((uint8 *)&value, sizeof(value));
}
uint8 const& operator[](size_t const pos) const
{
if (pos >= size())
throw ByteBufferPositionException(false, pos, 1, size());
return _storage[pos];
}
template <typename T> void put(size_t pos, T value)
{
EndianConvert(value);
put(pos, (uint8 *)&value, sizeof(value));
}
size_t rpos() const { return _rpos; }
ByteBuffer &operator<<(uint8 value)
{
append<uint8>(value);
return *this;
}
size_t rpos(size_t rpos_)
{
_rpos = rpos_;
return _rpos;
}
ByteBuffer &operator<<(uint16 value)
{
append<uint16>(value);
return *this;
}
void rfinish()
{
_rpos = wpos();
}
ByteBuffer &operator<<(uint32 value)
{
append<uint32>(value);
return *this;
}
size_t wpos() const { return _wpos; }
ByteBuffer &operator<<(uint64 value)
{
append<uint64>(value);
return *this;
}
size_t wpos(size_t wpos_)
{
_wpos = wpos_;
return _wpos;
}
// signed as in 2e complement
ByteBuffer &operator<<(int8 value)
{
append<int8>(value);
return *this;
}
template<typename T>
void read_skip() { read_skip(sizeof(T)); }
ByteBuffer &operator<<(int16 value)
{
append<int16>(value);
return *this;
}
void read_skip(size_t skip)
{
if (_rpos + skip > size())
throw ByteBufferPositionException(false, _rpos, skip, size());
_rpos += skip;
}
ByteBuffer &operator<<(int32 value)
{
append<int32>(value);
return *this;
}
template <typename T> T read()
{
T r = read<T>(_rpos);
_rpos += sizeof(T);
return r;
}
ByteBuffer &operator<<(int64 value)
{
append<int64>(value);
return *this;
}
template <typename T> T read(size_t pos) const
{
if (pos + sizeof(T) > size())
throw ByteBufferPositionException(false, pos, sizeof(T), size());
T val = *((T const*)&_storage[pos]);
EndianConvert(val);
return val;
}
// floating points
ByteBuffer &operator<<(float value)
{
append<float>(value);
return *this;
}
void read(uint8* dest, size_t len)
{
if (_rpos + len > size())
throw ByteBufferPositionException(false, _rpos, len, size());
std::memcpy(dest, &_storage[_rpos], len);
_rpos += len;
}
ByteBuffer &operator<<(double value)
{
append<double>(value);
return *this;
}
void readPackGUID(uint64& guid)
{
if (rpos() + 1 > size())
throw ByteBufferPositionException(false, _rpos, 1, size());
ByteBuffer &operator<<(const std::string &value)
{
if (size_t len = value.length())
append((uint8 const*)value.c_str(), len);
append((uint8)0);
return *this;
}
guid = 0;
ByteBuffer &operator<<(const char *str)
{
if (size_t len = (str ? strlen(str) : 0))
append((uint8 const*)str, len);
append((uint8)0);
return *this;
}
uint8 guidmark = 0;
(*this) >> guidmark;
ByteBuffer &operator>>(bool &value)
for (int i = 0; i < 8; ++i)
{
value = (read<char>() > 0);
return *this;
}
ByteBuffer &operator>>(uint8 &value)
{
value = read<uint8>();
return *this;
}
ByteBuffer &operator>>(uint16 &value)
{
value = read<uint16>();
return *this;
}
ByteBuffer &operator>>(uint32 &value)
{
value = read<uint32>();
return *this;
}
ByteBuffer &operator>>(uint64 &value)
{
value = read<uint64>();
return *this;
}
//signed as in 2e complement
ByteBuffer &operator>>(int8 &value)
{
value = read<int8>();
return *this;
}
ByteBuffer &operator>>(int16 &value)
{
value = read<int16>();
return *this;
}
ByteBuffer &operator>>(int32 &value)
{
value = read<int32>();
return *this;
}
ByteBuffer &operator>>(int64 &value)
{
value = read<int64>();
return *this;
}
ByteBuffer &operator>>(float &value)
{
value = read<float>();
if (!myisfinite(value))
if (guidmark & (uint8(1) << i))
{
value = 0.0f;
//throw ByteBufferException();
}
return *this;
}
if (rpos() + 1 > size())
throw ByteBufferPositionException(false, _rpos, 1, size());
ByteBuffer &operator>>(double &value)
{
value = read<double>();
if (!myisfinite(value))
{
value = 0.0f;
//throw ByteBufferException();
}
return *this;
}
ByteBuffer &operator>>(std::string& value)
{
value.clear();
while (rpos() < size()) // prevent crash at wrong string format in packet
{
char c = read<char>();
if (c == 0)
break;
value += c;
}
return *this;
}
uint8& operator[](size_t const pos)
{
if (pos >= size())
throw ByteBufferPositionException(false, pos, 1, size());
return _storage[pos];
}
uint8 const& operator[](size_t const pos) const
{
if (pos >= size())
throw ByteBufferPositionException(false, pos, 1, size());
return _storage[pos];
}
size_t rpos() const { return _rpos; }
size_t rpos(size_t rpos_)
{
_rpos = rpos_;
return _rpos;
}
void rfinish()
{
_rpos = wpos();
}
size_t wpos() const { return _wpos; }
size_t wpos(size_t wpos_)
{
_wpos = wpos_;
return _wpos;
}
template<typename T>
void read_skip() { read_skip(sizeof(T)); }
void read_skip(size_t skip)
{
if (_rpos + skip > size())
throw ByteBufferPositionException(false, _rpos, skip, size());
_rpos += skip;
}
template <typename T> T read()
{
T r = read<T>(_rpos);
_rpos += sizeof(T);
return r;
}
template <typename T> T read(size_t pos) const
{
if (pos + sizeof(T) > size())
throw ByteBufferPositionException(false, pos, sizeof(T), size());
T val = *((T const*)&_storage[pos]);
EndianConvert(val);
return val;
}
void read(uint8 *dest, size_t len)
{
if (_rpos + len > size())
throw ByteBufferPositionException(false, _rpos, len, size());
std::memcpy(dest, &_storage[_rpos], len);
_rpos += len;
}
void readPackGUID(uint64& guid)
{
if (rpos() + 1 > size())
throw ByteBufferPositionException(false, _rpos, 1, size());
guid = 0;
uint8 guidmark = 0;
(*this) >> guidmark;
for (int i = 0; i < 8; ++i)
{
if (guidmark & (uint8(1) << i))
{
if (rpos() + 1 > size())
throw ByteBufferPositionException(false, _rpos, 1, size());
uint8 bit;
(*this) >> bit;
guid |= (uint64(bit) << (i * 8));
}
uint8 bit;
(*this) >> bit;
guid |= (uint64(bit) << (i * 8));
}
}
}
uint32 ReadPackedTime()
uint32 ReadPackedTime()
{
uint32 packedDate = read<uint32>();
tm lt = tm();
lt.tm_min = packedDate & 0x3F;
lt.tm_hour = (packedDate >> 6) & 0x1F;
//lt.tm_wday = (packedDate >> 11) & 7;
lt.tm_mday = ((packedDate >> 14) & 0x3F) + 1;
lt.tm_mon = (packedDate >> 20) & 0xF;
lt.tm_year = ((packedDate >> 24) & 0x1F) + 100;
return uint32(mktime(&lt));
}
ByteBuffer& ReadPackedTime(uint32& time)
{
time = ReadPackedTime();
return *this;
}
uint8* contents()
{
if (_storage.empty())
throw ByteBufferException();
return &_storage[0];
}
const uint8* contents() const
{
if (_storage.empty())
throw ByteBufferException();
return &_storage[0];
}
size_t size() const { return _storage.size(); }
bool empty() const { return _storage.empty(); }
void resize(size_t newsize)
{
_storage.resize(newsize, 0);
_rpos = 0;
_wpos = size();
}
void reserve(size_t ressize)
{
if (ressize > size())
_storage.reserve(ressize);
}
void append(const char* src, size_t cnt)
{
return append((const uint8*)src, cnt);
}
template<class T> void append(const T* src, size_t cnt)
{
return append((const uint8*)src, cnt * sizeof(T));
}
void append(const uint8* src, size_t cnt)
{
if (!cnt)
throw ByteBufferSourceException(_wpos, size(), cnt);
if (!src)
throw ByteBufferSourceException(_wpos, size(), cnt);
ASSERT(size() < 10000000);
size_t newsize = _wpos + cnt;
if (_storage.capacity() < newsize) // pussywizard
{
uint32 packedDate = read<uint32>();
tm lt = tm();
lt.tm_min = packedDate & 0x3F;
lt.tm_hour = (packedDate >> 6) & 0x1F;
//lt.tm_wday = (packedDate >> 11) & 7;
lt.tm_mday = ((packedDate >> 14) & 0x3F) + 1;
lt.tm_mon = (packedDate >> 20) & 0xF;
lt.tm_year = ((packedDate >> 24) & 0x1F) + 100;
return uint32(mktime(&lt));
if (newsize < 100)
_storage.reserve(300);
else if (newsize < 750)
_storage.reserve(2500);
else if (newsize < 6000)
_storage.reserve(10000);
else
_storage.reserve(400000);
}
ByteBuffer& ReadPackedTime(uint32& time)
if (_storage.size() < newsize)
_storage.resize(newsize);
memcpy(&_storage[_wpos], src, cnt);
_wpos = newsize;
}
void append(const ByteBuffer& buffer)
{
if (buffer.wpos())
append(buffer.contents(), buffer.wpos());
}
// can be used in SMSG_MONSTER_MOVE opcode
void appendPackXYZ(float x, float y, float z)
{
uint32 packed = 0;
packed |= ((int)(x / 0.25f) & 0x7FF);
packed |= ((int)(y / 0.25f) & 0x7FF) << 11;
packed |= ((int)(z / 0.25f) & 0x3FF) << 22;
*this << packed;
}
void appendPackGUID(uint64 guid)
{
uint8 packGUID[8 + 1];
packGUID[0] = 0;
size_t size = 1;
for (uint8 i = 0; guid != 0; ++i)
{
time = ReadPackedTime();
return *this;
}
uint8 * contents()
{
if (_storage.empty())
throw ByteBufferException();
return &_storage[0];
}
const uint8 *contents() const
{
if (_storage.empty())
throw ByteBufferException();
return &_storage[0];
}
size_t size() const { return _storage.size(); }
bool empty() const { return _storage.empty(); }
void resize(size_t newsize)
{
_storage.resize(newsize, 0);
_rpos = 0;
_wpos = size();
}
void reserve(size_t ressize)
{
if (ressize > size())
_storage.reserve(ressize);
}
void append(const char *src, size_t cnt)
{
return append((const uint8 *)src, cnt);
}
template<class T> void append(const T *src, size_t cnt)
{
return append((const uint8 *)src, cnt * sizeof(T));
}
void append(const uint8 *src, size_t cnt)
{
if (!cnt)
throw ByteBufferSourceException(_wpos, size(), cnt);
if (!src)
throw ByteBufferSourceException(_wpos, size(), cnt);
ASSERT(size() < 10000000);
size_t newsize = _wpos + cnt;
if (_storage.capacity() < newsize) // pussywizard
if (guid & 0xFF)
{
if (newsize < 100)
_storage.reserve(300);
else if (newsize < 750)
_storage.reserve(2500);
else if (newsize < 6000)
_storage.reserve(10000);
else
_storage.reserve(400000);
packGUID[0] |= uint8(1 << i);
packGUID[size] = uint8(guid & 0xFF);
++size;
}
if (_storage.size() < newsize)
_storage.resize(newsize);
memcpy(&_storage[_wpos], src, cnt);
_wpos = newsize;
guid >>= 8;
}
append(packGUID, size);
}
void append(const ByteBuffer& buffer)
{
if (buffer.wpos())
append(buffer.contents(), buffer.wpos());
}
void AppendPackedTime(time_t time)
{
tm lt;
localtime_r(&time, &lt);
append<uint32>((lt.tm_year - 100) << 24 | lt.tm_mon << 20 | (lt.tm_mday - 1) << 14 | lt.tm_wday << 11 | lt.tm_hour << 6 | lt.tm_min);
}
// can be used in SMSG_MONSTER_MOVE opcode
void appendPackXYZ(float x, float y, float z)
{
uint32 packed = 0;
packed |= ((int)(x / 0.25f) & 0x7FF);
packed |= ((int)(y / 0.25f) & 0x7FF) << 11;
packed |= ((int)(z / 0.25f) & 0x3FF) << 22;
*this << packed;
}
void put(size_t pos, const uint8* src, size_t cnt)
{
if (pos + cnt > size())
throw ByteBufferPositionException(true, pos, cnt, size());
void appendPackGUID(uint64 guid)
{
uint8 packGUID[8+1];
packGUID[0] = 0;
size_t size = 1;
for (uint8 i = 0;guid != 0;++i)
{
if (guid & 0xFF)
{
packGUID[0] |= uint8(1 << i);
packGUID[size] = uint8(guid & 0xFF);
++size;
}
if (!src)
throw ByteBufferSourceException(_wpos, size(), cnt);
guid >>= 8;
}
append(packGUID, size);
}
std::memcpy(&_storage[pos], src, cnt);
}
void AppendPackedTime(time_t time)
{
tm lt;
localtime_r(&time, &lt);
append<uint32>((lt.tm_year - 100) << 24 | lt.tm_mon << 20 | (lt.tm_mday - 1) << 14 | lt.tm_wday << 11 | lt.tm_hour << 6 | lt.tm_min);
}
void hexlike(bool outString = false) const;
void put(size_t pos, const uint8 *src, size_t cnt)
{
if (pos + cnt > size())
throw ByteBufferPositionException(true, pos, cnt, size());
if (!src)
throw ByteBufferSourceException(_wpos, size(), cnt);
std::memcpy(&_storage[pos], src, cnt);
}
void hexlike(bool outString = false) const;
protected:
size_t _rpos, _wpos;
std::vector<uint8> _storage;
protected:
size_t _rpos, _wpos;
std::vector<uint8> _storage;
};
template <typename T>
inline ByteBuffer &operator<<(ByteBuffer &b, std::vector<T> v)
inline ByteBuffer& operator<<(ByteBuffer& b, std::vector<T> v)
{
b << (uint32)v.size();
for (typename std::vector<T>::iterator i = v.begin(); i != v.end(); ++i)
@@ -521,7 +521,7 @@ inline ByteBuffer &operator<<(ByteBuffer &b, std::vector<T> v)
}
template <typename T>
inline ByteBuffer &operator>>(ByteBuffer &b, std::vector<T> &v)
inline ByteBuffer& operator>>(ByteBuffer& b, std::vector<T>& v)
{
uint32 vsize;
b >> vsize;
@@ -536,7 +536,7 @@ inline ByteBuffer &operator>>(ByteBuffer &b, std::vector<T> &v)
}
template <typename T>
inline ByteBuffer &operator<<(ByteBuffer &b, std::list<T> v)
inline ByteBuffer& operator<<(ByteBuffer& b, std::list<T> v)
{
b << (uint32)v.size();
for (typename std::list<T>::iterator i = v.begin(); i != v.end(); ++i)
@@ -547,7 +547,7 @@ inline ByteBuffer &operator<<(ByteBuffer &b, std::list<T> v)
}
template <typename T>
inline ByteBuffer &operator>>(ByteBuffer &b, std::list<T> &v)
inline ByteBuffer& operator>>(ByteBuffer& b, std::list<T>& v)
{
uint32 vsize;
b >> vsize;
@@ -562,7 +562,7 @@ inline ByteBuffer &operator>>(ByteBuffer &b, std::list<T> &v)
}
template <typename K, typename V>
inline ByteBuffer &operator<<(ByteBuffer &b, std::map<K, V> &m)
inline ByteBuffer& operator<<(ByteBuffer& b, std::map<K, V>& m)
{
b << (uint32)m.size();
for (typename std::map<K, V>::iterator i = m.begin(); i != m.end(); ++i)
@@ -573,7 +573,7 @@ inline ByteBuffer &operator<<(ByteBuffer &b, std::map<K, V> &m)
}
template <typename K, typename V>
inline ByteBuffer &operator>>(ByteBuffer &b, std::map<K, V> &m)
inline ByteBuffer& operator>>(ByteBuffer& b, std::map<K, V>& m)
{
uint32 msize;
b >> msize;

View File

@@ -12,34 +12,34 @@
class WorldPacket : public ByteBuffer
{
public:
// just container for later use
WorldPacket() : ByteBuffer(0), m_opcode(0)
{
}
explicit WorldPacket(uint16 opcode, size_t res=200) : ByteBuffer(res), m_opcode(opcode) { }
// copy constructor
WorldPacket(const WorldPacket &packet) : ByteBuffer(packet), m_opcode(packet.m_opcode)
{
}
/* requried as of C++ 11 */
#if __cplusplus >= 201103L
WorldPacket(WorldPacket&&) = default;
WorldPacket& operator=(const WorldPacket&) = default;
WorldPacket& operator=(WorldPacket&&) = default;
#endif
public:
// just container for later use
WorldPacket() : ByteBuffer(0), m_opcode(0)
{
}
explicit WorldPacket(uint16 opcode, size_t res = 200) : ByteBuffer(res), m_opcode(opcode) { }
// copy constructor
WorldPacket(const WorldPacket& packet) : ByteBuffer(packet), m_opcode(packet.m_opcode)
{
}
/* requried as of C++ 11 */
#if __cplusplus >= 201103L
WorldPacket(WorldPacket&&) = default;
WorldPacket& operator=(const WorldPacket&) = default;
WorldPacket& operator=(WorldPacket&&) = default;
#endif
void Initialize(uint16 opcode, size_t newres=200)
{
clear();
_storage.reserve(newres);
m_opcode = opcode;
}
void Initialize(uint16 opcode, size_t newres = 200)
{
clear();
_storage.reserve(newres);
m_opcode = opcode;
}
uint16 GetOpcode() const { return m_opcode; }
void SetOpcode(uint16 opcode) { m_opcode = opcode; }
uint16 GetOpcode() const { return m_opcode; }
void SetOpcode(uint16 opcode) { m_opcode = opcode; }
protected:
uint16 m_opcode;
protected:
uint16 m_opcode;
};
#endif

View File

@@ -23,277 +23,277 @@ typedef ACE_Future<PreparedQueryResult> PreparedQueryResultFuture;
template <typename Result, typename ParamType, bool chain = false>
class QueryCallback
{
public:
QueryCallback() : _param(), _stage(chain ? 0 : CALLBACK_STAGE_INVALID) {}
public:
QueryCallback() : _param(), _stage(chain ? 0 : CALLBACK_STAGE_INVALID) {}
//! The parameter of this function should be a resultset returned from either .AsyncQuery or .AsyncPQuery
void SetFutureResult(ACE_Future<Result> value)
{
_result = value;
}
//! The parameter of this function should be a resultset returned from either .AsyncQuery or .AsyncPQuery
void SetFutureResult(ACE_Future<Result> value)
{
_result = value;
}
ACE_Future<Result> GetFutureResult()
{
return _result;
}
ACE_Future<Result> GetFutureResult()
{
return _result;
}
int IsReady()
{
return _result.ready();
}
int IsReady()
{
return _result.ready();
}
void GetResult(Result& res)
{
_result.get(res);
}
void GetResult(Result& res)
{
_result.get(res);
}
void FreeResult()
{
_result.cancel();
}
void FreeResult()
{
_result.cancel();
}
void SetParam(ParamType value)
{
_param = value;
}
void SetParam(ParamType value)
{
_param = value;
}
ParamType GetParam()
{
return _param;
}
ParamType GetParam()
{
return _param;
}
//! Resets the stage of the callback chain
void ResetStage()
{
if (!chain)
return;
//! Resets the stage of the callback chain
void ResetStage()
{
if (!chain)
return;
_stage = 0;
}
_stage = 0;
}
//! Advances the callback chain to the next stage, so upper level code can act on its results accordingly
void NextStage()
{
if (!chain)
return;
//! Advances the callback chain to the next stage, so upper level code can act on its results accordingly
void NextStage()
{
if (!chain)
return;
++_stage;
}
++_stage;
}
//! Returns the callback stage (or CALLBACK_STAGE_INVALID if invalid)
uint8 GetStage()
{
return _stage;
}
//! Returns the callback stage (or CALLBACK_STAGE_INVALID if invalid)
uint8 GetStage()
{
return _stage;
}
//! Resets all underlying variables (param, result and stage)
void Reset()
{
SetParam(NULL);
FreeResult();
ResetStage();
}
//! Resets all underlying variables (param, result and stage)
void Reset()
{
SetParam(NULL);
FreeResult();
ResetStage();
}
private:
ACE_Future<Result> _result;
ParamType _param;
uint8 _stage;
private:
ACE_Future<Result> _result;
ParamType _param;
uint8 _stage;
};
template <typename Result, typename ParamType1, typename ParamType2, bool chain = false>
class QueryCallback_2
{
public:
QueryCallback_2() : _stage(chain ? 0 : CALLBACK_STAGE_INVALID) {}
public:
QueryCallback_2() : _stage(chain ? 0 : CALLBACK_STAGE_INVALID) {}
//! The parameter of this function should be a resultset returned from either .AsyncQuery or .AsyncPQuery
void SetFutureResult(ACE_Future<Result> value)
{
_result = value;
}
//! The parameter of this function should be a resultset returned from either .AsyncQuery or .AsyncPQuery
void SetFutureResult(ACE_Future<Result> value)
{
_result = value;
}
ACE_Future<Result> GetFutureResult()
{
return _result;
}
ACE_Future<Result> GetFutureResult()
{
return _result;
}
int IsReady()
{
return _result.ready();
}
int IsReady()
{
return _result.ready();
}
void GetResult(Result& res)
{
_result.get(res);
}
void GetResult(Result& res)
{
_result.get(res);
}
void FreeResult()
{
_result.cancel();
}
void FreeResult()
{
_result.cancel();
}
void SetFirstParam(ParamType1 value)
{
_param_1 = value;
}
void SetFirstParam(ParamType1 value)
{
_param_1 = value;
}
void SetSecondParam(ParamType2 value)
{
_param_2 = value;
}
void SetSecondParam(ParamType2 value)
{
_param_2 = value;
}
ParamType1 GetFirstParam()
{
return _param_1;
}
ParamType1 GetFirstParam()
{
return _param_1;
}
ParamType2 GetSecondParam()
{
return _param_2;
}
ParamType2 GetSecondParam()
{
return _param_2;
}
//! Resets the stage of the callback chain
void ResetStage()
{
if (!chain)
return;
//! Resets the stage of the callback chain
void ResetStage()
{
if (!chain)
return;
_stage = 0;
}
_stage = 0;
}
//! Advances the callback chain to the next stage, so upper level code can act on its results accordingly
void NextStage()
{
if (!chain)
return;
//! Advances the callback chain to the next stage, so upper level code can act on its results accordingly
void NextStage()
{
if (!chain)
return;
++_stage;
}
++_stage;
}
//! Returns the callback stage (or CALLBACK_STAGE_INVALID if invalid)
uint8 GetStage()
{
return _stage;
}
//! Returns the callback stage (or CALLBACK_STAGE_INVALID if invalid)
uint8 GetStage()
{
return _stage;
}
//! Resets all underlying variables (param, result and stage)
void Reset()
{
SetFirstParam(0);
SetSecondParam(NULL);
FreeResult();
ResetStage();
}
//! Resets all underlying variables (param, result and stage)
void Reset()
{
SetFirstParam(0);
SetSecondParam(NULL);
FreeResult();
ResetStage();
}
private:
ACE_Future<Result> _result;
ParamType1 _param_1;
ParamType2 _param_2;
uint8 _stage;
private:
ACE_Future<Result> _result;
ParamType1 _param_1;
ParamType2 _param_2;
uint8 _stage;
};
template <typename Result, typename ParamType1, typename ParamType2, typename ParamType3, bool chain = false>
class QueryCallback_3
{
public:
QueryCallback_3() : _stage(chain ? 0 : CALLBACK_STAGE_INVALID) {}
public:
QueryCallback_3() : _stage(chain ? 0 : CALLBACK_STAGE_INVALID) {}
//! The parameter of this function should be a resultset returned from either .AsyncQuery or .AsyncPQuery
void SetFutureResult(ACE_Future<Result> value)
{
_result = value;
}
//! The parameter of this function should be a resultset returned from either .AsyncQuery or .AsyncPQuery
void SetFutureResult(ACE_Future<Result> value)
{
_result = value;
}
ACE_Future<Result> GetFutureResult()
{
return _result;
}
ACE_Future<Result> GetFutureResult()
{
return _result;
}
int IsReady()
{
return _result.ready();
}
int IsReady()
{
return _result.ready();
}
void GetResult(Result& res)
{
_result.get(res);
}
void GetResult(Result& res)
{
_result.get(res);
}
void FreeResult()
{
_result.cancel();
}
void FreeResult()
{
_result.cancel();
}
void SetFirstParam(ParamType1 value)
{
_param_1 = value;
}
void SetFirstParam(ParamType1 value)
{
_param_1 = value;
}
void SetSecondParam(ParamType2 value)
{
_param_2 = value;
}
void SetSecondParam(ParamType2 value)
{
_param_2 = value;
}
void SetThirdParam(ParamType3 value)
{
_param_3 = value;
}
void SetThirdParam(ParamType3 value)
{
_param_3 = value;
}
ParamType1 GetFirstParam()
{
return _param_1;
}
ParamType1 GetFirstParam()
{
return _param_1;
}
ParamType2 GetSecondParam()
{
return _param_2;
}
ParamType2 GetSecondParam()
{
return _param_2;
}
ParamType3 GetThirdParam()
{
return _param_3;
}
ParamType3 GetThirdParam()
{
return _param_3;
}
//! Resets the stage of the callback chain
void ResetStage()
{
if (!chain)
return;
//! Resets the stage of the callback chain
void ResetStage()
{
if (!chain)
return;
_stage = 0;
}
_stage = 0;
}
//! Advances the callback chain to the next stage, so upper level code can act on its results accordingly
void NextStage()
{
if (!chain)
return;
//! Advances the callback chain to the next stage, so upper level code can act on its results accordingly
void NextStage()
{
if (!chain)
return;
++_stage;
}
++_stage;
}
//! Returns the callback stage (or CALLBACK_STAGE_INVALID if invalid)
uint8 GetStage()
{
return _stage;
}
//! Returns the callback stage (or CALLBACK_STAGE_INVALID if invalid)
uint8 GetStage()
{
return _stage;
}
//! Resets all underlying variables (param, result and stage)
void Reset()
{
SetFirstParam(NULL);
SetSecondParam(NULL);
SetThirdParam(NULL);
FreeResult();
ResetStage();
}
//! Resets all underlying variables (param, result and stage)
void Reset()
{
SetFirstParam(NULL);
SetSecondParam(NULL);
SetThirdParam(NULL);
FreeResult();
ResetStage();
}
private:
ACE_Future<Result> _result;
ParamType1 _param_1;
ParamType2 _param_2;
ParamType3 _param_3;
uint8 _stage;
private:
ACE_Future<Result> _result;
ParamType1 _param_1;
ParamType2 _param_2;
ParamType3 _param_3;
uint8 _stage;
};
#endif

View File

@@ -10,7 +10,7 @@ DelayExecutor* DelayExecutor::instance()
}
DelayExecutor::DelayExecutor()
: pre_svc_hook_(0), post_svc_hook_(0), activated_(false), mqueue_(1*1024*1024, 1*1024*1024), queue_(&mqueue_)
: pre_svc_hook_(0), post_svc_hook_(0), activated_(false), mqueue_(1 * 1024 * 1024, 1 * 1024 * 1024), queue_(&mqueue_)
{
}

View File

@@ -7,33 +7,33 @@
class DelayExecutor : protected ACE_Task_Base
{
public:
public:
DelayExecutor();
virtual ~DelayExecutor();
DelayExecutor();
virtual ~DelayExecutor();
static DelayExecutor* instance();
static DelayExecutor* instance();
int execute(ACE_Method_Request* new_req);
int execute(ACE_Method_Request* new_req);
int start(int num_threads = 1, ACE_Method_Request* pre_svc_hook = NULL, ACE_Method_Request* post_svc_hook = NULL);
int start(int num_threads = 1, ACE_Method_Request* pre_svc_hook = NULL, ACE_Method_Request* post_svc_hook = NULL);
int deactivate();
int deactivate();
bool activated();
bool activated();
virtual int svc();
virtual int svc();
private:
private:
ACE_Method_Request* pre_svc_hook_;
ACE_Method_Request* post_svc_hook_;
bool activated_;
ACE_Message_Queue<ACE_SYNCH> mqueue_;
ACE_Activation_Queue queue_;
ACE_Method_Request* pre_svc_hook_;
ACE_Method_Request* post_svc_hook_;
bool activated_;
ACE_Message_Queue<ACE_SYNCH> mqueue_;
ACE_Activation_Queue queue_;
void activated(bool s);
void activated(bool s);
};
#endif // _M_DELAY_EXECUTOR_H

View File

@@ -15,8 +15,8 @@
namespace ACE_Based
{
template <class T, class LockType, typename StorageType=std::deque<T> >
class LockedQueue
template <class T, class LockType, typename StorageType = std::deque<T> >
class LockedQueue
{
//! Lock access to the queue.
LockType _lock;
@@ -27,120 +27,120 @@ namespace ACE_Based
//! Cancellation flag.
volatile bool _canceled;
public:
public:
//! Create a LockedQueue.
LockedQueue()
: _canceled(false)
{
}
//! Create a LockedQueue.
LockedQueue()
: _canceled(false)
{
}
//! Destroy a LockedQueue.
virtual ~LockedQueue()
{
}
//! Destroy a LockedQueue.
virtual ~LockedQueue()
{
}
//! Adds an item to the queue.
void add(const T& item)
{
lock();
//! Adds an item to the queue.
void add(const T& item)
{
lock();
//ASSERT(!this->_canceled);
// throw Cancellation_Exception();
//ASSERT(!this->_canceled);
// throw Cancellation_Exception();
_queue.push_back(item);
_queue.push_back(item);
unlock();
}
//! Gets the next result in the queue, if any.
bool next(T& result)
{
// ACE_Guard<LockType> g(this->_lock);
ACE_GUARD_RETURN (LockType, g, this->_lock, false);
if (_queue.empty())
return false;
//ASSERT (!_queue.empty() || !this->_canceled);
// throw Cancellation_Exception();
result = _queue.front();
_queue.pop_front();
return true;
}
template<class Checker>
bool next(T& result, Checker& check)
{
ACE_Guard<LockType> g(this->_lock);
if (_queue.empty())
return false;
result = _queue.front();
if (!check.Process(result))
return false;
_queue.pop_front();
return true;
}
//! Peeks at the top of the queue. Check if the queue is empty before calling! Remember to unlock after use if autoUnlock == false.
T& peek(bool autoUnlock = false)
{
lock();
T& result = _queue.front();
if (autoUnlock)
unlock();
}
//! Gets the next result in the queue, if any.
bool next(T& result)
{
// ACE_Guard<LockType> g(this->_lock);
ACE_GUARD_RETURN (LockType, g, this->_lock, false);
return result;
}
if (_queue.empty())
return false;
//! Cancels the queue.
void cancel()
{
lock();
//ASSERT (!_queue.empty() || !this->_canceled);
// throw Cancellation_Exception();
result = _queue.front();
_queue.pop_front();
_canceled = true;
return true;
}
unlock();
}
template<class Checker>
bool next(T& result, Checker& check)
{
ACE_Guard<LockType> g(this->_lock);
//! Checks if the queue is cancelled.
bool cancelled()
{
ACE_Guard<LockType> g(this->_lock);
return _canceled;
}
if (_queue.empty())
return false;
//! Locks the queue for access.
void lock()
{
this->_lock.acquire();
}
result = _queue.front();
if (!check.Process(result))
return false;
//! Unlocks the queue.
void unlock()
{
this->_lock.release();
}
_queue.pop_front();
return true;
}
///! Calls pop_front of the queue
void pop_front()
{
ACE_GUARD (LockType, g, this->_lock);
_queue.pop_front();
}
//! Peeks at the top of the queue. Check if the queue is empty before calling! Remember to unlock after use if autoUnlock == false.
T& peek(bool autoUnlock = false)
{
lock();
T& result = _queue.front();
if (autoUnlock)
unlock();
return result;
}
//! Cancels the queue.
void cancel()
{
lock();
_canceled = true;
unlock();
}
//! Checks if the queue is cancelled.
bool cancelled()
{
ACE_Guard<LockType> g(this->_lock);
return _canceled;
}
//! Locks the queue for access.
void lock()
{
this->_lock.acquire();
}
//! Unlocks the queue.
void unlock()
{
this->_lock.release();
}
///! Calls pop_front of the queue
void pop_front()
{
ACE_GUARD (LockType, g, this->_lock);
_queue.pop_front();
}
///! Checks if we're empty or not with locks held
bool empty()
{
ACE_GUARD_RETURN (LockType, g, this->_lock, false);
return _queue.empty();
}
///! Checks if we're empty or not with locks held
bool empty()
{
ACE_GUARD_RETURN (LockType, g, this->_lock, false);
return _queue.empty();
}
};
}
#endif

View File

@@ -95,7 +95,7 @@ private:
typename std::enable_if<std::is_pointer<E>::value>::type DeleteQueuedObject(E& obj) { delete obj; }
template<typename E = T>
typename std::enable_if<!std::is_pointer<E>::value>::type DeleteQueuedObject(E const& /*packet*/) { }
typename std::enable_if < !std::is_pointer<E>::value >::type DeleteQueuedObject(E const& /*packet*/) { }
};
#endif

View File

@@ -88,13 +88,27 @@ void Thread::setPriority(Priority priority)
switch (priority)
{
#ifdef WIN32
case Priority_Realtime: _ok = SetThreadPriority(handle, THREAD_PRIORITY_TIME_CRITICAL); break;
case Priority_Highest: _ok = SetThreadPriority(handle, THREAD_PRIORITY_HIGHEST); break;
case Priority_High: _ok = SetThreadPriority(handle, THREAD_PRIORITY_ABOVE_NORMAL); break;
case Priority_Normal: _ok = SetThreadPriority(handle, THREAD_PRIORITY_NORMAL); break;
case Priority_Low: _ok = SetThreadPriority(handle, THREAD_PRIORITY_BELOW_NORMAL); break;
case Priority_Lowest: _ok = SetThreadPriority(handle, THREAD_PRIORITY_LOWEST); break;
case Priority_Idle: _ok = SetThreadPriority(handle, THREAD_PRIORITY_IDLE); break;
case Priority_Realtime:
_ok = SetThreadPriority(handle, THREAD_PRIORITY_TIME_CRITICAL);
break;
case Priority_Highest:
_ok = SetThreadPriority(handle, THREAD_PRIORITY_HIGHEST);
break;
case Priority_High:
_ok = SetThreadPriority(handle, THREAD_PRIORITY_ABOVE_NORMAL);
break;
case Priority_Normal:
_ok = SetThreadPriority(handle, THREAD_PRIORITY_NORMAL);
break;
case Priority_Low:
_ok = SetThreadPriority(handle, THREAD_PRIORITY_BELOW_NORMAL);
break;
case Priority_Lowest:
_ok = SetThreadPriority(handle, THREAD_PRIORITY_LOWEST);
break;
case Priority_Idle:
_ok = SetThreadPriority(handle, THREAD_PRIORITY_IDLE);
break;
#endif
default:
break;

View File

@@ -17,18 +17,18 @@ namespace acore
{
class Runnable
{
public:
virtual ~Runnable() {}
virtual void run() = 0;
public:
virtual ~Runnable() {}
virtual void run() = 0;
void incReference() { ++m_refs; }
void decReference()
{
if (!--m_refs)
delete this;
}
private:
std::atomic_long m_refs;
void incReference() { ++m_refs; }
void decReference()
{
if (!--m_refs)
delete this;
}
private:
std::atomic_long m_refs;
};
enum Priority
@@ -44,28 +44,28 @@ namespace acore
class Thread
{
public:
Thread();
explicit Thread(Runnable* instance);
~Thread();
public:
Thread();
explicit Thread(Runnable* instance);
~Thread();
bool wait();
void destroy();
bool wait();
void destroy();
void setPriority(Priority type);
void setPriority(Priority type);
static void Sleep(unsigned long msecs);
static std::thread::id currentId();
static void Sleep(unsigned long msecs);
static std::thread::id currentId();
private:
Thread(const Thread&);
Thread& operator=(const Thread&);
private:
Thread(const Thread&);
Thread& operator=(const Thread&);
static void ThreadTask(void* param);
static void ThreadTask(void* param);
Runnable* const m_task;
std::thread::id m_iThreadId;
std::thread m_ThreadImp;
Runnable* const m_task;
std::thread::id m_iThreadId;
std::thread m_ThreadImp;
};
}
#endif

View File

@@ -19,120 +19,120 @@ namespace acore
template<typename MUTEX>
class GeneralLock
{
public:
public:
GeneralLock(MUTEX& m)
: i_mutex(m)
{
i_mutex.lock();
}
GeneralLock(MUTEX& m)
: i_mutex(m)
{
i_mutex.lock();
}
~GeneralLock()
{
i_mutex.unlock();
}
~GeneralLock()
{
i_mutex.unlock();
}
private:
private:
GeneralLock(const GeneralLock&);
GeneralLock& operator=(const GeneralLock&);
MUTEX& i_mutex;
GeneralLock(const GeneralLock&);
GeneralLock& operator=(const GeneralLock&);
MUTEX& i_mutex;
};
template<class T>
class SingleThreaded
{
public:
public:
struct Lock // empty object
struct Lock // empty object
{
Lock()
{
Lock()
{
}
Lock(const T&)
{
}
}
Lock(const T&)
{
}
Lock(const SingleThreaded<T>&) // for single threaded we ignore this
{
}
};
Lock(const SingleThreaded<T>&) // for single threaded we ignore this
{
}
};
};
template<class T, class MUTEX>
class ObjectLevelLockable
{
public:
ObjectLevelLockable()
: i_mtx()
{
}
friend class Lock;
class Lock
{
public:
ObjectLevelLockable()
: i_mtx()
Lock(ObjectLevelLockable<T, MUTEX>& host)
: i_lock(host.i_mtx)
{
}
friend class Lock;
class Lock
{
public:
Lock(ObjectLevelLockable<T, MUTEX>& host)
: i_lock(host.i_mtx)
{
}
private:
GeneralLock<MUTEX> i_lock;
};
private:
// prevent the compiler creating a copy construct
ObjectLevelLockable(const ObjectLevelLockable<T, MUTEX>&);
ObjectLevelLockable<T, MUTEX>& operator=(const ObjectLevelLockable<T, MUTEX>&);
GeneralLock<MUTEX> i_lock;
};
MUTEX i_mtx;
private:
// prevent the compiler creating a copy construct
ObjectLevelLockable(const ObjectLevelLockable<T, MUTEX>&);
ObjectLevelLockable<T, MUTEX>& operator=(const ObjectLevelLockable<T, MUTEX>&);
MUTEX i_mtx;
};
template<class T, class MUTEX>
class ClassLevelLockable
{
public:
ClassLevelLockable()
{
}
friend class Lock;
class Lock
{
public:
ClassLevelLockable()
Lock(const T& /*host*/)
{
ClassLevelLockable<T, MUTEX>::si_mtx.lock();
}
friend class Lock;
class Lock
Lock(const ClassLevelLockable<T, MUTEX>&)
{
public:
ClassLevelLockable<T, MUTEX>::si_mtx.lock();
}
Lock(const T& /*host*/)
{
ClassLevelLockable<T, MUTEX>::si_mtx.lock();
}
Lock()
{
ClassLevelLockable<T, MUTEX>::si_mtx.lock();
}
Lock(const ClassLevelLockable<T, MUTEX>&)
{
ClassLevelLockable<T, MUTEX>::si_mtx.lock();
}
~Lock()
{
ClassLevelLockable<T, MUTEX>::si_mtx.unlock();
}
};
Lock()
{
ClassLevelLockable<T, MUTEX>::si_mtx.lock();
}
private:
~Lock()
{
ClassLevelLockable<T, MUTEX>::si_mtx.unlock();
}
};
private:
static MUTEX si_mtx;
static MUTEX si_mtx;
};
}

View File

@@ -17,18 +17,18 @@
namespace ByteConverter
{
template<size_t T>
inline void convert(char *val)
inline void convert(char* val)
{
std::swap(*val, *(val + T - 1));
convert<T - 2>(val + 1);
convert < T - 2 > (val + 1);
}
template<> inline void convert<0>(char *) { }
template<> inline void convert<1>(char *) { } // ignore central byte
template<> inline void convert<0>(char*) { }
template<> inline void convert<1>(char*) { } // ignore central byte
template<typename T> inline void apply(T *val)
template<typename T> inline void apply(T* val)
{
convert<sizeof(T)>((char *)(val));
convert<sizeof(T)>((char*)(val));
}
}

View File

@@ -26,7 +26,8 @@ public:
/**
* Returns a pointer to object of requested type stored with given key or nullptr
*/
template<class T> T* Get(std::string const & k) const {
template<class T> T* Get(std::string const& k) const
{
static_assert(std::is_base_of<Base, T>::value, "T must derive from Base");
if (Container.empty())
return nullptr;
@@ -36,13 +37,14 @@ public:
return dynamic_cast<T*>(it->second.get());
return nullptr;
}
/**
* Returns a pointer to object of requested type stored with given key
* or default constructs one and returns that one
*/
template<class T, typename std::enable_if<std::is_default_constructible<T>::value, int>::type = 0>
T* GetDefault(std::string const & k) {
T * GetDefault(std::string const& k)
{
static_assert(std::is_base_of<Base, T>::value, "T must derive from Base");
if (T* v = Get<T>(k))
return v;
@@ -50,16 +52,16 @@ public:
Container.emplace(k, std::unique_ptr<T>(v));
return v;
}
/**
* Stores a new object that inherits the Base class with the given key
*/
void Set(std::string const & k, Base* v) { Container[k] = std::unique_ptr<Base>(v); }
void Set(std::string const& k, Base* v) { Container[k] = std::unique_ptr<Base>(v); }
/**
* Removes objects with given key and returns true if one was removed, false otherwise
*/
bool Erase(std::string const & k) { return Container.erase(k) != 0; }
bool Erase(std::string const& k) { return Container.erase(k) != 0; }
private:
std::unordered_map<std::string, std::unique_ptr<Base>> Container;

View File

@@ -15,51 +15,51 @@
class BasicEvent
{
public:
BasicEvent()
{
to_Abort = false;
m_addTime = 0;
m_execTime = 0;
}
virtual ~BasicEvent() { } // override destructor to perform some actions on event removal
public:
BasicEvent()
{
to_Abort = false;
m_addTime = 0;
m_execTime = 0;
}
virtual ~BasicEvent() { } // override destructor to perform some actions on event removal
// this method executes when the event is triggered
// return false if event does not want to be deleted
// e_time is execution time, p_time is update interval
virtual bool Execute(uint64 /*e_time*/, uint32 /*p_time*/) { return true; }
// this method executes when the event is triggered
// return false if event does not want to be deleted
// e_time is execution time, p_time is update interval
virtual bool Execute(uint64 /*e_time*/, uint32 /*p_time*/) { return true; }
virtual bool IsDeletable() const { return true; } // this event can be safely deleted
virtual bool IsDeletable() const { return true; } // this event can be safely deleted
virtual void Abort(uint64 /*e_time*/) { } // this method executes when the event is aborted
virtual void Abort(uint64 /*e_time*/) { } // this method executes when the event is aborted
bool to_Abort; // set by externals when the event is aborted, aborted events don't execute
// and get Abort call when deleted
bool to_Abort; // set by externals when the event is aborted, aborted events don't execute
// and get Abort call when deleted
// these can be used for time offset control
uint64 m_addTime; // time when the event was added to queue, filled by event handler
uint64 m_execTime; // planned time of next execution, filled by event handler
// these can be used for time offset control
uint64 m_addTime; // time when the event was added to queue, filled by event handler
uint64 m_execTime; // planned time of next execution, filled by event handler
};
typedef std::multimap<uint64, BasicEvent*> EventList;
class EventProcessor
{
public:
EventProcessor();
~EventProcessor();
public:
EventProcessor();
~EventProcessor();
void Update(uint32 p_time);
void KillAllEvents(bool force);
void AddEvent(BasicEvent* Event, uint64 e_time, bool set_addtime = true);
uint64 CalculateTime(uint64 t_offset) const;
void Update(uint32 p_time);
void KillAllEvents(bool force);
void AddEvent(BasicEvent* Event, uint64 e_time, bool set_addtime = true);
uint64 CalculateTime(uint64 t_offset) const;
// Xinef: calculates next queue tick time
uint64 CalculateQueueTime(uint64 delay) const;
// Xinef: calculates next queue tick time
uint64 CalculateQueueTime(uint64 delay) const;
protected:
uint64 m_time;
EventList m_events;
bool m_aborting;
protected:
uint64 m_time;
EventList m_events;
bool m_aborting;
};
#endif

View File

@@ -25,7 +25,7 @@
#endif
#endif
extern int main(int argc, char ** argv);
extern int main(int argc, char** argv);
extern char serviceLongName[];
extern char serviceName[];
extern char serviceDescription[];
@@ -36,7 +36,7 @@ SERVICE_STATUS serviceStatus;
SERVICE_STATUS_HANDLE serviceStatusHandle = 0;
typedef WINADVAPI BOOL (WINAPI *CSD_T)(SC_HANDLE, DWORD, LPCVOID);
typedef WINADVAPI BOOL (WINAPI* CSD_T)(SC_HANDLE, DWORD, LPCVOID);
bool WinServiceInstall()
{
@@ -45,24 +45,24 @@ bool WinServiceInstall()
if (serviceControlManager)
{
char path[_MAX_PATH + 10];
if (GetModuleFileName( 0, path, sizeof(path)/sizeof(path[0]) ) > 0)
if (GetModuleFileName( 0, path, sizeof(path) / sizeof(path[0]) ) > 0)
{
SC_HANDLE service;
std::strcat(path, " --service");
service = CreateService(serviceControlManager,
serviceName, // name of service
serviceLongName, // service name to display
SERVICE_ALL_ACCESS, // desired access
// service type
SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS,
SERVICE_AUTO_START, // start type
SERVICE_ERROR_IGNORE, // error control type
path, // service's binary
0, // no load ordering group
0, // no tag identifier
0, // no dependencies
0, // LocalSystem account
0); // no password
serviceName, // name of service
serviceLongName, // service name to display
SERVICE_ALL_ACCESS, // desired access
// service type
SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS,
SERVICE_AUTO_START, // start type
SERVICE_ERROR_IGNORE, // error control type
path, // service's binary
0, // no load ordering group
0, // no tag identifier
0, // no dependencies
0, // LocalSystem account
0); // no password
if (service)
{
HMODULE advapi32 = GetModuleHandle("ADVAPI32.DLL");
@@ -95,7 +95,7 @@ bool WinServiceInstall()
ZeroMemory(&sfa, sizeof(SERVICE_FAILURE_ACTIONS));
sfa.lpsaActions = _action;
sfa.cActions = 1;
sfa.dwResetPeriod =INFINITE;
sfa.dwResetPeriod = INFINITE;
ChangeService_Config2(
service, // handle to service
SERVICE_CONFIG_FAILURE_ACTIONS, // information level
@@ -117,7 +117,7 @@ bool WinServiceUninstall()
if (serviceControlManager)
{
SC_HANDLE service = OpenService(serviceControlManager,
serviceName, SERVICE_QUERY_STATUS | DELETE);
serviceName, SERVICE_QUERY_STATUS | DELETE);
if (service)
{
SERVICE_STATUS serviceStatus2;
@@ -173,7 +173,7 @@ void WINAPI ServiceControlHandler(DWORD controlCode)
SetServiceStatus(serviceStatusHandle, &serviceStatus);
}
void WINAPI ServiceMain(DWORD argc, char *argv[])
void WINAPI ServiceMain(DWORD argc, char* argv[])
{
// initialise service status
serviceStatus.dwServiceType = SERVICE_WIN32;
@@ -191,7 +191,7 @@ void WINAPI ServiceMain(DWORD argc, char *argv[])
char path[_MAX_PATH + 1];
unsigned int i, last_slash = 0;
GetModuleFileName(0, path, sizeof(path)/sizeof(path[0]));
GetModuleFileName(0, path, sizeof(path) / sizeof(path[0]));
for (i = 0; i < std::strlen(path); i++)
{

View File

@@ -12,9 +12,9 @@
namespace acore
{
/// Handle termination signals
class SignalHandler : public ACE_Event_Handler
{
/// Handle termination signals
class SignalHandler : public ACE_Event_Handler
{
public:
int handle_signal(int SigNum, siginfo_t* = NULL, ucontext_t* = NULL)
{
@@ -22,7 +22,7 @@ class SignalHandler : public ACE_Event_Handler
return 0;
}
virtual void HandleSignal(int /*SigNum*/) { };
};
};
}

View File

@@ -50,158 +50,158 @@ inline uint32 GetMSTimeDiffToNow(uint32 oldMSTime)
struct IntervalTimer
{
public:
public:
IntervalTimer()
: _interval(0), _current(0)
{
}
IntervalTimer()
: _interval(0), _current(0)
{
}
void Update(time_t diff)
{
_current += diff;
if (_current < 0)
_current = 0;
}
void Update(time_t diff)
{
_current += diff;
if (_current < 0)
_current = 0;
}
bool Passed()
{
return _current >= _interval;
}
bool Passed()
{
return _current >= _interval;
}
void Reset()
{
if (_current >= _interval)
_current %= _interval;
}
void Reset()
{
if (_current >= _interval)
_current %= _interval;
}
void SetCurrent(time_t current)
{
_current = current;
}
void SetCurrent(time_t current)
{
_current = current;
}
void SetInterval(time_t interval)
{
_interval = interval;
}
void SetInterval(time_t interval)
{
_interval = interval;
}
time_t GetInterval() const
{
return _interval;
}
time_t GetInterval() const
{
return _interval;
}
time_t GetCurrent() const
{
return _current;
}
time_t GetCurrent() const
{
return _current;
}
private:
private:
time_t _interval;
time_t _current;
time_t _interval;
time_t _current;
};
struct TimeTracker
{
public:
public:
TimeTracker(time_t expiry)
: i_expiryTime(expiry)
{
}
TimeTracker(time_t expiry)
: i_expiryTime(expiry)
{
}
void Update(time_t diff)
{
i_expiryTime -= diff;
}
void Update(time_t diff)
{
i_expiryTime -= diff;
}
bool Passed() const
{
return i_expiryTime <= 0;
}
bool Passed() const
{
return i_expiryTime <= 0;
}
void Reset(time_t interval)
{
i_expiryTime = interval;
}
void Reset(time_t interval)
{
i_expiryTime = interval;
}
time_t GetExpiry() const
{
return i_expiryTime;
}
time_t GetExpiry() const
{
return i_expiryTime;
}
private:
private:
time_t i_expiryTime;
time_t i_expiryTime;
};
struct TimeTrackerSmall
{
public:
public:
TimeTrackerSmall(uint32 expiry = 0)
: i_expiryTime(expiry)
{
}
TimeTrackerSmall(uint32 expiry = 0)
: i_expiryTime(expiry)
{
}
void Update(int32 diff)
{
i_expiryTime -= diff;
}
void Update(int32 diff)
{
i_expiryTime -= diff;
}
bool Passed() const
{
return i_expiryTime <= 0;
}
bool Passed() const
{
return i_expiryTime <= 0;
}
void Reset(uint32 interval)
{
i_expiryTime = interval;
}
void Reset(uint32 interval)
{
i_expiryTime = interval;
}
int32 GetExpiry() const
{
return i_expiryTime;
}
int32 GetExpiry() const
{
return i_expiryTime;
}
private:
private:
int32 i_expiryTime;
int32 i_expiryTime;
};
struct PeriodicTimer
{
public:
public:
PeriodicTimer(int32 period, int32 start_time)
: i_period(period), i_expireTime(start_time)
{
}
PeriodicTimer(int32 period, int32 start_time)
: i_period(period), i_expireTime(start_time)
{
}
bool Update(const uint32 diff)
{
if ((i_expireTime -= diff) > 0)
return false;
bool Update(const uint32 diff)
{
if ((i_expireTime -= diff) > 0)
return false;
i_expireTime += i_period > int32(diff) ? i_period : diff;
return true;
}
i_expireTime += i_period > int32(diff) ? i_period : diff;
return true;
}
void SetPeriodic(int32 period, int32 start_time)
{
i_expireTime = start_time;
i_period = period;
}
void SetPeriodic(int32 period, int32 start_time)
{
i_expireTime = start_time;
i_period = period;
}
// Tracker interface
void TUpdate(int32 diff) { i_expireTime -= diff; }
bool TPassed() const { return i_expireTime <= 0; }
void TReset(int32 diff, int32 period) { i_expireTime += period > diff ? period : diff; }
// Tracker interface
void TUpdate(int32 diff) { i_expireTime -= diff; }
bool TPassed() const { return i_expireTime <= 0; }
void TReset(int32 diff, int32 period) { i_expireTime += period > diff ? period : diff; }
private:
private:
int32 i_period;
int32 i_expireTime;
int32 i_period;
int32 i_expireTime;
};
#endif

View File

@@ -68,7 +68,7 @@ SFMTEngine& SFMTEngine::Instance()
return engine;
}
Tokenizer::Tokenizer(const std::string &src, const char sep, uint32 vectorReserve)
Tokenizer::Tokenizer(const std::string& src, const char sep, uint32 vectorReserve)
{
m_str = new char[src.length() + 1];
memcpy(m_str, src.c_str(), src.length() + 1);
@@ -141,7 +141,7 @@ time_t GetLocalHourTimestamp(time_t time, uint8 hour, bool onlyAfterTime)
return hourLocal;
}
void stripLineInvisibleChars(std::string &str)
void stripLineInvisibleChars(std::string& str)
{
static std::string const invChars = " \t\7\n";
@@ -150,7 +150,7 @@ void stripLineInvisibleChars(std::string &str)
bool space = false;
for (size_t pos = 0; pos < str.size(); ++pos)
{
if (invChars.find(str[pos])!=std::string::npos)
if (invChars.find(str[pos]) != std::string::npos)
{
if (!space)
{
@@ -160,7 +160,7 @@ void stripLineInvisibleChars(std::string &str)
}
else
{
if (wpos!=pos)
if (wpos != pos)
str[wpos++] = str[pos];
else
++wpos;
@@ -170,7 +170,7 @@ void stripLineInvisibleChars(std::string &str)
if (wpos < str.size())
str.erase(wpos, str.size());
if (str.find("|TInterface")!=std::string::npos)
if (str.find("|TInterface") != std::string::npos)
str.clear();
}
@@ -194,8 +194,8 @@ std::string secsToTimeString(uint64 timeInSecs, bool shortText)
std::string str = ss.str();
if (!shortText && !str.empty() && str[str.size()-1] == ' ')
str.resize(str.size()-1);
if (!shortText && !str.empty() && str[str.size() - 1] == ' ')
str.resize(str.size() - 1);
return str;
}
@@ -205,8 +205,8 @@ int32 MoneyStringToMoney(const std::string& moneyString)
int32 money = 0;
if (!(std::count(moneyString.begin(), moneyString.end(), 'g') == 1 ||
std::count(moneyString.begin(), moneyString.end(), 's') == 1 ||
std::count(moneyString.begin(), moneyString.end(), 'c') == 1))
std::count(moneyString.begin(), moneyString.end(), 's') == 1 ||
std::count(moneyString.begin(), moneyString.end(), 'c') == 1))
return 0; // Bad format
Tokenizer tokens(moneyString, ' ');
@@ -241,22 +241,31 @@ uint32 TimeStringToSecs(const std::string& timestring)
{
if (isdigit(*itr))
{
buffer*=10;
buffer+= (*itr)-'0';
buffer *= 10;
buffer += (*itr) - '0';
}
else
{
switch (*itr)
{
case 'd': multiplier = DAY; break;
case 'h': multiplier = HOUR; break;
case 'm': multiplier = MINUTE; break;
case 's': multiplier = 1; break;
default : return 0; //bad format
case 'd':
multiplier = DAY;
break;
case 'h':
multiplier = HOUR;
break;
case 'm':
multiplier = MINUTE;
break;
case 's':
multiplier = 1;
break;
default :
return 0; //bad format
}
buffer*=multiplier;
secs+=buffer;
buffer=0;
buffer *= multiplier;
secs += buffer;
buffer = 0;
}
}
@@ -274,7 +283,7 @@ std::string TimeToTimestampStr(time_t t)
// MM minutes (2 digits 00-59)
// SS seconds (2 digits 00-59)
char buf[20];
int ret = snprintf(buf, 20, "%04d-%02d-%02d_%02d-%02d-%02d", aTm.tm_year+1900, aTm.tm_mon+1, aTm.tm_mday, aTm.tm_hour, aTm.tm_min, aTm.tm_sec);
int ret = snprintf(buf, 20, "%04d-%02d-%02d_%02d-%02d-%02d", aTm.tm_year + 1900, aTm.tm_mon + 1, aTm.tm_mday, aTm.tm_hour, aTm.tm_min, aTm.tm_sec);
if (ret < 0)
{
@@ -349,7 +358,7 @@ size_t utf8length(std::string& utf8str)
{
try
{
return utf8::distance(utf8str.c_str(), utf8str.c_str()+utf8str.size());
return utf8::distance(utf8str.c_str(), utf8str.c_str() + utf8str.size());
}
catch(std::exception const&)
{
@@ -362,16 +371,16 @@ void utf8truncate(std::string& utf8str, size_t len)
{
try
{
size_t wlen = utf8::distance(utf8str.c_str(), utf8str.c_str()+utf8str.size());
size_t wlen = utf8::distance(utf8str.c_str(), utf8str.c_str() + utf8str.size());
if (wlen <= len)
return;
std::wstring wstr;
wstr.resize(wlen);
utf8::utf8to16(utf8str.c_str(), utf8str.c_str()+utf8str.size(), &wstr[0]);
utf8::utf8to16(utf8str.c_str(), utf8str.c_str() + utf8str.size(), &wstr[0]);
wstr.resize(len);
char* oend = utf8::utf16to8(wstr.c_str(), wstr.c_str()+wstr.size(), &utf8str[0]);
utf8str.resize(oend-(&utf8str[0])); // remove unused tail
char* oend = utf8::utf16to8(wstr.c_str(), wstr.c_str() + wstr.size(), &utf8str[0]);
utf8str.resize(oend - (&utf8str[0])); // remove unused tail
}
catch(std::exception const&)
{
@@ -384,7 +393,7 @@ bool Utf8toWStr(char const* utf8str, size_t csize, wchar_t* wstr, size_t& wsize)
try
{
acore::CheckedBufferOutputIterator<wchar_t> out(wstr, wsize);
out = utf8::utf8to16(utf8str, utf8str+csize, out);
out = utf8::utf8to16(utf8str, utf8str + csize, out);
wsize -= out.remaining(); // remaining unused space
wstr[wsize] = L'\0';
}
@@ -418,7 +427,7 @@ bool Utf8toWStr(const std::string& utf8str, std::wstring& wstr)
wstr.clear();
try
{
utf8::utf8to16(utf8str.c_str(), utf8str.c_str()+utf8str.size(), std::back_inserter(wstr));
utf8::utf8to16(utf8str.c_str(), utf8str.c_str() + utf8str.size(), std::back_inserter(wstr));
}
catch(std::exception const&)
{
@@ -434,12 +443,12 @@ bool WStrToUtf8(wchar_t* wstr, size_t size, std::string& utf8str)
try
{
std::string utf8str2;
utf8str2.resize(size*4); // allocate for most long case
utf8str2.resize(size * 4); // allocate for most long case
if (size)
{
char* oend = utf8::utf16to8(wstr, wstr+size, &utf8str2[0]);
utf8str2.resize(oend-(&utf8str2[0])); // remove unused tail
char* oend = utf8::utf16to8(wstr, wstr + size, &utf8str2[0]);
utf8str2.resize(oend - (&utf8str2[0])); // remove unused tail
}
utf8str = utf8str2;
}
@@ -457,12 +466,12 @@ bool WStrToUtf8(std::wstring const& wstr, std::string& utf8str)
try
{
std::string utf8str2;
utf8str2.resize(wstr.size()*4); // allocate for most long case
utf8str2.resize(wstr.size() * 4); // allocate for most long case
if (wstr.size())
{
char* oend = utf8::utf16to8(wstr.c_str(), wstr.c_str()+wstr.size(), &utf8str2[0]);
utf8str2.resize(oend-(&utf8str2[0])); // remove unused tail
char* oend = utf8::utf16to8(wstr.c_str(), wstr.c_str() + wstr.size(), &utf8str2[0]);
utf8str2.resize(oend - (&utf8str2[0])); // remove unused tail
}
utf8str = utf8str2;
}
@@ -512,13 +521,14 @@ std::wstring GetMainPartOfName(std::wstring const& wname, uint32 declension)
static std::wstring const j_End = { wchar_t(0x0439), wchar_t(0x0000) };
static std::array<std::array<std::wstring const*, 7>, 6> const dropEnds = {{
{ &a_End, &o_End, &ya_End, &ie_End, &soft_End, &j_End, nullptr },
{ &a_End, &ya_End, &yeru_End, &i_End, nullptr, nullptr, nullptr },
{ &ie_End, &u_End, &yu_End, &i_End, nullptr, nullptr, nullptr },
{ &u_End, &yu_End, &o_End, &ie_End, &soft_End, &ya_End, &a_End },
{ &oj_End, &io_j_End, &ie_j_End, &o_m_End, &io_m_End, &ie_m_End, &yu_End },
{ &ie_End, &i_End, nullptr, nullptr, nullptr, nullptr, nullptr }
}};
{ &a_End, &o_End, &ya_End, &ie_End, &soft_End, &j_End, nullptr },
{ &a_End, &ya_End, &yeru_End, &i_End, nullptr, nullptr, nullptr },
{ &ie_End, &u_End, &yu_End, &i_End, nullptr, nullptr, nullptr },
{ &u_End, &yu_End, &o_End, &ie_End, &soft_End, &ya_End, &a_End },
{ &oj_End, &io_j_End, &ie_j_End, &o_m_End, &io_m_End, &ie_m_End, &yu_End },
{ &ie_End, &i_End, nullptr, nullptr, nullptr, nullptr, nullptr }
}
};
std::size_t const thisLen = wname.length();
std::array<std::wstring const*, 7> const& endings = dropEnds[declension];
@@ -529,8 +539,8 @@ std::wstring GetMainPartOfName(std::wstring const& wname, uint32 declension)
if (!(endLen <= thisLen))
continue;
if (wname.substr(thisLen-endLen, thisLen) == ending)
return wname.substr(0, thisLen-endLen);
if (wname.substr(thisLen - endLen, thisLen) == ending)
return wname.substr(0, thisLen - endLen);
}
return wname;
@@ -584,7 +594,7 @@ bool Utf8FitTo(const std::string& str, std::wstring const& search)
return true;
}
void utf8printf(FILE* out, const char *str, ...)
void utf8printf(FILE* out, const char* str, ...)
{
va_list ap;
va_start(ap, str);
@@ -592,7 +602,7 @@ void utf8printf(FILE* out, const char *str, ...)
va_end(ap);
}
void vutf8printf(FILE* out, const char *str, va_list* ap)
void vutf8printf(FILE* out, const char* str, va_list* ap)
{
#if AC_PLATFORM == AC_PLATFORM_WINDOWS
char temp_buf[32 * 1024];
@@ -601,9 +611,9 @@ void vutf8printf(FILE* out, const char *str, va_list* ap)
size_t temp_len = vsnprintf(temp_buf, 32 * 1024, str, *ap);
//vsnprintf returns -1 if the buffer is too small
if (temp_len == size_t(-1))
temp_len = 32*1024-1;
temp_len = 32 * 1024 - 1;
size_t wtemp_len = 32*1024-1;
size_t wtemp_len = 32 * 1024 - 1;
Utf8toWStr(temp_buf, temp_len, wtemp_buf, wtemp_len);
CharToOemBuffW(&wtemp_buf[0], &temp_buf[0], uint32(wtemp_len + 1));
@@ -683,5 +693,5 @@ bool StringToBool(std::string const& str)
bool StringContainsStringI(std::string const& haystack, std::string const& needle)
{
return haystack.end() !=
std::search(haystack.begin(), haystack.end(), needle.begin(), needle.end(), [](char c1, char c2) { return std::toupper(c1) == std::toupper(c2); });
std::search(haystack.begin(), haystack.end(), needle.begin(), needle.end(), [](char c1, char c2) { return std::toupper(c1) == std::toupper(c2); });
}

Some files were not shown because too many files have changed in this diff Show More