summaryrefslogtreecommitdiff
path: root/src/base
diff options
context:
space:
mode:
authorDimitri John Ledkov <dimitri.ledkov@canonical.com>2014-02-20 16:10:52 +0000
committerDimitri John Ledkov <dimitri.ledkov@canonical.com>2014-02-20 19:15:57 +0000
commitd20f4a64eba38690337ac914a04a113de7caf125 (patch)
tree6828990e93ca5d8847b8cde2f2febb6566b0d53f /src/base
parent28161e9209f21be1a600f637565ecede94855a36 (diff)
New upstream release. Closes: #721047debian/1.8.0-1
Drop all patches, none are needed with this new upstream release. Port to dh. Specify foreign in configure.ac.
Diffstat (limited to 'src/base')
-rw-r--r--src/base/Backtrace.cpp39
-rw-r--r--src/base/Backtrace.h2
-rw-r--r--src/base/BezierCurve.cpp27
-rw-r--r--src/base/BezierCurve.h20
-rw-r--r--src/base/CmdLine.cpp82
-rw-r--r--src/base/CmdQueue.h9
-rw-r--r--src/base/Command.h2
-rw-r--r--src/base/ConfigMgr.cpp99
-rw-r--r--src/base/ConfigMgr.h16
-rw-r--r--src/base/CubicSpline.cpp97
-rw-r--r--src/base/CubicSpline.h16
-rw-r--r--src/base/DAG.cpp130
-rw-r--r--src/base/DAG.h (renamed from src/base/Triple.h)58
-rw-r--r--src/base/DirEntry.cpp2
-rw-r--r--src/base/DirEntry.h2
-rw-r--r--src/base/Directory.cpp2
-rw-r--r--src/base/Directory.h2
-rw-r--r--src/base/DlfcnWrapper.cpp2
-rw-r--r--src/base/DlfcnWrapper.h2
-rw-r--r--src/base/Exception.cpp28
-rw-r--r--src/base/Exception.h10
-rw-r--r--src/base/FileHelper.cpp11
-rw-r--r--src/base/FileHelper.h20
-rw-r--r--src/base/GLMHelper.cpp183
-rw-r--r--src/base/GLMHelper.h70
-rw-r--r--src/base/GeomHelper.cpp54
-rw-r--r--src/base/GeomHelper.h23
-rw-r--r--src/base/IFrameEndListener.h2
-rw-r--r--src/base/ILogSink.h (renamed from src/base/Matrix3x4.h)47
-rw-r--r--src/base/IPlaybackEndListener.h2
-rw-r--r--src/base/IPreRenderListener.h2
-rw-r--r--src/base/Logger.cpp339
-rw-r--r--src/base/Logger.h150
-rw-r--r--src/base/Makefile.am32
-rw-r--r--src/base/Makefile.in371
-rw-r--r--src/base/MathHelper.cpp32
-rw-r--r--src/base/MathHelper.h12
-rw-r--r--src/base/Matrix3x4.cpp128
-rw-r--r--src/base/OSHelper.cpp142
-rw-r--r--src/base/OSHelper.h6
-rw-r--r--src/base/ObjectCounter.cpp11
-rw-r--r--src/base/ObjectCounter.h9
-rw-r--r--src/base/Point.cpp325
-rw-r--r--src/base/Point.h124
-rw-r--r--src/base/ProfilingZone.cpp14
-rw-r--r--src/base/ProfilingZone.h6
-rw-r--r--src/base/ProfilingZoneID.cpp21
-rw-r--r--src/base/ProfilingZoneID.h11
-rw-r--r--src/base/Queue.h46
-rw-r--r--src/base/Rect.h61
-rw-r--r--src/base/ScopeTimer.cpp13
-rw-r--r--src/base/ScopeTimer.h31
-rw-r--r--src/base/Signal.h2
-rw-r--r--src/base/StandardLogSink.cpp54
-rw-r--r--src/base/StandardLogSink.h (renamed from src/base/CmdLine.h)35
-rw-r--r--src/base/StringHelper.cpp36
-rw-r--r--src/base/StringHelper.h38
-rw-r--r--src/base/Test.cpp4
-rw-r--r--src/base/Test.h3
-rw-r--r--src/base/TestSuite.cpp6
-rw-r--r--src/base/TestSuite.h2
-rw-r--r--src/base/ThreadHelper.cpp94
-rw-r--r--src/base/ThreadHelper.h37
-rw-r--r--src/base/ThreadProfiler.cpp61
-rw-r--r--src/base/ThreadProfiler.h38
-rw-r--r--src/base/TimeSource.cpp18
-rw-r--r--src/base/TimeSource.h2
-rw-r--r--src/base/Triangle.cpp50
-rw-r--r--src/base/Triangle.h18
-rw-r--r--src/base/Triangulate.cpp139
-rw-r--r--src/base/Triangulate.h22
-rw-r--r--src/base/Triple.cpp107
-rw-r--r--src/base/UTF8String.cpp7
-rw-r--r--src/base/UTF8String.h5
-rw-r--r--src/base/WideLine.cpp16
-rw-r--r--src/base/WideLine.h16
-rw-r--r--src/base/WorkerThread.cpp41
-rw-r--r--src/base/WorkerThread.h43
-rw-r--r--src/base/XMLHelper.cpp149
-rw-r--r--src/base/XMLHelper.h40
-rw-r--r--src/base/testbase.cpp553
-rw-r--r--src/base/triangulate/AdvancingFront.cpp104
-rw-r--r--src/base/triangulate/AdvancingFront.h118
-rw-r--r--src/base/triangulate/Makefile.am8
-rw-r--r--src/base/triangulate/Makefile.in593
-rw-r--r--src/base/triangulate/Shapes.cpp353
-rw-r--r--src/base/triangulate/Shapes.h296
-rw-r--r--src/base/triangulate/Sweep.cpp796
-rw-r--r--src/base/triangulate/Sweep.h201
-rw-r--r--src/base/triangulate/SweepContext.cpp196
-rw-r--r--src/base/triangulate/SweepContext.h181
-rw-r--r--src/base/triangulate/Triangulate.cpp90
-rw-r--r--src/base/triangulate/Triangulate.h33
-rw-r--r--src/base/triangulate/Utils.h124
94 files changed, 5738 insertions, 1936 deletions
diff --git a/src/base/Backtrace.cpp b/src/base/Backtrace.cpp
index f6d1d77..2b85cde 100644
--- a/src/base/Backtrace.cpp
+++ b/src/base/Backtrace.cpp
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -21,6 +21,8 @@
#include "Backtrace.h"
+#include "StringHelper.h"
+
#ifndef _WIN32
#include <execinfo.h>
#include <cxxabi.h>
@@ -28,6 +30,7 @@
#include <stdlib.h>
#include <iostream>
+#include <stdio.h>
using namespace std;
@@ -38,12 +41,10 @@ void dumpBacktrace()
#ifndef _WIN32
vector<string> sFuncs;
getBacktrace(sFuncs);
- int i=0;
vector<string>::iterator it = sFuncs.begin();
++it;
for (; it != sFuncs.end(); ++it) {
- cerr << " " << i << ": " << *it << endl;
- i++;
+ cerr << " " << *it << endl;
}
#endif
}
@@ -67,7 +68,15 @@ string funcNameFromLine(const string& sLine)
}
}
-void getBacktrace(std::vector<std::string>& sFuncs)
+void consolidateRepeatedLines(vector<string>& sFuncs, unsigned& i, unsigned numSameLines)
+{
+ unsigned firstSameLine = i - numSameLines;
+ sFuncs[firstSameLine+1] = " [...]";
+ sFuncs.erase(sFuncs.begin()+firstSameLine+2, sFuncs.begin()+i-1);
+ i = firstSameLine + 3;
+}
+
+void getBacktrace(vector<string>& sFuncs)
{
#ifndef _WIN32
void* callstack[128];
@@ -83,9 +92,27 @@ void getBacktrace(std::vector<std::string>& sFuncs)
sFuncName = pszDemangledFuncName;
free(pszDemangledFuncName);
}
- sFuncs.push_back(sFuncName);
+ char szLineNum[10];
+ sprintf(szLineNum, "%3d", i);
+ sFuncs.push_back(string(szLineNum)+" "+sFuncName);
}
free(ppszLines);
+
+ unsigned numSameLines = 1;
+ unsigned i = 1;
+ for (i = 1; i < sFuncs.size(); ++i) {
+ if (sFuncs[i].substr(4, string::npos) == sFuncs[i-1].substr(4, string::npos)) {
+ numSameLines++;
+ } else {
+ if (numSameLines > 3) {
+ consolidateRepeatedLines(sFuncs, i, numSameLines);
+ }
+ numSameLines = 1;
+ }
+ }
+ if (numSameLines > 2) {
+ consolidateRepeatedLines(sFuncs, i, numSameLines);
+ }
#endif
}
diff --git a/src/base/Backtrace.h b/src/base/Backtrace.h
index cc49964..2eee387 100644
--- a/src/base/Backtrace.h
+++ b/src/base/Backtrace.h
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
diff --git a/src/base/BezierCurve.cpp b/src/base/BezierCurve.cpp
index 3d1ea72..7e5fb8e 100644
--- a/src/base/BezierCurve.cpp
+++ b/src/base/BezierCurve.cpp
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -21,14 +21,16 @@
#include "BezierCurve.h"
+#include "GLMHelper.h"
+
#include <iostream>
using namespace std;
namespace avg {
-BezierCurve::BezierCurve(const DPoint& p0, const DPoint& p1, const DPoint& p2,
- const DPoint& p3)
+BezierCurve::BezierCurve(const glm::vec2& p0, const glm::vec2& p1, const glm::vec2& p2,
+ const glm::vec2& p3)
: m_P0(p0),
m_P1(p1),
m_P2(p2),
@@ -36,18 +38,19 @@ BezierCurve::BezierCurve(const DPoint& p0, const DPoint& p1, const DPoint& p2,
{
}
-DPoint BezierCurve::interpolate(double t) const
+glm::vec2 BezierCurve::interpolate(float t) const
{
- return (1-t)*(1-t)*(1-t)*m_P0+
- 3*t*(1-t)*(1-t) *m_P1+
- 3*t*t*(1-t) *m_P2+
- t*t*t *m_P3;
+ return (1.f-t)*(1.f-t)*(1.f-t)*m_P0+
+ 3.f*t*(1.f-t)*(1.f-t) *m_P1+
+ 3.f*t*t*(1.f-t) *m_P2+
+ t*t*t *m_P3;
}
-DPoint BezierCurve::getDeriv(double t) const
+
+glm::vec2 BezierCurve::getDeriv(float t) const
{
- return 3*(m_P1-m_P0)*(1-t)*(1-t)+
- 6*(m_P2-m_P1)*(1-t)*t+
- 3*(m_P3-m_P2)*t*t;
+ return 3.f*(m_P1-m_P0)*(1.f-t)*(1.f-t)+
+ 6.f*(m_P2-m_P1)*(1.f-t)*t+
+ 3.f*(m_P3-m_P2)*t*t;
}
}
diff --git a/src/base/BezierCurve.h b/src/base/BezierCurve.h
index b7e00f4..b2ec1dc 100644
--- a/src/base/BezierCurve.h
+++ b/src/base/BezierCurve.h
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -23,7 +23,8 @@
#define _BezierCurve_H_
#include "../api.h"
-#include "Point.h"
+
+#include "../glm/glm.hpp"
#include <boost/shared_ptr.hpp>
#include <vector>
@@ -32,16 +33,17 @@ namespace avg {
class AVG_API BezierCurve {
public:
- BezierCurve(const DPoint& p0, const DPoint& p1, const DPoint& p2, const DPoint& p3);
+ BezierCurve(const glm::vec2& p0, const glm::vec2& p1, const glm::vec2& p2,
+ const glm::vec2& p3);
- DPoint interpolate(double t) const;
- DPoint getDeriv(double t) const;
+ glm::vec2 interpolate(float t) const;
+ glm::vec2 getDeriv(float t) const;
private:
- DPoint m_P0;
- DPoint m_P1;
- DPoint m_P2;
- DPoint m_P3;
+ glm::vec2 m_P0;
+ glm::vec2 m_P1;
+ glm::vec2 m_P2;
+ glm::vec2 m_P3;
};
typedef boost::shared_ptr<BezierCurve> BezierCurvePtr;
diff --git a/src/base/CmdLine.cpp b/src/base/CmdLine.cpp
deleted file mode 100644
index d081ec5..0000000
--- a/src/base/CmdLine.cpp
+++ /dev/null
@@ -1,82 +0,0 @@
-//
-// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
-//
-// This library is free software; you can redistribute it and/or
-// modify it under the terms of the GNU Lesser General Public
-// License as published by the Free Software Foundation; either
-// version 2 of the License, or (at your option) any later version.
-//
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public
-// License along with this library; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-//
-// Current versions can be found at www.libavg.de
-//
-
-#include "CmdLine.h"
-
-#include <iostream>
-
-using namespace std;
-
-namespace avg {
-
-CmdLine::CmdLine(int argc, char **argv)
-{
- for (int i = 1; i < argc; ++i) {
- string sArg(argv[i]);
- if (sArg.substr(0, 2) == "--") {
- string::size_type DelimPos = sArg.find('=');
- string sOptName;
- string sOptVal;
- if (DelimPos == sArg.npos) {
- sOptName = sArg.substr(2);
- sOptVal = "";
- } else {
- sOptName = sArg.substr(2, DelimPos-2);
- sOptVal = sArg.substr(DelimPos+1);
- }
- m_Options[sOptName] = sOptVal;
- } else {
- m_Args.push_back(sArg);
- }
- }
-}
-
-const OptionMap& CmdLine::getOptions() const
-{
- return m_Options;
-}
-
-const string* CmdLine::getOption(const string& sName) const
-{
- OptionMap::const_iterator it = m_Options.find(sName);
- if (it == m_Options.end()) {
- return 0;
- } else {
- return &(*it).second;
- }
-}
-
-int CmdLine::getNumArgs() const
-{
- return int(m_Args.size());
-}
-
-const string* CmdLine::getArg(unsigned int i) const
-{
- if (i>=m_Args.size()) {
- return 0;
- } else {
- return &m_Args[i];
- }
-}
-
-}
-
diff --git a/src/base/CmdQueue.h b/src/base/CmdQueue.h
index a2dc6a3..9d38f37 100644
--- a/src/base/CmdQueue.h
+++ b/src/base/CmdQueue.h
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -33,12 +33,19 @@ template<class RECEIVER>
class AVG_TEMPLATE_API CmdQueue: public Queue<Command<RECEIVER> >
{
public:
+ CmdQueue(int maxSize=-1);
typedef typename Queue<Command<RECEIVER> >::QElementPtr CmdPtr;
void pushCmd(typename Command<RECEIVER>::CmdFunc func);
};
template<class RECEIVER>
+CmdQueue<RECEIVER>::CmdQueue(int maxSize)
+ : Queue<Command<RECEIVER> >(maxSize)
+{
+}
+
+template<class RECEIVER>
void CmdQueue<RECEIVER>::pushCmd(typename Command<RECEIVER>::CmdFunc func)
{
this->push(CmdPtr(new Command<RECEIVER>(func)));
diff --git a/src/base/Command.h b/src/base/Command.h
index 79c48a6..fe18171 100644
--- a/src/base/Command.h
+++ b/src/base/Command.h
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
diff --git a/src/base/ConfigMgr.cpp b/src/base/ConfigMgr.cpp
index 04b756d..0414037 100644
--- a/src/base/ConfigMgr.cpp
+++ b/src/base/ConfigMgr.cpp
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -66,29 +66,45 @@ ConfigMgr* ConfigMgr::get()
ConfigMgr::ConfigMgr()
{
addSubsys("scr");
+ addOption("scr", "gles", "false");
addOption("scr", "bpp", "24");
addOption("scr", "fullscreen", "false");
addOption("scr", "windowwidth", "0");
addOption("scr", "windowheight", "0");
addOption("scr", "dotspermm", "0");
addOption("scr", "usepow2textures", "false");
- addOption("scr", "useshaders", "true");
addOption("scr", "usepixelbuffers", "true");
- addOption("scr", "multisamplesamples", "1");
+ addOption("scr", "multisamplesamples", "8");
+ addOption("scr", "shaderusage", "auto");
addOption("scr", "gamma", "-1,-1,-1");
addOption("scr", "vsyncmode", "auto");
+ addOption("scr", "videoaccel", "true");
addSubsys("aud");
addOption("aud", "channels", "2");
addOption("aud", "samplerate", "44100");
addOption("aud", "outputbuffersamples", "1024");
+ addSubsys("gesture");
+ addOption("gesture", "maxtapdist", "15");
+ addOption("gesture", "maxdoubletaptime", "300");
+ addOption("gesture", "minswipedist", "50");
+ addOption("gesture", "swipedirectiontolerance", "0.393"); // pi/8
+ addOption("gesture", "maxswipecontactdist", "100");
+ addOption("gesture", "holddelay", "500");
+ addOption("gesture", "mindragdist", "5");
+ addOption("gesture", "filtermincutoff", "0.1");
+ addOption("gesture", "filterbeta", "0.03");
+ addOption("gesture", "friction", "-1");
+
+ addSubsys("touch");
+ addOption("touch", "area", "0, 0");
+ addOption("touch", "offset", "0, 0");
+
m_sFName = "avgrc";
loadFile(getGlobalConfigDir()+m_sFName);
char * pHome = getenv("HOME");
- if (!pHome) {
- AVG_TRACE(Logger::WARNING, "No home directory set.");
- } else {
+ if (pHome) {
loadFile(string(pHome)+"/."+m_sFName);
}
}
@@ -131,8 +147,8 @@ const string* ConfigMgr::getOption(const string& sSubsys,
}
}
-bool ConfigMgr::getBoolOption(const std::string& sSubsys,
- const std::string& sName, bool bDefault) const
+bool ConfigMgr::getBoolOption(const string& sSubsys,
+ const string& sName, bool bDefault) const
{
const string * psOption = getOption(sSubsys, sName);
if (psOption == 0) {
@@ -143,15 +159,14 @@ bool ConfigMgr::getBoolOption(const std::string& sSubsys,
} else if (*psOption == "false") {
return false;
} else {
- AVG_TRACE(Logger::ERROR,
- m_sFName << ": Unrecognized value for option "<<sName<<": "
+ AVG_LOG_ERROR(m_sFName << ": Unrecognized value for option " << sName << ": "
<< *psOption << ". Must be true or false. Aborting.");
exit(-1);
}
}
-int ConfigMgr::getIntOption(const std::string& sSubsys,
- const std::string& sName, int Default) const
+int ConfigMgr::getIntOption(const string& sSubsys,
+ const string& sName, int Default) const
{
errno = 0;
const string * psOption = getOption(sSubsys, sName);
@@ -161,30 +176,57 @@ int ConfigMgr::getIntOption(const std::string& sSubsys,
int Result = strtol(psOption->c_str(), 0, 10);
int rc = errno;
if (rc == EINVAL || rc == ERANGE) {
- AVG_TRACE(Logger::ERROR,
- m_sFName << ": Unrecognized value for option "<<sName<<": "
+ AVG_LOG_ERROR(m_sFName << ": Unrecognized value for option "<<sName<<": "
<< *psOption << ". Must be an integer. Aborting.");
exit(-1);
}
return Result;
}
-void ConfigMgr::getGammaOption(const std::string& sSubsys,
- const std::string& sName, double* Val) const
+void ConfigMgr::getGammaOption(const string& sSubsys,
+ const string& sName, float* Val) const
{
const string * psOption = getOption(sSubsys, sName);
if (psOption == 0) {
return;
}
- int rc = sscanf(psOption->c_str(), "%lf,%lf,%lf", Val, Val+1, Val+2);
+ int rc = sscanf(psOption->c_str(), "%f,%f,%f", Val, Val+1, Val+2);
if (rc < 3) {
- AVG_TRACE(Logger::ERROR,
- m_sFName << ": Unrecognized value for option "<<sName<<": "
+ AVG_LOG_ERROR(m_sFName << ": Unrecognized value for option "<<sName<<": "
<< *psOption << ". Must be three comma-separated numbers. Aborting.");
exit(-1);
}
}
+glm::vec2 ConfigMgr::getSizeOption(const string& sSubsys,
+ const string& sName) const
+{
+ const string * psOption = getOption(sSubsys, sName);
+ if (psOption == 0) {
+ return glm::vec2(0, 0);
+ }
+ float val[2];
+ int rc = sscanf(psOption->c_str(), "%f,%f", val, val+1);
+ if (rc < 2) {
+ AVG_LOG_ERROR(m_sFName << ": Unrecognized value for option " << sName << ": "
+ << *psOption << ". Must be 2 comma-separated numbers(x, y). Aborting.");
+ exit(-1);
+ }
+ return glm::vec2(val[0], val[1]);
+}
+
+void ConfigMgr::getStringOption(const string& sSubsys,
+ const string& sName, const string& sDefault, string& sVal) const
+{
+ const string * psOption = getOption(sSubsys, sName);
+ if (psOption == 0) {
+ sVal = sDefault;
+ } else {
+ sVal = *psOption;
+ }
+}
+
+
bool ConfigMgr::loadFile(const std::string& sPath)
{
string sSubsys;
@@ -194,8 +236,8 @@ bool ConfigMgr::loadFile(const std::string& sPath)
int err = access(sPath.c_str(), R_OK);
if (err == -1) {
if (errno == EACCES) {
- AVG_TRACE(Logger::WARNING,
- sPath+": File exists, but process doesn't have read permissions!");
+ AVG_LOG_WARNING(sPath+
+ ": File exists, but process doesn't have read permissions!");
}
return false;
}
@@ -215,8 +257,7 @@ bool ConfigMgr::loadFile(const std::string& sPath)
}
xmlNodePtr pRoot = xmlDocGetRootElement(doc);
if (xmlStrcmp(pRoot->name, (const xmlChar *)(m_sFName.c_str()))) {
- AVG_TRACE(Logger::ERROR,
- sPath+": Root node must be <"+m_sFName+">, found "
+ AVG_LOG_ERROR(sPath+": Root node must be <"+m_sFName+">, found "
<< pRoot->name << ". Aborting.");
exit(255);
}
@@ -228,8 +269,7 @@ bool ConfigMgr::loadFile(const std::string& sPath)
sSubsys = ((const char *)pSubsysNode->name);
xmlNodePtr pOptionNode = pSubsysNode->xmlChildrenNode;
if (!pOptionNode) {
- AVG_TRACE(Logger::ERROR,
- sPath << ": Option " << sSubsys
+ AVG_LOG_ERROR(sPath << ": Option " << sSubsys
<< " has no value. Ignoring.");
} else {
ConfigOptionVector& CurSubsys = getSubsys(sSubsys);
@@ -249,13 +289,12 @@ bool ConfigMgr::loadFile(const std::string& sPath)
} catch (Exception& e) {
switch (e.getCode()) {
case AVG_ERR_OPTION_SUBSYS_UNKNOWN:
- AVG_TRACE(Logger::ERROR, "While parsing " << sPath
- << ": Option group " << e.getStr() << " unknown. Aborting.");
+ AVG_LOG_ERROR("While parsing " << sPath << ": Option group " <<
+ e.getStr() << " unknown. Aborting.");
exit(255);
case AVG_ERR_OPTION_UNKNOWN:
- AVG_TRACE(Logger::ERROR, "While parsing " << sPath
- << ": Option " << sSubsys << ":" << e.getStr()
- << " unknown. Aborting.");
+ AVG_LOG_ERROR("While parsing " << sPath << ": Option " << sSubsys <<
+ ":" << e.getStr() << " unknown. Aborting.");
exit(255);
default:
throw;
diff --git a/src/base/ConfigMgr.h b/src/base/ConfigMgr.h
index 421c399..e2af8f1 100644
--- a/src/base/ConfigMgr.h
+++ b/src/base/ConfigMgr.h
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -23,8 +23,8 @@
#define _ConfigMgr_H_
#include "../api.h"
-#include "CmdLine.h"
+#include "GLMHelper.h"
#include <libxml/parser.h>
#include <string>
@@ -49,9 +49,8 @@ public:
void addSubsys(const std::string& sName);
void addOption(const std::string& sSubsys, const std::string& sName,
const std::string& sDefault);
-
- const ConfigOptionVector* getOptions(const std::string& sSubsys)
- const;
+
+ const ConfigOptionVector* getOptions(const std::string& sSubsys) const;
const std::string* getOption(const std::string& sSubsys,
const std::string& sName) const;
bool getBoolOption(const std::string& sSubsys,
@@ -59,7 +58,12 @@ public:
int getIntOption(const std::string& sSubsys,
const std::string& sName, int Default) const;
void getGammaOption(const std::string& sSubsys,
- const std::string& sName, double* Val) const;
+ const std::string& sName, float* Val) const;
+ glm::vec2 getSizeOption(const std::string& sSubsys,
+ const std::string& sName) const;
+ void getStringOption(const std::string& sSubsys,
+ const std::string& sName, const std::string& sDefault, std::string& sVal)
+ const;
void dump() const;
diff --git a/src/base/CubicSpline.cpp b/src/base/CubicSpline.cpp
index f03f7f5..105563d 100644
--- a/src/base/CubicSpline.cpp
+++ b/src/base/CubicSpline.cpp
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -21,6 +21,7 @@
#include "CubicSpline.h"
#include "Exception.h"
+#include "MathHelper.h"
#include <iostream>
@@ -28,61 +29,75 @@ using namespace std;
namespace avg {
-CubicSpline::CubicSpline(const vector<double>& x, const vector<double>& y)
- : m_X(x),
- m_Y(y)
+CubicSpline::CubicSpline(const vector<float>& x, const vector<float>& y, bool bLoop)
{
AVG_ASSERT(x.size() == y.size());
- // Add fake points before the first and after the last point so all derivatives
- // are defined.
- double edgeX = 2*m_X[0]-m_X[1];
- double edgeY = 2*m_Y[0]-m_Y[1];
- m_X.insert(m_X.begin(), edgeX);
- m_Y.insert(m_Y.begin(), edgeY);
+ for (unsigned i=0; i<x.size(); ++i) {
+ m_Pts.push_back(glm::vec2(x[i], y[i]));
+ }
+ init();
+}
- int len = m_X.size();
- edgeX = 2*m_X[len-1]-m_X[len-2];
- edgeY = 2*m_Y[len-1]-m_Y[len-2];
- m_X.push_back(edgeX);
- m_Y.push_back(edgeY);
+CubicSpline::CubicSpline(const vector<glm::vec2>& pts, bool bLoop)
+ : m_Pts(pts)
+{
+ init();
}
CubicSpline::~CubicSpline()
{
}
-double normedInterpolate(double y0, double y1, double y2, double y3, double mu)
+float CubicSpline::interpolate(float orig)
{
- double mu2 = mu*mu;
- double a0 = y3 - y2 - y0 + y1;
- double a1 = y0 - y1 - a0;
- double a2 = y2 - y0;
- double a3 = y1;
-
- return(a0*mu*mu2+a1*mu2+a2*mu+a3);
+ int len = m_Pts.size();
+ int low = 0;
+ int high = len-1;
+ // Binary search.
+ while (high - low > 1) {
+ int avg = (high+low) / 2;
+ if (m_Pts[avg].x > orig) {
+ high = avg;
+ } else {
+ low = avg;
+ }
+ }
+ float h = m_Pts[high].x - m_Pts[low].x;
+ float a = (m_Pts[high].x-orig)/h;
+ float b = (orig-m_Pts[low].x)/h;
+
+ float y = a*m_Pts[low].y + b*m_Pts[high].y
+ + ((a*a*a-a)*m_Y2[low] + (b*b*b-b)*m_Y2[high])*(h*h)/6.f;
+ return y;
}
-
-double CubicSpline::interpolate(double orig)
+void CubicSpline::init()
{
- unsigned i = 0;
- if (m_X[m_X.size()-1] <= orig) {
- i = m_X.size();
- } else {
- while (m_X[i] < orig) {
- i++;
+ int len = m_Pts.size();
+ for (int i=1; i<len; ++i) {
+ if (m_Pts[i].x <= m_Pts[i-1].x) {
+ throw Exception(AVG_ERR_INVALID_ARGS,
+ "CubicSplines must have increasing x coordinates.");
}
}
- if (i < 2) {
- double dxdy = (m_X[1]-m_X[0])/(m_Y[1]-m_Y[0]);
- return m_Y[1]+(orig-m_X[1])/dxdy;
- } else if (i > m_X.size()-2) {
- unsigned len = m_X.size();
- double dxdy = (m_X[len-1]-m_X[len-2])/(m_Y[len-1]-m_Y[len-2]);
- return m_Y[len-2]+(orig-m_X[len-2])/dxdy;
- } else {
- double ratio = (orig-m_X[i-1])/(m_X[i]-m_X[i-1]);
- return normedInterpolate(m_Y[i-2], m_Y[i-1], m_Y[i], m_Y[i+1], ratio);
+ vector<float> u(len-1,0);
+ m_Y2.push_back(0.f);
+ u[0] = 0.f;
+ for (int i=1; i<len-1; ++i) {
+ float sig = (m_Pts[i].x-m_Pts[i-1].x) / (m_Pts[i+1].x-m_Pts[i-1].x);
+ float p = sig * m_Y2[i-1]+2.0f;
+ m_Y2.push_back((sig-1.0f)/p);
+ u[i] = (m_Pts[i+1].y-m_Pts[i].y) / (m_Pts[i+1].x-m_Pts[i].x) -
+ (m_Pts[i].y - m_Pts[i-1].y) / (m_Pts[i].x-m_Pts[i-1].x);
+ u[i] = (6.f*u[i]/(m_Pts[i+1].x-m_Pts[i-1].x) - sig*u[i-1]) / p;
+ }
+ float qn = 0.f;
+ float un = 0.f;
+
+ m_Y2.push_back((un-qn*u[len-2]) / (qn*m_Y2[len-2]-1.0f));
+
+ for (int i=len-2; i>=0; i--) {
+ m_Y2[i] = m_Y2[i]*m_Y2[i+1]+u[i];
}
}
diff --git a/src/base/CubicSpline.h b/src/base/CubicSpline.h
index 276f41c..a275413 100644
--- a/src/base/CubicSpline.h
+++ b/src/base/CubicSpline.h
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -23,6 +23,8 @@
#define _CubicSpline_H_
#include "../api.h"
+#include "../glm/glm.hpp"
+
#include <boost/shared_ptr.hpp>
#include <vector>
@@ -30,14 +32,18 @@ namespace avg {
class AVG_API CubicSpline {
public:
- CubicSpline(const std::vector<double>& x, const std::vector<double>& y);
+ CubicSpline(const std::vector<float>& x, const std::vector<float>& y,
+ bool bLoop=false);
+ CubicSpline(const std::vector<glm::vec2>& pts, bool bLoop=false);
virtual ~CubicSpline();
- double interpolate(double orig);
+ float interpolate(float orig);
private:
- std::vector<double> m_X;
- std::vector<double> m_Y;
+ void init();
+
+ std::vector<glm::vec2> m_Pts;
+ std::vector<float> m_Y2; // Second derivatives
};
typedef boost::shared_ptr<CubicSpline> CubicSplinePtr;
diff --git a/src/base/DAG.cpp b/src/base/DAG.cpp
new file mode 100644
index 0000000..85ab8bb
--- /dev/null
+++ b/src/base/DAG.cpp
@@ -0,0 +1,130 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "DAG.h"
+
+#include "Exception.h"
+
+#include <boost/enable_shared_from_this.hpp>
+
+using namespace std;
+
+namespace avg {
+
+class AVG_API DAGNode: public boost::enable_shared_from_this<DAGNode>
+{
+public:
+ DAGNode(long vertexID, const std::set<long>& outgoingIDs);
+ void resolveIDs(DAG* pDAG);
+
+ long m_VertexID;
+ std::set<long> m_OutgoingIDs;
+ std::set<DAGNodePtr> m_pOutgoingNodes;
+ std::set<DAGNodePtr> m_pIncomingNodes;
+};
+
+
+DAGNode::DAGNode(long vertexID, const set<long>& outgoingIDs)
+{
+ m_VertexID = vertexID;
+ m_OutgoingIDs = outgoingIDs;
+}
+
+void DAGNode::resolveIDs(DAG* pDAG)
+{
+ set<long>::iterator it;
+ for (it=m_OutgoingIDs.begin(); it!=m_OutgoingIDs.end(); ++it) {
+ long outgoingID = *it;
+ DAGNodePtr pDestNode = pDAG->findNode(outgoingID);
+ m_pOutgoingNodes.insert(pDestNode);
+ pDestNode->m_pIncomingNodes.insert(shared_from_this());
+ }
+ m_OutgoingIDs.clear();
+}
+
+
+DAG::DAG()
+{
+}
+
+DAG::~DAG()
+{
+}
+
+void DAG::addNode(long vertexID, const set<long>& outgoingIDs)
+{
+ DAGNode* pNode = new DAGNode(vertexID, outgoingIDs);
+ m_pNodes.insert(DAGNodePtr(pNode));
+}
+
+void DAG::sort(vector<long>& pResults)
+{
+ resolveIDs();
+ while (!m_pNodes.empty()) {
+ DAGNodePtr pCurNode = findStartNode(*m_pNodes.begin());
+ removeNode(pCurNode);
+ pResults.push_back(pCurNode->m_VertexID);
+ }
+}
+
+void DAG::resolveIDs()
+{
+ set<DAGNodePtr>::iterator it;
+ for (it=m_pNodes.begin(); it!=m_pNodes.end(); ++it) {
+ (*it)->resolveIDs(this);
+ }
+}
+
+DAGNodePtr DAG::findNode(long id)
+{
+ set<DAGNodePtr>::iterator it;
+ for (it=m_pNodes.begin(); it!=m_pNodes.end(); ++it) {
+ if ((*it)->m_VertexID == id) {
+ return (*it);
+ }
+ }
+ AVG_ASSERT(false);
+ return DAGNodePtr();
+}
+
+void DAG::removeNode(DAGNodePtr pNode)
+{
+ set<DAGNodePtr>::iterator it;
+ for (it=pNode->m_pOutgoingNodes.begin(); it!=pNode->m_pOutgoingNodes.end(); ++it) {
+ DAGNodePtr pDestNode = *it;
+ pDestNode->m_pIncomingNodes.erase(pNode);
+ }
+ m_pNodes.erase(pNode);
+}
+
+DAGNodePtr DAG::findStartNode(DAGNodePtr pNode, unsigned depth)
+{
+ if (pNode->m_pIncomingNodes.empty()) {
+ return pNode;
+ } else {
+ if (depth > m_pNodes.size()) {
+ throw Exception(AVG_ERR_INVALID_ARGS, "cyclic graph");
+ }
+ return findStartNode(*pNode->m_pIncomingNodes.begin(), depth+1);
+ }
+}
+
+}
diff --git a/src/base/Triple.h b/src/base/DAG.h
index 879a809..929ecd2 100644
--- a/src/base/Triple.h
+++ b/src/base/DAG.h
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -19,48 +19,46 @@
// Current versions can be found at www.libavg.de
//
-#ifndef _Triple_H_
-#define _Triple_H_
+#ifndef _DAG_H_
+#define _DAG_H_
#include "../api.h"
-#include <ostream>
-#include <istream>
+#include <set>
#include <vector>
-
-// Fix for non-C99 win compilers up to MSVC++2008
-#if defined _MSC_VER && _MSC_VER <= 1500
-#define isinf(x) (!_finite(x))
-#define isnan(x) (_isnan(x))
-#endif
+#include <boost/shared_ptr.hpp>
namespace avg {
-template<class NUM>
-class AVG_TEMPLATE_API Triple
+class DAG;
+class DAGNode;
+typedef boost::shared_ptr<DAGNode> DAGNodePtr;
+
+// Directed Acyclic Graph class.
+// Only useful for sorting. The process of sorting destroys the DAG.
+class AVG_API DAG
{
public:
- NUM x;
- NUM y;
- NUM z;
+ DAG();
+ virtual ~DAG();
- Triple();
- Triple(NUM X, NUM Y, NUM Z);
- Triple(const Triple<NUM> & p);
- Triple(const std::vector<NUM>& v);
- ~Triple();
-
-};
+ void addNode(long vertexID, const std::set<long>& outgoingIDs);
+ void sort(std::vector<long>& pResults);
-template<class NUM>
-std::ostream& operator<<(std::ostream& os, const Triple<NUM> &p);
+private:
+ friend class DAGNode;
-template<class NUM>
-std::istream& operator>>(std::istream& is, Triple<NUM>& p);
+ void resolveIDs();
+ DAGNodePtr findNode(long pID);
+ void removeNode(DAGNodePtr pNode);
+ DAGNodePtr findStartNode(DAGNodePtr pNode, unsigned depth=0);
-typedef Triple<double> DTriple;
-typedef Triple<int> IntTriple;
+ std::set<DAGNodePtr> m_pNodes;
+};
}
-#endif
+#endif
+
+
+
diff --git a/src/base/DirEntry.cpp b/src/base/DirEntry.cpp
index 7da4edb..c654e50 100644
--- a/src/base/DirEntry.cpp
+++ b/src/base/DirEntry.cpp
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
diff --git a/src/base/DirEntry.h b/src/base/DirEntry.h
index d23388d..ac2fca9 100644
--- a/src/base/DirEntry.h
+++ b/src/base/DirEntry.h
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
diff --git a/src/base/Directory.cpp b/src/base/Directory.cpp
index dda1e8d..bc40ecc 100644
--- a/src/base/Directory.cpp
+++ b/src/base/Directory.cpp
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
diff --git a/src/base/Directory.h b/src/base/Directory.h
index 1edb139..f75107d 100644
--- a/src/base/Directory.h
+++ b/src/base/Directory.h
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
diff --git a/src/base/DlfcnWrapper.cpp b/src/base/DlfcnWrapper.cpp
index 8dfbfbc..f8011b1 100644
--- a/src/base/DlfcnWrapper.cpp
+++ b/src/base/DlfcnWrapper.cpp
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
diff --git a/src/base/DlfcnWrapper.h b/src/base/DlfcnWrapper.h
index 4cc0e98..883fb37 100644
--- a/src/base/DlfcnWrapper.h
+++ b/src/base/DlfcnWrapper.h
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
diff --git a/src/base/Exception.cpp b/src/base/Exception.cpp
index e694320..eb4f03c 100644
--- a/src/base/Exception.cpp
+++ b/src/base/Exception.cpp
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -27,23 +27,29 @@
#include <cstdlib>
#include <sstream>
+#ifdef WIN32
+#include <intrin.h>
+#endif
+
using namespace std;
namespace avg {
Exception::Exception(int code, const string& sErr)
- : m_Code (code),
+ : std::exception(),
+ m_Code (code),
m_sErr (sErr)
{
}
Exception::Exception(const Exception& ex)
- : m_Code (ex.getCode()),
+ : std::exception(),
+ m_Code (ex.getCode()),
m_sErr (ex.getStr())
{
}
-Exception::~Exception()
+Exception::~Exception() throw()
{
}
@@ -57,23 +63,17 @@ const string& Exception::getStr() const
return m_sErr;
}
-void fatalError(const string& sMsg)
+const char* Exception::what() const throw()
{
- AVG_TRACE(Logger::ERROR, "Internal error: "+sMsg+" Aborting.");
- exit(-1);
+ return m_sErr.c_str();
}
void debugBreak()
{
#ifdef _WIN32
- __asm int 3;
-#elseifdef __x86_64
- asm("int $3");
-#elseifdef __i386__
- asm("int $3");
+ __debugbreak();
#else
- //deliberately dereferencing a null pointer should break in most debuggers
- *((char *)0) = 0;
+ __builtin_trap();
#endif
}
diff --git a/src/base/Exception.h b/src/base/Exception.h
index 1524cb5..b28dc1a 100644
--- a/src/base/Exception.h
+++ b/src/base/Exception.h
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -24,6 +24,7 @@
#include "../api.h"
#include <string>
+#include <exception>
#define AVG_ERR_UNKNOWN -1
#define AVG_ERR_XML_PARSE 1
@@ -57,24 +58,25 @@
#define AVG_ERR_DEPRECATED 31
#define AVG_ERR_ASSERT_FAILED 32
#define AVG_ERR_MT_INIT 33
+#define AVG_ERR_DEBUG_CONTEXT_FAILED 34
namespace avg {
-class AVG_API Exception
+class AVG_API Exception: public std::exception
{
public:
Exception(int code, const std::string& sErr = "");
Exception(const Exception& ex);
- virtual ~Exception();
+ virtual ~Exception() throw();
virtual int getCode() const;
virtual const std::string& getStr() const;
+ virtual const char* what() const throw();
private:
int m_Code;
std::string m_sErr;
};
-void AVG_API fatalError(const std::string& sMsg);
void AVG_API debugBreak();
void AVG_API avgAssert(bool b, const char * pszFile, int line, const char * pszReason=0);
diff --git a/src/base/FileHelper.cpp b/src/base/FileHelper.cpp
index 9e38e51..d9221c4 100644
--- a/src/base/FileHelper.cpp
+++ b/src/base/FileHelper.cpp
@@ -1,6 +1,6 @@
//
-// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,6 @@
//
#include "FileHelper.h"
-#include "ConfigMgr.h"
#include "Exception.h"
#ifndef _WIN32
@@ -32,7 +31,9 @@
#include <sys/stat.h>
#include <string.h>
#include <unistd.h>
+#include <stdlib.h>
+#include <vector>
#include <map>
#include <cstring>
#include <iostream>
@@ -113,7 +114,7 @@ bool isAbsPath(const std::string& path)
#else
return path[0] == '/';
#endif
-
+
}
bool fileExists(const string& sFilename)
@@ -155,7 +156,7 @@ void writeWholeFile(const string& sFilename, const string& sContent)
void copyFile(const string& sSourceFile, const string& sDestFile)
{
string sData;
-
+
readWholeFile(sSourceFile, sData);
writeWholeFile(sDestFile, sData);
}
diff --git a/src/base/FileHelper.h b/src/base/FileHelper.h
index c5724f5..f367d0b 100644
--- a/src/base/FileHelper.h
+++ b/src/base/FileHelper.h
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -27,20 +27,20 @@
namespace avg {
-std::string getPath(const std::string& sFilename);
-std::string getFilenamePart(const std::string& sFilename);
-std::string getExtension(const std::string& sFilename);
-std::string getCWD();
+std::string AVG_API getPath(const std::string& sFilename);
+std::string AVG_API getFilenamePart(const std::string& sFilename);
+std::string AVG_API getExtension(const std::string& sFilename);
+std::string AVG_API getCWD();
-bool isAbsPath(const std::string& path);
+bool AVG_API isAbsPath(const std::string& path);
-bool fileExists(const std::string& sFilename);
+bool AVG_API fileExists(const std::string& sFilename);
-void readWholeFile(const std::string& sFilename, std::string& sContents);
+void AVG_API readWholeFile(const std::string& sFilename, std::string& sContents);
-void writeWholeFile(const std::string& sFilename, const std::string& sContent);
+void AVG_API writeWholeFile(const std::string& sFilename, const std::string& sContent);
-void copyFile(const std::string& sSourceFile, const std::string& sDestFile);
+void AVG_API copyFile(const std::string& sSourceFile, const std::string& sDestFile);
#ifdef WIN32
diff --git a/src/base/GLMHelper.cpp b/src/base/GLMHelper.cpp
new file mode 100644
index 0000000..e4b0f43
--- /dev/null
+++ b/src/base/GLMHelper.cpp
@@ -0,0 +1,183 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "GLMHelper.h"
+#include "StringHelper.h"
+#include "MathHelper.h"
+
+#include "../glm/gtx/rotate_vector.hpp"
+
+using namespace std;
+
+namespace avg {
+
+glm::vec2 getRotated(const glm::vec2& vec, float angle)
+{
+ return glm::rotate(vec, angle*180/PI);
+}
+
+glm::vec2 getRotatedPivot(const glm::vec2& vec, float angle, const glm::vec2& pivot)
+{
+ // translate pivot to origin
+ glm::vec2 translated = vec - pivot;
+
+ // calculate rotated coordinates about the origin
+ glm::vec2 rotated = glm::rotate(translated, angle*180/PI);
+
+ // re-translate pivot to original position
+ rotated += pivot;
+
+ return rotated;
+}
+
+float getAngle(const glm::vec2& vec)
+{
+ return float(atan2(double(vec.y), double(vec.x)));
+}
+
+glm::vec2 fromPolar(float angle, float radius)
+{
+ return glm::vec2(cos(angle)*radius, sin(angle)*radius);
+}
+
+template<class NUM>
+bool almostEqual(const glm::detail::tvec2<NUM>& v1, const glm::detail::tvec2<NUM>& v2)
+{
+ return (fabs(v1.x-v2.x)+fabs(v1.y-v2.y)) < 0.0001;
+}
+
+template<class NUM>
+bool almostEqual(const glm::detail::tvec4<NUM>& v1, const glm::detail::tvec4<NUM>& v2)
+{
+ return (fabs(v1.x-v2.x)+fabs(v1.y-v2.y)+fabs(v1.z-v2.z)+fabs(v1.w-v2.w)) < 0.0001;
+}
+
+template<class NUM>
+std::ostream& operator<<( std::ostream& os, const glm::detail::tvec2<NUM> &v)
+{
+ os << "(" << v.x << "," << v.y << ")";
+ return os;
+}
+
+template<class NUM>
+std::ostream& operator<<( std::ostream& os, const glm::detail::tvec3<NUM> &v)
+{
+ os << "(" << v.x << "," << v.y << "," << v.z << ")";
+ return os;
+}
+
+template<class NUM>
+std::ostream& operator<<( std::ostream& os, const glm::detail::tvec4<NUM> &v)
+{
+ os << "(" << v.x << "," << v.y << "," << v.z << ", " << v.a << ")";
+ return os;
+}
+
+template<class NUM>
+std::ostream& operator<<( std::ostream& os, const glm::detail::tmat4x4<NUM> &m)
+{
+ os << "(" << m[0] << ", " << endl <<
+ m[1] << ", " << endl <<
+ m[2] << ", " << endl <<
+ m[3] << ", " << endl << ")";
+ return os;
+}
+
+template<class NUM>
+std::istream& operator>>(std::istream& is, glm::detail::tvec2<NUM>& p)
+{
+ skipToken(is, '(');
+ is >> p.x;
+ skipToken(is, ',');
+ is >> p.y;
+ skipToken(is, ')');
+ return is;
+}
+
+template<class NUM>
+std::istream& operator>>(std::istream& is, glm::detail::tvec3<NUM>& p)
+{
+ skipToken(is, '(');
+ is >> p.x;
+ skipToken(is, ',');
+ is >> p.y;
+ skipToken(is, ',');
+ is >> p.z;
+ skipToken(is, ')');
+ return is;
+}
+
+glm::vec2 stringToVec2(const std::string& s)
+{
+ glm::vec2 pt;
+ fromString(s, pt);
+ return pt;
+}
+
+glm::vec3 stringToVec3(const std::string& s)
+{
+ glm::vec3 pt;
+ fromString(s, pt);
+ return pt;
+}
+
+glm::ivec3 stringToIVec3(const std::string& s)
+{
+ glm::ivec3 pt;
+ fromString(s, pt);
+ return pt;
+}
+
+
+template AVG_TEMPLATE_API std::ostream& operator<<(std::ostream& os, const glm::detail::tvec2<int> &p);
+template AVG_TEMPLATE_API std::ostream& operator<<(std::ostream& os, const glm::detail::tvec2<float> &p);
+template AVG_TEMPLATE_API std::ostream& operator<<(std::ostream& os, const glm::detail::tvec2<double> &p);
+
+template AVG_TEMPLATE_API std::istream& operator>>(std::istream& is, glm::detail::tvec2<int>& p);
+template AVG_TEMPLATE_API std::istream& operator>>(std::istream& is, glm::detail::tvec2<float>& p);
+template AVG_TEMPLATE_API std::istream& operator>>(std::istream& is, glm::detail::tvec2<double>& p);
+
+template AVG_TEMPLATE_API std::ostream& operator<<(std::ostream& os, const glm::detail::tvec3<int> &p);
+template AVG_TEMPLATE_API std::ostream& operator<<(std::ostream& os, const glm::detail::tvec3<float> &p);
+template AVG_TEMPLATE_API std::ostream& operator<<(std::ostream& os, const glm::detail::tvec3<double> &p);
+
+template AVG_TEMPLATE_API std::istream& operator>>(std::istream& is, glm::detail::tvec3<int>& p);
+template AVG_TEMPLATE_API std::istream& operator>>(std::istream& is, glm::detail::tvec3<float>& p);
+template AVG_TEMPLATE_API std::istream& operator>>(std::istream& is, glm::detail::tvec3<double>& p);
+
+template AVG_TEMPLATE_API std::ostream& operator<<(std::ostream& os, const glm::detail::tvec4<int> &p);
+template AVG_TEMPLATE_API std::ostream& operator<<(std::ostream& os, const glm::detail::tvec4<float> &p);
+template AVG_TEMPLATE_API std::ostream& operator<<(std::ostream& os, const glm::detail::tvec4<double> &p);
+
+template AVG_TEMPLATE_API std::ostream& operator<<(std::ostream& os, const glm::detail::tmat4x4<float> &p);
+template AVG_TEMPLATE_API std::ostream& operator<<(std::ostream& os,
+ const glm::detail::tmat4x4<double> &p);
+
+template AVG_TEMPLATE_API bool almostEqual(const glm::detail::tvec2<float>& v1,
+ const glm::detail::tvec2<float>& v2);
+template AVG_TEMPLATE_API bool almostEqual(const glm::detail::tvec2<double>& v1,
+ const glm::detail::tvec2<double>& v2);
+template AVG_TEMPLATE_API bool almostEqual(const glm::detail::tvec4<float>& v1,
+ const glm::detail::tvec4<float>& v2);
+template AVG_TEMPLATE_API bool almostEqual(const glm::detail::tvec4<double>& v1,
+ const glm::detail::tvec4<double>& v2);
+}
+
diff --git a/src/base/GLMHelper.h b/src/base/GLMHelper.h
new file mode 100644
index 0000000..4af8991
--- /dev/null
+++ b/src/base/GLMHelper.h
@@ -0,0 +1,70 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _GLMHelper_H_
+#define _GLMHelper_H_
+
+#include "../api.h"
+
+#include "../glm/glm.hpp"
+#include "../glm/gtc/matrix_transform.hpp"
+#include "../glm/gtc/type_ptr.hpp"
+
+#include <iostream>
+#include <vector>
+
+namespace avg {
+
+glm::vec2 getRotated(const glm::vec2& vec, float angle);
+glm::vec2 getRotatedPivot(const glm::vec2& vec, float angle,
+ const glm::vec2& pivot=glm::vec2(0,0));
+float getAngle(const glm::vec2& vec);
+glm::vec2 fromPolar(float angle, float radius);
+
+template<class NUM>
+bool almostEqual(const glm::detail::tvec2<NUM>& v1, const glm::detail::tvec2<NUM>& v2);
+template<class NUM>
+bool almostEqual(const glm::detail::tvec4<NUM>& v1, const glm::detail::tvec4<NUM>& v2);
+
+template<class NUM>
+std::ostream& operator<<(std::ostream& os, const glm::detail::tvec2<NUM> &v);
+template<class NUM>
+std::ostream& operator<<(std::ostream& os, const glm::detail::tvec3<NUM> &v);
+template<class NUM>
+std::ostream& operator<<(std::ostream& os, const glm::detail::tvec4<NUM> &v);
+template<class NUM>
+std::ostream& operator<<(std::ostream& os, const glm::detail::tmat4x4<NUM> &v);
+
+template<class NUM>
+std::istream& operator>>(std::istream& is, glm::detail::tvec2<NUM>& p);
+template<class NUM>
+std::istream& operator>>(std::istream& is, glm::detail::tvec3<NUM>& p);
+
+typedef glm::ivec2 IntPoint;
+typedef std::vector<glm::vec2> Vec2Vector;
+
+glm::vec2 stringToVec2(const std::string& s);
+glm::vec3 stringToVec3(const std::string& s);
+glm::ivec3 stringToIVec3(const std::string& s);
+
+}
+
+#endif
diff --git a/src/base/GeomHelper.cpp b/src/base/GeomHelper.cpp
index c1fa7a8..da167ad 100644
--- a/src/base/GeomHelper.cpp
+++ b/src/base/GeomHelper.cpp
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -28,31 +28,31 @@ using namespace std;
namespace avg {
-DLineSegment::DLineSegment(const DPoint& pt0, const DPoint& pt1)
+LineSegment::LineSegment(const glm::vec2& pt0, const glm::vec2& pt1)
: p0(pt0),
p1(pt1)
{
}
-bool DLineSegment::isPointOver(const DPoint& pt)
+bool LineSegment::isPointOver(const glm::vec2& pt)
{
- DPoint c = pt - p0; // DPoint from a to Point
- DPoint v = (p1 - p0);
- double d = v.getNorm(); // Length of the line segment
- v /= d; // Unit DPoint from a to b
- double t = dotProduct(v, c); // Intersection point Distance from a
+ glm::vec2 c = pt - p0;
+ glm::vec2 v = (p1 - p0);
+ float d = glm::length(v);
+ v /= d;
+ float t = glm::dot(v, c);
return (t >= 0 && t <= d);
}
// Code adapted from Antonio, Franklin, "Faster Line Segment Intersection,"
// Graphics Gems III (David Kirk, ed.), Academic Press, pp. 199-202, 1992.
-bool lineSegmentsIntersect(const DLineSegment& l0, const DLineSegment& l1)
+bool lineSegmentsIntersect(const LineSegment& l0, const LineSegment& l1)
{
- double xdiff0 = l0.p1.x-l0.p0.x;
- double xdiff1 = l1.p0.x-l1.p1.x;
+ float xdiff0 = l0.p1.x-l0.p0.x;
+ float xdiff1 = l1.p0.x-l1.p1.x;
- double x1lo, x1hi;
+ float x1lo, x1hi;
/* X bound box test*/
if (xdiff0 < 0) {
@@ -72,10 +72,10 @@ bool lineSegmentsIntersect(const DLineSegment& l0, const DLineSegment& l1)
}
}
- double ydiff0 = l0.p1.y-l0.p0.y;
- double ydiff1 = l1.p0.y-l1.p1.y;
+ float ydiff0 = l0.p1.y-l0.p0.y;
+ float ydiff1 = l1.p0.y-l1.p1.y;
- double y1lo, y1hi;
+ float y1lo, y1hi;
/* Y bound box test*/
if (ydiff0 < 0) {
@@ -95,10 +95,10 @@ bool lineSegmentsIntersect(const DLineSegment& l0, const DLineSegment& l1)
}
}
- double Cx = l0.p0.x-l1.p0.x;
- double Cy = l0.p0.y-l1.p0.y;
- double d = ydiff1*Cx - xdiff1*Cy; /* alpha numerator*/
- double f = ydiff0*xdiff1 - xdiff0*ydiff1; /* both denominator*/
+ float Cx = l0.p0.x-l1.p0.x;
+ float Cy = l0.p0.y-l1.p0.y;
+ float d = ydiff1*Cx - xdiff1*Cy; /* alpha numerator*/
+ float f = ydiff0*xdiff1 - xdiff0*ydiff1; /* both denominator*/
if (f > 0) { /* alpha tests*/
if (d < 0 || d > f) {
return false;
@@ -109,7 +109,7 @@ bool lineSegmentsIntersect(const DLineSegment& l0, const DLineSegment& l1)
}
}
- double e = xdiff0*Cy - ydiff0*Cx; /* beta numerator*/
+ float e = xdiff0*Cy - ydiff0*Cx; /* beta numerator*/
if(f > 0) { /* beta tests*/
if (e < 0 || e > f) {
return false;
@@ -127,7 +127,7 @@ bool lineSegmentsIntersect(const DLineSegment& l0, const DLineSegment& l1)
}
// /*compute intersection coordinates*/
-// double num = d*xdiff0; /* numerator */
+// float num = d*xdiff0; /* numerator */
// offset = SAME_SIGNS(num,f) ? f/2 : -f/2; /* round direction*/
// *x = x1 + (num+offset) / f; /* intersection x */
//
@@ -142,7 +142,7 @@ bool lineSegmentsIntersect(const DLineSegment& l0, const DLineSegment& l1)
// http://www.ecse.rpi.edu/Homepages/wrf/Research/Short_Notes/pnpoly.html.
// Precomputing a bounding box for the polygon would speed this up a lot,
// but the function hasn't shown up on any profiles so far.
-bool pointInPolygon(const DPoint& pt, const vector<DPoint>& poly)
+bool pointInPolygon(const glm::vec2& pt, const vector<glm::vec2>& poly)
{
if (poly.size() < 3) {
return false;
@@ -159,16 +159,16 @@ bool pointInPolygon(const DPoint& pt, const vector<DPoint>& poly)
return bPtInPoly;
}
-DPoint getLineLineIntersection(const DPoint& p1, const DPoint& v1, const DPoint& p2,
- const DPoint& v2)
+glm::vec2 getLineLineIntersection(const glm::vec2& p1, const glm::vec2& v1,
+ const glm::vec2& p2, const glm::vec2& v2)
{
- double denom = v2.y*v1.x-v2.x*v1.y;
+ float denom = v2.y*v1.x-v2.x*v1.y;
if (fabs(denom) < 0.0000001) {
// If the lines are parallel or coincident, we just return p2!
return p2;
}
- double numer = v2.x*(p1.y-p2.y) - v2.y*(p1.x-p2.x);
- double ua = numer/denom;
+ float numer = v2.x*(p1.y-p2.y) - v2.y*(p1.x-p2.x);
+ float ua = numer/denom;
return p1+ua*v1;
diff --git a/src/base/GeomHelper.h b/src/base/GeomHelper.h
index 272a8ef..5774231 100644
--- a/src/base/GeomHelper.h
+++ b/src/base/GeomHelper.h
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -23,27 +23,28 @@
#define _GeomHelper_H_
#include "../api.h"
-#include "Point.h"
+
+#include "../glm/glm.hpp"
#include <vector>
namespace avg {
-struct AVG_API DLineSegment {
+struct AVG_API LineSegment {
public:
- DLineSegment(const DPoint& pt0, const DPoint& pt1);
- DPoint p0;
- DPoint p1;
+ LineSegment(const glm::vec2& pt0, const glm::vec2& pt1);
+ glm::vec2 p0;
+ glm::vec2 p1;
- bool isPointOver(const DPoint& pt);
+ bool isPointOver(const glm::vec2& pt);
};
-bool AVG_API lineSegmentsIntersect(const DLineSegment& l0, const DLineSegment& l1);
+bool AVG_API lineSegmentsIntersect(const LineSegment& l0, const LineSegment& l1);
-bool AVG_API pointInPolygon(const DPoint& pt, const std::vector<DPoint>& poly);
+bool AVG_API pointInPolygon(const glm::vec2& pt, const std::vector<glm::vec2>& poly);
-DPoint AVG_API getLineLineIntersection(const DPoint& p1, const DPoint& v1, const DPoint& p2,
- const DPoint& v2);
+glm::vec2 AVG_API getLineLineIntersection(const glm::vec2& p1, const glm::vec2& v1,
+ const glm::vec2& p2, const glm::vec2& v2);
}
#endif
diff --git a/src/base/IFrameEndListener.h b/src/base/IFrameEndListener.h
index 5f172d2..6147dbe 100644
--- a/src/base/IFrameEndListener.h
+++ b/src/base/IFrameEndListener.h
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
diff --git a/src/base/Matrix3x4.h b/src/base/ILogSink.h
index 62a0222..de4c1da 100644
--- a/src/base/Matrix3x4.h
+++ b/src/base/ILogSink.h
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -17,39 +17,36 @@
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// Current versions can be found at www.libavg.de
-//
-#ifndef _Matrix3x4_H_
-#define _Matrix3x4_H_
+#ifndef _ILOGHANDLER_H_
+#define _ILOGHANDLER_H_
+
+#include "UTF8String.h"
+
+#ifdef _WIN32
+#include <time.h>
+#else
+#include <sys/time.h>
+#endif
-#include "../api.h"
+#include <boost/shared_ptr.hpp>
-#include "Triple.h"
+using namespace std;
-#include <iostream>
+namespace avg{
-namespace avg {
-
-class AVG_API Matrix3x4 {
+typedef unsigned severity_t;
+typedef UTF8String category_t;
+
+class AVG_API ILogSink
+{
public:
- float val[3][4];
-
- Matrix3x4();
- Matrix3x4(const float *);
- static Matrix3x4 createTranslate(float x, float y, float z);
- static Matrix3x4 createTranslate(const DTriple& tr);
- static Matrix3x4 createScale(float x, float y, float z);
- static Matrix3x4 createScale(const DTriple& tr);
+ virtual void logMessage(const tm* pTime, unsigned millis, const category_t& category,
+ severity_t severity, const UTF8String& sMsg) = 0;
- const Matrix3x4& operator *=(const Matrix3x4& mat);
-
-private:
- void setIdent();
};
-bool almostEqual(const Matrix3x4& mat1, const Matrix3x4& mat2);
-
-std::ostream& operator<<(std::ostream& os, const Matrix3x4& mat);
+typedef boost::shared_ptr<ILogSink> LogSinkPtr;
}
diff --git a/src/base/IPlaybackEndListener.h b/src/base/IPlaybackEndListener.h
index 08d8c41..f505177 100644
--- a/src/base/IPlaybackEndListener.h
+++ b/src/base/IPlaybackEndListener.h
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
diff --git a/src/base/IPreRenderListener.h b/src/base/IPreRenderListener.h
index 5fe4d82..32c244e 100644
--- a/src/base/IPreRenderListener.h
+++ b/src/base/IPreRenderListener.h
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
diff --git a/src/base/Logger.cpp b/src/base/Logger.cpp
index 286f76c..dd7efe1 100644
--- a/src/base/Logger.cpp
+++ b/src/base/Logger.cpp
@@ -1,6 +1,6 @@
//
-// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -20,77 +20,104 @@
//
#include "Logger.h"
-
-#include "OSHelper.h"
#include "Exception.h"
+#include "StandardLogSink.h"
+#include "OSHelper.h"
+
+#include <boost/algorithm/string.hpp>
#ifdef _WIN32
#include <Winsock2.h>
-#undef ERROR
-#undef WARNING
#include <time.h>
#include <Mmsystem.h>
+#undef ERROR
#else
#include <sys/time.h>
#include <syslog.h>
#endif
#include <iostream>
#include <iomanip>
-#include <boost/thread.hpp>
using namespace std;
+namespace ba = boost::algorithm;
namespace avg {
+ const severity_t Logger::severity::CRITICAL = 50;
+ const severity_t Logger::severity::ERROR = 40;
+ const severity_t Logger::severity::WARNING = 30;
+ const severity_t Logger::severity::INFO = 20;
+ const severity_t Logger::severity::DEBUG = 10;
+ const severity_t Logger::severity::NONE = 0;
-const long Logger::NONE=0;
-const long Logger::BLTS=1;
-const long Logger::PROFILE=2;
-const long Logger::PROFILE_LATEFRAMES=4;
-const long Logger::PROFILE_VIDEO=8;
-const long Logger::EVENTS=16;
-const long Logger::EVENTS2=32;
-const long Logger::CONFIG=64;
-const long Logger::WARNING=128;
-const long Logger::ERROR=256;
-const long Logger::MEMORY=512;
-const long Logger::APP=1024;
-const long Logger::PLUGIN=2048;
-const long Logger::PLAYER=4096;
-
-Logger* Logger::m_pLogger = 0;
-boost::mutex log_Mutex;
+ const category_t Logger::category::NONE = UTF8String("NONE");
+ const category_t Logger::category::PROFILE = UTF8String("PROFILE");
+ const category_t Logger::category::PROFILE_VIDEO = UTF8String("PROFILE_V");
+ const category_t Logger::category::EVENTS = UTF8String("EVENTS");
+ const category_t Logger::category::CONFIG = UTF8String("CONFIG");
+ const category_t Logger::category::MEMORY = UTF8String("MEMORY");
+ const category_t Logger::category::APP = UTF8String("APP");
+ const category_t Logger::category::PLUGIN = UTF8String("PLUGIN");
+ const category_t Logger::category::PLAYER = UTF8String("PLAYER");
+ const category_t Logger::category::SHADER = UTF8String("SHADER");
+ const category_t Logger::category::DEPRECATION = UTF8String("DEPREC");
+
+namespace {
+ Logger* s_pLogger = 0;
+ boost::mutex s_logMutex;
+ boost::mutex s_traceMutex;
+ boost::mutex s_sinkMutex;
+ boost::mutex s_removeStdSinkMutex;
+}
+
+boost::mutex Logger::m_CategoryMutex;
Logger * Logger::get()
{
-
- if (!m_pLogger) {
- boost::mutex::scoped_lock Lock(log_Mutex);
- m_pLogger = new Logger;
+ lock_guard lock(s_logMutex);
+ if (!s_pLogger) {
+ s_pLogger = new Logger;
}
- return m_pLogger;
+ return s_pLogger;
}
Logger::Logger()
{
- m_Flags = ERROR | WARNING | APP;
+ m_Severity = severity::WARNING;
+ string sEnvSeverity;
+ bool bEnvSeveritySet = getEnv("AVG_LOG_SEVERITY", sEnvSeverity);
+ if(bEnvSeveritySet) {
+ m_Severity = Logger::stringToSeverity(sEnvSeverity);
+ }
+ setupCategory();
+
string sEnvCategories;
bool bEnvSet = getEnv("AVG_LOG_CATEGORIES", sEnvCategories);
if (bEnvSet) {
- m_Flags = ERROR | APP;
- bool bDone = false;
- string sCategory;
- do {
- string::size_type pos = sEnvCategories.find(":");
- if (pos == string::npos) {
- sCategory = sEnvCategories;
- bDone = true;
+ vector<string> sCategories;
+ ba::split(sCategories, sEnvCategories, ba::is_any_of(" "), ba::token_compress_on);
+ vector<string>::iterator it;
+ for(it=sCategories.begin(); it!=sCategories.end(); it++) {
+ string::size_type pos = (*it).find(":");
+ string sCategory;
+ string sSeverity = "NONE";
+ if(pos == string::npos) {
+ sCategory = *it;
} else {
- sCategory = sEnvCategories.substr(0, pos);
- sEnvCategories = sEnvCategories.substr(pos+1);
+ vector<string> tmpValues;
+ ba::split( tmpValues, *it, ba::is_any_of(":"), ba::token_compress_on);
+ sCategory = tmpValues.at(0);
+ sSeverity = tmpValues.at(1);
}
- long category = stringToCategory(sCategory);
- m_Flags |= category;
- } while (!bDone);
+ severity_t severity = stringToSeverity(sSeverity);
+ configureCategory(sCategory, severity);
+ }
+ }
+
+ string sDummy;
+ bool bEnvOmitStdErr = getEnv("AVG_LOG_OMIT_STDERR", sDummy);
+ if (!bEnvOmitStdErr) {
+ m_pStdSink = LogSinkPtr(new StandardLogSink);
+ addLogSink(m_pStdSink);
}
}
@@ -98,116 +125,156 @@ Logger::~Logger()
{
}
-void Logger::setCategories(int flags)
+void Logger::addLogSink(const LogSinkPtr& logSink)
{
- boost::mutex::scoped_lock Lock(log_Mutex);
- m_Flags = flags | ERROR | WARNING;
+ lock_guard lock(s_sinkMutex);
+ m_pSinks.push_back(logSink);
}
-
-void Logger::pushCategories()
+
+void Logger::removeLogSink(const LogSinkPtr& logSink)
{
- m_FlagStack.push_back(m_Flags);
+ lock_guard lock(s_sinkMutex);
+ std::vector<LogSinkPtr>::iterator it;
+ it = find(m_pSinks.begin(), m_pSinks.end(), logSink);
+ if ( it != m_pSinks.end() ) {
+ m_pSinks.erase(it);
+ }
}
-void Logger::popCategories()
+void Logger::removeStdLogSink()
{
- if (m_FlagStack.empty()) {
- throw Exception(AVG_ERR_OUT_OF_RANGE, "popCategories: Nothing to pop.");
+ lock_guard lock(s_removeStdSinkMutex);
+ if ( m_pStdSink.get()) {
+ removeLogSink(m_pStdSink);
+ m_pStdSink = LogSinkPtr();
}
- m_Flags = m_FlagStack.back();
- m_FlagStack.pop_back();
}
-void Logger::trace(int category, const UTF8String& sMsg)
+category_t Logger::configureCategory(category_t category, severity_t severity)
{
- boost::mutex::scoped_lock Lock(log_Mutex);
- if (category & m_Flags) {
- struct tm* pTime;
-#ifdef _WIN32
- __int64 now;
- _time64(&now);
- pTime = _localtime64(&now);
- DWORD tms = timeGetTime();
- unsigned millis = unsigned(tms % 1000);
-#else
- struct timeval time;
- gettimeofday(&time, NULL);
- pTime = localtime(&time.tv_sec);
- unsigned millis = time.tv_usec/1000;
-#endif
- char timeString[256];
- strftime(timeString, sizeof(timeString), "%y-%m-%d %H:%M:%S", pTime);
- cerr << "[" << timeString << "." <<
- setw(3) << setfill('0') << millis << setw(0) << "] ";
- cerr << categoryToString(category) << ": ";
- cerr << sMsg << endl;
- cerr.flush();
+ lock_guard lock(m_CategoryMutex);
+ severity = (severity == Logger::severity::NONE) ? m_Severity : severity;
+ UTF8String sCategory = boost::to_upper_copy(string(category));
+ CatToSeverityMap::iterator it;
+ it = m_CategorySeverities.find(sCategory);
+ if ( it != m_CategorySeverities.end()) {
+ m_CategorySeverities.erase(sCategory);
+ }
+ pair<const category_t, const severity_t> element(sCategory, severity);
+ m_CategorySeverities.insert(element);
+ return sCategory;
+}
+
+CatToSeverityMap Logger::getCategories()
+{
+ return m_CategorySeverities;
+}
+
+void Logger::trace(const UTF8String& sMsg, const category_t& category,
+ severity_t severity) const
+{
+ lock_guard lock(s_traceMutex);
+ struct tm* pTime;
+ #ifdef _WIN32
+ __int64 now;
+ _time64(&now);
+ pTime = _localtime64(&now);
+ DWORD tms = timeGetTime();
+ unsigned millis = unsigned(tms % 1000);
+ #else
+ struct timeval time;
+ gettimeofday(&time, NULL);
+ pTime = localtime(&time.tv_sec);
+ unsigned millis = time.tv_usec/1000;
+ #endif
+ lock_guard lockHandler(s_sinkMutex);
+ std::vector<LogSinkPtr>::const_iterator it;
+ for(it=m_pSinks.begin(); it!=m_pSinks.end(); ++it){
+ (*it)->logMessage(pTime, millis, category, severity, sMsg);
}
}
-const char * Logger::categoryToString(int category)
-{
- switch(category) {
- case BLTS:
- return "BLTS";
- case PROFILE:
- case PROFILE_LATEFRAMES:
- case PROFILE_VIDEO:
- return "PROFILE";
- case EVENTS:
- case EVENTS2:
- return "EVENTS";
- case CONFIG:
- return "CONFIG";
- case WARNING:
- return "WARNING";
- case ERROR:
- return "ERROR";
- case MEMORY:
- return "MEMORY";
- case APP:
- return "APP";
- case PLUGIN:
- return "PLUGIN";
- case PLAYER:
- return "PLAYER";
- default:
- return "UNKNOWN";
+void Logger::logDebug(const UTF8String& msg, const category_t& category) const
+{
+ log(msg, category, Logger::severity::DEBUG);
+}
+
+void Logger::logInfo(const UTF8String& msg, const category_t& category) const
+{
+ log(msg, category, Logger::severity::INFO);
+}
+
+void Logger::logWarning(const UTF8String& msg, const category_t& category) const
+{
+ log(msg, category, Logger::severity::WARNING);
+}
+
+void Logger::logError(const UTF8String& msg, const category_t& category) const
+{
+ log(msg, category, Logger::severity::ERROR);
+}
+
+void Logger::logCritical(const UTF8String& msg, const category_t& category) const
+{
+ log(msg, category, Logger::severity::CRITICAL);
+}
+
+void Logger::log(const UTF8String& msg, const category_t& category,
+ severity_t severity) const
+{
+ if(shouldLog(category, severity)) {
+ Logger::trace(msg, category, severity);
+ }
+}
+
+void Logger::setupCategory()
+{
+ configureCategory(category::NONE);
+ configureCategory(category::PROFILE);
+ configureCategory(category::PROFILE_VIDEO);
+ configureCategory(category::EVENTS);
+ configureCategory(category::CONFIG);
+ configureCategory(category::MEMORY);
+ configureCategory(category::APP);
+ configureCategory(category::PLUGIN);
+ configureCategory(category::PLAYER);
+ configureCategory(category::SHADER);
+ configureCategory(category::DEPRECATION);
+}
+
+severity_t Logger::stringToSeverity(const string& sSeverity)
+{
+ string severity = boost::to_upper_copy(string(sSeverity));
+ if (severity == "CRIT") {
+ return Logger::severity::CRITICAL;
+ } else if (severity == "ERR") {
+ return Logger::severity::ERROR;
+ } else if (severity == "WARN") {
+ return Logger::severity::WARNING;
+ } else if (severity == "INFO") {
+ return Logger::severity::INFO;
+ } else if (severity == "DBG") {
+ return Logger::severity::DEBUG;
+ } else if (severity == "NONE") {
+ return Logger::severity::NONE;
}
+ throw Exception(AVG_ERR_INVALID_ARGS, severity + " is an invalid log severity");
}
-int Logger::stringToCategory(const string& sCategory)
-{
- if (sCategory == "BLTS") {
- return BLTS;
- } else if (sCategory == "PROFILE") {
- return PROFILE;
- } else if (sCategory == "PROFILE_LATEFRAMES") {
- return PROFILE_LATEFRAMES;
- } else if (sCategory == "PROFILE_VIDEO") {
- return PROFILE_VIDEO;
- } else if (sCategory == "EVENTS") {
- return EVENTS;
- } else if (sCategory == "EVENTS2") {
- return EVENTS2;
- } else if (sCategory == "CONFIG") {
- return CONFIG;
- } else if (sCategory == "WARNING") {
- return WARNING;
- } else if (sCategory == "ERROR") {
- return ERROR;
- } else if (sCategory == "MEMORY") {
- return MEMORY;
- } else if (sCategory == "APP") {
- return APP;
- } else if (sCategory == "PLUGIN") {
- return PLUGIN;
- } else if (sCategory == "PLAYER") {
- return PLAYER;
- } else {
- throw Exception (AVG_ERR_INVALID_ARGS, "Unknown logger category " + sCategory
- + " set using AVG_LOG_CATEGORIES.");
+const char * Logger::severityToString(severity_t severity)
+{
+ if(severity == Logger::severity::CRITICAL) {
+ return "CRIT";
+ } else if(severity == Logger::severity::ERROR) {
+ return "ERR";
+ } else if(severity == Logger::severity::WARNING) {
+ return "WARN";
+ } else if(severity == Logger::severity::INFO) {
+ return "INFO";
+ } else if(severity == Logger::severity::DEBUG) {
+ return "DBG";
}
+ throw Exception(AVG_ERR_UNKNOWN, "Unkown log severity");
}
}
diff --git a/src/base/Logger.h b/src/base/Logger.h
index 34be8b8..197c0c2 100644
--- a/src/base/Logger.h
+++ b/src/base/Logger.h
@@ -1,6 +1,6 @@
//
-// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -19,68 +19,136 @@
// Current versions can be found at www.libavg.de
//
-#ifndef _Logger_H_
+#ifndef _Logger_H_
#define _Logger_H_
-#include "../api.h"
+#include "Exception.h"
+#include "ILogSink.h"
#include "UTF8String.h"
+#include "ThreadHelper.h"
+#include "../api.h"
+
+#include <boost/noncopyable.hpp>
+#include <boost/functional/hash.hpp>
+#include <boost/unordered_map.hpp>
#include <string>
#include <vector>
#include <sstream>
-namespace avg {
-
#ifdef ERROR
#undef ERROR
#endif
-class AVG_API Logger {
+namespace avg {
+
+typedef boost::unordered_map< const category_t, const severity_t > CatToSeverityMap;
+
+#ifdef _WIN32
+// non dll-interface class used as base for dll-interface class
+#pragma warning(disable:4275)
+#endif
+class AVG_API Logger: private boost::noncopyable {
public:
+ struct AVG_API severity
+ {
+ static const severity_t CRITICAL;
+ static const severity_t ERROR;
+ static const severity_t WARNING;
+ static const severity_t INFO;
+ static const severity_t DEBUG;
+ static const severity_t NONE;
+ };
+
+ struct AVG_API category
+ {
+ static const category_t NONE;
+ static const category_t PROFILE;
+ static const category_t PROFILE_VIDEO;
+ static const category_t EVENTS;
+ static const category_t CONFIG;
+ static const category_t MEMORY;
+ static const category_t APP;
+ static const category_t PLUGIN;
+ static const category_t PLAYER;
+ static const category_t SHADER;
+ static const category_t DEPRECATION;
+ };
+
static Logger* get();
virtual ~Logger();
-
- void setCategories(int flags);
- void pushCategories();
- void popCategories();
- void trace(int category, const UTF8String& sMsg);
- inline bool isFlagSet(int category) {
- return (category & m_Flags) != 0;
- }
- static const long NONE;
- static const long BLTS;
- static const long PROFILE;
- static const long PROFILE_LATEFRAMES;
- static const long PROFILE_VIDEO;
- static const long EVENTS;
- static const long EVENTS2;
- static const long CONFIG;
- static const long WARNING;
- static const long ERROR;
- static const long MEMORY;
- static const long APP;
- static const long PLUGIN;
- static const long PLAYER;
+ static severity_t stringToSeverity(const string& sSeverity);
+ static const char * severityToString(const severity_t severity);
+
+ void addLogSink(const LogSinkPtr& logSink);
+ void removeLogSink(const LogSinkPtr& logSink);
+ void removeStdLogSink();
+
+ category_t configureCategory(category_t category,
+ severity_t severity=severity::NONE);
+ CatToSeverityMap getCategories();
+
+ void trace(const UTF8String& sMsg, const category_t& category,
+ severity_t severity) const;
+ void logDebug(const UTF8String& msg,
+ const category_t& category=category::APP) const;
+ void logInfo(const UTF8String& msg,
+ const category_t& category=category::APP) const;
+ void logWarning(const UTF8String& msg,
+ const category_t& category=category::APP) const;
+ void logError(const UTF8String& msg,
+ const category_t& category=category::APP) const;
+ void logCritical(const UTF8String& msg,
+ const category_t& category=category::APP) const;
+ void log(const UTF8String& msg, const category_t& category=category::APP,
+ severity_t severity=severity::INFO) const;
+
+ inline bool shouldLog(const category_t& category, severity_t severity) const {
+ lock_guard lock(m_CategoryMutex);
+ try {
+ severity_t targetSeverity = m_CategorySeverities.at(category);
+ return (targetSeverity <= severity);
+ } catch (out_of_range e){
+ string msg("Unknown category: " + category);
+ throw Exception(AVG_ERR_INVALID_ARGS, msg);
+ }
+ }
private:
Logger();
- static const char * categoryToString(int category);
- int stringToCategory(const std::string& sCategory);
-
- static Logger* m_pLogger;
+ void setupCategory();
- int m_Flags;
- std::vector<int> m_FlagStack;
+ std::vector<LogSinkPtr> m_pSinks;
+ LogSinkPtr m_pStdSink;
+ CatToSeverityMap m_CategorySeverities;
+ severity_t m_Severity;
+ static boost::mutex m_CategoryMutex;
};
-#define AVG_TRACE(category, sMsg) { \
- if (Logger::get()->isFlagSet(category)) { \
- std::stringstream tmp(std::stringstream::in | std::stringstream::out); \
- tmp << sMsg; \
- Logger::get()->trace(category, tmp.str()); \
+#define AVG_TRACE(category, severity, sMsg) { \
+if (Logger::get()->shouldLog(category, severity)) { \
+ std::stringstream tmp(std::stringstream::in | std::stringstream::out); \
+ tmp << sMsg; \
+ Logger::get()->trace(tmp.str(), category, severity); \
}\
-}
+}\
+
+#define AVG_LOG_ERROR(sMsg){ \
+ AVG_TRACE(Logger::category::NONE, Logger::severity::ERROR, sMsg); \
+}\
+
+#define AVG_LOG_WARNING(sMsg){ \
+ AVG_TRACE(Logger::category::NONE, Logger::severity::WARNING, sMsg); \
+}\
+
+#define AVG_LOG_INFO(sMsg){ \
+ AVG_TRACE(Logger::category::NONE, Logger::severity::INFO, sMsg); \
+}\
+
+#define AVG_LOG_DEBUG(sMsg){ \
+ AVG_TRACE(Logger::category::NONE, Logger::severity::DEBUG, sMsg); \
+}\
}
#endif
diff --git a/src/base/Makefile.am b/src/base/Makefile.am
index 5fe4c94..ce995f2 100644
--- a/src/base/Makefile.am
+++ b/src/base/Makefile.am
@@ -1,31 +1,35 @@
+SUBDIRS = triangulate
-INCLUDES = -I.. @XML2_CFLAGS@ @PTHREAD_CFLAGS@
-ALL_H = FileHelper.h CmdLine.h Exception.h Logger.h ConfigMgr.h ObjectCounter.h \
+AM_CPPFLAGS = -I.. @XML2_CFLAGS@ @PTHREAD_CFLAGS@
+ALL_H = FileHelper.h Exception.h Logger.h ConfigMgr.h ObjectCounter.h \
XMLHelper.h TimeSource.h ProfilingZone.h ThreadProfiler.h \
ScopeTimer.h IFrameEndListener.h IPreRenderListener.h IPlaybackEndListener.h \
Test.h TestSuite.h OSHelper.h Queue.h WorkerThread.h Command.h ObjectCounter.h \
- Point.h Rect.h Directory.h DirEntry.h StringHelper.h MathHelper.h GeomHelper.h \
- CubicSpline.h BezierCurve.h UTF8String.h Triangle.h \
- Triangulate.h WideLine.h Triple.h DlfcnWrapper.h Signal.h Backtrace.h \
- CmdQueue.h Matrix3x4.h ProfilingZoneID.h
+ Rect.h Directory.h DirEntry.h StringHelper.h MathHelper.h GeomHelper.h \
+ CubicSpline.h BezierCurve.h UTF8String.h Triangle.h DAG.h \
+ WideLine.h DlfcnWrapper.h Signal.h Backtrace.h \
+ CmdQueue.h ProfilingZoneID.h GLMHelper.h StandardLogSink.h ILogSink.h \
+ ThreadHelper.h
-TESTS=testbase
+TESTS = testbase
EXTRA_DIST = DlfcnWrapper.cpp
noinst_LTLIBRARIES = libbase.la
-libbase_la_SOURCES = FileHelper.cpp CmdLine.cpp Exception.cpp Logger.cpp \
+libbase_la_SOURCES = FileHelper.cpp Exception.cpp Logger.cpp \
ConfigMgr.cpp XMLHelper.cpp TimeSource.cpp OSHelper.cpp \
ProfilingZone.cpp ThreadProfiler.cpp ScopeTimer.cpp Test.cpp \
- TestSuite.cpp ObjectCounter.cpp Point.cpp Directory.cpp DirEntry.cpp \
+ TestSuite.cpp ObjectCounter.cpp Directory.cpp DirEntry.cpp \
StringHelper.cpp MathHelper.cpp GeomHelper.cpp CubicSpline.cpp \
- BezierCurve.cpp UTF8String.cpp Triangle.cpp Triangulate.cpp WideLine.cpp \
- Triple.cpp Backtrace.cpp Matrix3x4.cpp ProfilingZoneID.cpp \
+ BezierCurve.cpp UTF8String.cpp Triangle.cpp DAG.cpp WideLine.cpp \
+ Backtrace.cpp ProfilingZoneID.cpp GLMHelper.cpp \
+ WorkerThread.cpp StandardLogSink.cpp ThreadHelper.cpp \
$(ALL_H)
libbase_a_CXXFLAGS = -Wno-format-y2k
-noinst_PROGRAMS=testbase
-testbase_SOURCES=testbase.cpp $(ALL_H)
-testbase_LDADD = ./libbase.la -l@BOOST_THREAD_LIB@ -lboost_system @PTHREAD_LIBS@
+noinst_PROGRAMS = testbase
+testbase_SOURCES = testbase.cpp $(ALL_H)
+testbase_LDADD = ./libbase.la ./triangulate/libtriangulate.la \
+ @BOOST_THREAD_LIBS@ @XML2_LIBS@ @PTHREAD_LIBS@
# -rdynamic needed only for testBacktrace to work under linux.
testbase_LDFLAGS = -rdynamic
diff --git a/src/base/Makefile.in b/src/base/Makefile.in
index cc935b7..2383ebb 100644
--- a/src/base/Makefile.in
+++ b/src/base/Makefile.in
@@ -1,9 +1,9 @@
-# Makefile.in generated by automake 1.11.1 from Makefile.am.
+# Makefile.in generated by automake 1.11.3 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation,
-# Inc.
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software
+# Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
@@ -44,11 +44,12 @@ ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/ac_cxx_namespaces.m4 \
$(top_srcdir)/m4/ac_path_generic.m4 \
$(top_srcdir)/m4/ax_boost_thread.m4 \
- $(top_srcdir)/m4/ax_check_gl.m4 $(top_srcdir)/m4/libtool.m4 \
- $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
- $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
- $(top_srcdir)/m4/pkg.m4 $(top_srcdir)/m4/python_dev.m4 \
- $(top_srcdir)/configure.in
+ $(top_srcdir)/m4/ax_check_gl.m4 \
+ $(top_srcdir)/m4/ax_python_devel.m4 \
+ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
+ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
+ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/pkg.m4 \
+ $(top_srcdir)/m4/avg_version.m4 $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
@@ -58,22 +59,22 @@ CONFIG_CLEAN_VPATH_FILES =
LTLIBRARIES = $(noinst_LTLIBRARIES)
libbase_la_LIBADD =
am__objects_1 =
-am_libbase_la_OBJECTS = FileHelper.lo CmdLine.lo Exception.lo \
- Logger.lo ConfigMgr.lo XMLHelper.lo TimeSource.lo OSHelper.lo \
+am_libbase_la_OBJECTS = FileHelper.lo Exception.lo Logger.lo \
+ ConfigMgr.lo XMLHelper.lo TimeSource.lo OSHelper.lo \
ProfilingZone.lo ThreadProfiler.lo ScopeTimer.lo Test.lo \
- TestSuite.lo ObjectCounter.lo Point.lo Directory.lo \
- DirEntry.lo StringHelper.lo MathHelper.lo GeomHelper.lo \
- CubicSpline.lo BezierCurve.lo UTF8String.lo Triangle.lo \
- Triangulate.lo WideLine.lo Triple.lo Backtrace.lo Matrix3x4.lo \
- ProfilingZoneID.lo $(am__objects_1)
+ TestSuite.lo ObjectCounter.lo Directory.lo DirEntry.lo \
+ StringHelper.lo MathHelper.lo GeomHelper.lo CubicSpline.lo \
+ BezierCurve.lo UTF8String.lo Triangle.lo DAG.lo WideLine.lo \
+ Backtrace.lo ProfilingZoneID.lo GLMHelper.lo WorkerThread.lo \
+ StandardLogSink.lo ThreadHelper.lo $(am__objects_1)
libbase_la_OBJECTS = $(am_libbase_la_OBJECTS)
-AM_V_lt = $(am__v_lt_$(V))
-am__v_lt_ = $(am__v_lt_$(AM_DEFAULT_VERBOSITY))
+AM_V_lt = $(am__v_lt_@AM_V@)
+am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
am__v_lt_0 = --silent
PROGRAMS = $(noinst_PROGRAMS)
am_testbase_OBJECTS = testbase.$(OBJEXT) $(am__objects_1)
testbase_OBJECTS = $(am_testbase_OBJECTS)
-testbase_DEPENDENCIES = ./libbase.la
+testbase_DEPENDENCIES = ./libbase.la ./triangulate/libtriangulate.la
testbase_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \
$(CXXFLAGS) $(testbase_LDFLAGS) $(LDFLAGS) -o $@
@@ -87,18 +88,18 @@ LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \
$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
$(AM_CXXFLAGS) $(CXXFLAGS)
-AM_V_CXX = $(am__v_CXX_$(V))
-am__v_CXX_ = $(am__v_CXX_$(AM_DEFAULT_VERBOSITY))
+AM_V_CXX = $(am__v_CXX_@AM_V@)
+am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@)
am__v_CXX_0 = @echo " CXX " $@;
-AM_V_at = $(am__v_at_$(V))
-am__v_at_ = $(am__v_at_$(AM_DEFAULT_VERBOSITY))
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
am__v_at_0 = @
CXXLD = $(CXX)
CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \
$(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
-AM_V_CXXLD = $(am__v_CXXLD_$(V))
-am__v_CXXLD_ = $(am__v_CXXLD_$(AM_DEFAULT_VERBOSITY))
+AM_V_CXXLD = $(am__v_CXXLD_@AM_V@)
+am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@)
am__v_CXXLD_0 = @echo " CXXLD " $@;
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
@@ -106,26 +107,64 @@ LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
$(AM_CFLAGS) $(CFLAGS)
-AM_V_CC = $(am__v_CC_$(V))
-am__v_CC_ = $(am__v_CC_$(AM_DEFAULT_VERBOSITY))
+AM_V_CC = $(am__v_CC_@AM_V@)
+am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
am__v_CC_0 = @echo " CC " $@;
CCLD = $(CC)
LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
$(AM_LDFLAGS) $(LDFLAGS) -o $@
-AM_V_CCLD = $(am__v_CCLD_$(V))
-am__v_CCLD_ = $(am__v_CCLD_$(AM_DEFAULT_VERBOSITY))
+AM_V_CCLD = $(am__v_CCLD_@AM_V@)
+am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
am__v_CCLD_0 = @echo " CCLD " $@;
-AM_V_GEN = $(am__v_GEN_$(V))
-am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY))
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
am__v_GEN_0 = @echo " GEN " $@;
SOURCES = $(libbase_la_SOURCES) $(testbase_SOURCES)
DIST_SOURCES = $(libbase_la_SOURCES) $(testbase_SOURCES)
+RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \
+ html-recursive info-recursive install-data-recursive \
+ install-dvi-recursive install-exec-recursive \
+ install-html-recursive install-info-recursive \
+ install-pdf-recursive install-ps-recursive install-recursive \
+ installcheck-recursive installdirs-recursive pdf-recursive \
+ ps-recursive uninstall-recursive
+RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \
+ distclean-recursive maintainer-clean-recursive
+AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \
+ $(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS \
+ distdir
ETAGS = etags
CTAGS = ctags
am__tty_colors = \
red=; grn=; lgn=; blu=; std=
+DIST_SUBDIRS = $(SUBDIRS)
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+am__relativize = \
+ dir0=`pwd`; \
+ sed_first='s,^\([^/]*\)/.*$$,\1,'; \
+ sed_rest='s,^[^/]*/*,,'; \
+ sed_last='s,^.*/\([^/]*\)$$,\1,'; \
+ sed_butlast='s,/*[^/]*$$,,'; \
+ while test -n "$$dir1"; do \
+ first=`echo "$$dir1" | sed -e "$$sed_first"`; \
+ if test "$$first" != "."; then \
+ if test "$$first" = ".."; then \
+ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \
+ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \
+ else \
+ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \
+ if test "$$first2" = "$$first"; then \
+ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \
+ else \
+ dir2="../$$dir2"; \
+ fi; \
+ dir0="$$dir0"/"$$first"; \
+ fi; \
+ fi; \
+ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \
+ done; \
+ reldir="$$dir2"
ACLOCAL = @ACLOCAL@
AMTAR = @AMTAR@
AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
@@ -135,7 +174,7 @@ AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
BOOST_PYTHON_LIBS = @BOOST_PYTHON_LIBS@
-BOOST_THREAD_LIB = @BOOST_THREAD_LIB@
+BOOST_THREAD_LIBS = @BOOST_THREAD_LIBS@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
@@ -150,6 +189,7 @@ DC1394_2_CFLAGS = @DC1394_2_CFLAGS@
DC1394_2_LIBS = @DC1394_2_LIBS@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO_C = @ECHO_C@
@@ -190,6 +230,7 @@ LIPO = @LIPO@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
MKDIR_P = @MKDIR_P@
MTDEV_CFLAGS = @MTDEV_CFLAGS@
MTDEV_LIBS = @MTDEV_LIBS@
@@ -219,11 +260,13 @@ PTHREAD_CC = @PTHREAD_CC@
PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
PTHREAD_LIBS = @PTHREAD_LIBS@
PYTHON = @PYTHON@
+PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@
PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
-PYTHON_INCLUDES = @PYTHON_INCLUDES@
-PYTHON_LIBS = @PYTHON_LIBS@
+PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@
+PYTHON_LDFLAGS = @PYTHON_LDFLAGS@
PYTHON_PLATFORM = @PYTHON_PLATFORM@
PYTHON_PREFIX = @PYTHON_PREFIX@
+PYTHON_SITE_PKG = @PYTHON_SITE_PKG@
PYTHON_VERSION = @PYTHON_VERSION@
RANLIB = @RANLIB@
SDL_CFLAGS = @SDL_CFLAGS@
@@ -246,6 +289,7 @@ abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
ac_ct_CC = @ac_ct_CC@
ac_ct_CXX = @ac_ct_CXX@
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
@@ -280,7 +324,6 @@ libdir = @libdir@
libexecdir = @libexecdir@
localedir = @localedir@
localstatedir = @localstatedir@
-lt_ECHO = @lt_ECHO@
mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
@@ -304,33 +347,38 @@ target_vendor = @target_vendor@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
-INCLUDES = -I.. @XML2_CFLAGS@ @PTHREAD_CFLAGS@
-ALL_H = FileHelper.h CmdLine.h Exception.h Logger.h ConfigMgr.h ObjectCounter.h \
+SUBDIRS = triangulate
+AM_CPPFLAGS = -I.. @XML2_CFLAGS@ @PTHREAD_CFLAGS@
+ALL_H = FileHelper.h Exception.h Logger.h ConfigMgr.h ObjectCounter.h \
XMLHelper.h TimeSource.h ProfilingZone.h ThreadProfiler.h \
ScopeTimer.h IFrameEndListener.h IPreRenderListener.h IPlaybackEndListener.h \
Test.h TestSuite.h OSHelper.h Queue.h WorkerThread.h Command.h ObjectCounter.h \
- Point.h Rect.h Directory.h DirEntry.h StringHelper.h MathHelper.h GeomHelper.h \
- CubicSpline.h BezierCurve.h UTF8String.h Triangle.h \
- Triangulate.h WideLine.h Triple.h DlfcnWrapper.h Signal.h Backtrace.h \
- CmdQueue.h Matrix3x4.h ProfilingZoneID.h
+ Rect.h Directory.h DirEntry.h StringHelper.h MathHelper.h GeomHelper.h \
+ CubicSpline.h BezierCurve.h UTF8String.h Triangle.h DAG.h \
+ WideLine.h DlfcnWrapper.h Signal.h Backtrace.h \
+ CmdQueue.h ProfilingZoneID.h GLMHelper.h StandardLogSink.h ILogSink.h \
+ ThreadHelper.h
EXTRA_DIST = DlfcnWrapper.cpp
noinst_LTLIBRARIES = libbase.la
-libbase_la_SOURCES = FileHelper.cpp CmdLine.cpp Exception.cpp Logger.cpp \
+libbase_la_SOURCES = FileHelper.cpp Exception.cpp Logger.cpp \
ConfigMgr.cpp XMLHelper.cpp TimeSource.cpp OSHelper.cpp \
ProfilingZone.cpp ThreadProfiler.cpp ScopeTimer.cpp Test.cpp \
- TestSuite.cpp ObjectCounter.cpp Point.cpp Directory.cpp DirEntry.cpp \
+ TestSuite.cpp ObjectCounter.cpp Directory.cpp DirEntry.cpp \
StringHelper.cpp MathHelper.cpp GeomHelper.cpp CubicSpline.cpp \
- BezierCurve.cpp UTF8String.cpp Triangle.cpp Triangulate.cpp WideLine.cpp \
- Triple.cpp Backtrace.cpp Matrix3x4.cpp ProfilingZoneID.cpp \
+ BezierCurve.cpp UTF8String.cpp Triangle.cpp DAG.cpp WideLine.cpp \
+ Backtrace.cpp ProfilingZoneID.cpp GLMHelper.cpp \
+ WorkerThread.cpp StandardLogSink.cpp ThreadHelper.cpp \
$(ALL_H)
libbase_a_CXXFLAGS = -Wno-format-y2k
testbase_SOURCES = testbase.cpp $(ALL_H)
-testbase_LDADD = ./libbase.la -l@BOOST_THREAD_LIB@ @PTHREAD_LIBS@
+testbase_LDADD = ./libbase.la ./triangulate/libtriangulate.la \
+ @BOOST_THREAD_LIBS@ @XML2_LIBS@ @PTHREAD_LIBS@
+
# -rdynamic needed only for testBacktrace to work under linux.
testbase_LDFLAGS = -rdynamic
-all: all-am
+all: all-recursive
.SUFFIXES:
.SUFFIXES: .cpp .lo .o .obj
@@ -373,7 +421,7 @@ clean-noinstLTLIBRARIES:
echo "rm -f \"$${dir}/so_locations\""; \
rm -f "$${dir}/so_locations"; \
done
-libbase.la: $(libbase_la_OBJECTS) $(libbase_la_DEPENDENCIES)
+libbase.la: $(libbase_la_OBJECTS) $(libbase_la_DEPENDENCIES) $(EXTRA_libbase_la_DEPENDENCIES)
$(AM_V_CXXLD)$(CXXLINK) $(libbase_la_OBJECTS) $(libbase_la_LIBADD) $(LIBS)
clean-noinstPROGRAMS:
@@ -384,7 +432,7 @@ clean-noinstPROGRAMS:
list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
echo " rm -f" $$list; \
rm -f $$list
-testbase$(EXEEXT): $(testbase_OBJECTS) $(testbase_DEPENDENCIES)
+testbase$(EXEEXT): $(testbase_OBJECTS) $(testbase_DEPENDENCIES) $(EXTRA_testbase_DEPENDENCIES)
@rm -f testbase$(EXEEXT)
$(AM_V_CXXLD)$(testbase_LINK) $(testbase_OBJECTS) $(testbase_LDADD) $(LIBS)
@@ -396,59 +444,56 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Backtrace.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/BezierCurve.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CmdLine.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ConfigMgr.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CubicSpline.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DAG.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DirEntry.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Directory.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Exception.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/FileHelper.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/GLMHelper.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/GeomHelper.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Logger.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/MathHelper.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Matrix3x4.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/OSHelper.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ObjectCounter.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Point.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ProfilingZone.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ProfilingZoneID.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ScopeTimer.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/StandardLogSink.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/StringHelper.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Test.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TestSuite.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ThreadHelper.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ThreadProfiler.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TimeSource.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Triangle.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Triangulate.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Triple.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/UTF8String.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/WideLine.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/WorkerThread.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/XMLHelper.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/testbase.Po@am__quote@
.cpp.o:
@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
-@am__fastdepCXX_FALSE@ $(AM_V_CXX) @AM_BACKSLASH@
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $<
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $<
.cpp.obj:
@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
-@am__fastdepCXX_FALSE@ $(AM_V_CXX) @AM_BACKSLASH@
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
.cpp.lo:
@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
-@am__fastdepCXX_FALSE@ $(AM_V_CXX) @AM_BACKSLASH@
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(LTCXXCOMPILE) -c -o $@ $<
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LTCXXCOMPILE) -c -o $@ $<
mostlyclean-libtool:
-rm -f *.lo
@@ -456,6 +501,76 @@ mostlyclean-libtool:
clean-libtool:
-rm -rf .libs _libs
+# This directory's subdirectories are mostly independent; you can cd
+# into them and run `make' without going through this Makefile.
+# To change the values of `make' variables: instead of editing Makefiles,
+# (1) if the variable is set in `config.status', edit `config.status'
+# (which will cause the Makefiles to be regenerated when you run `make');
+# (2) otherwise, pass the desired values on the `make' command line.
+$(RECURSIVE_TARGETS):
+ @fail= failcom='exit 1'; \
+ for f in x $$MAKEFLAGS; do \
+ case $$f in \
+ *=* | --[!k]*);; \
+ *k*) failcom='fail=yes';; \
+ esac; \
+ done; \
+ dot_seen=no; \
+ target=`echo $@ | sed s/-recursive//`; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ echo "Making $$target in $$subdir"; \
+ if test "$$subdir" = "."; then \
+ dot_seen=yes; \
+ local_target="$$target-am"; \
+ else \
+ local_target="$$target"; \
+ fi; \
+ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+ || eval $$failcom; \
+ done; \
+ if test "$$dot_seen" = "no"; then \
+ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
+ fi; test -z "$$fail"
+
+$(RECURSIVE_CLEAN_TARGETS):
+ @fail= failcom='exit 1'; \
+ for f in x $$MAKEFLAGS; do \
+ case $$f in \
+ *=* | --[!k]*);; \
+ *k*) failcom='fail=yes';; \
+ esac; \
+ done; \
+ dot_seen=no; \
+ case "$@" in \
+ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
+ *) list='$(SUBDIRS)' ;; \
+ esac; \
+ rev=''; for subdir in $$list; do \
+ if test "$$subdir" = "."; then :; else \
+ rev="$$subdir $$rev"; \
+ fi; \
+ done; \
+ rev="$$rev ."; \
+ target=`echo $@ | sed s/-recursive//`; \
+ for subdir in $$rev; do \
+ echo "Making $$target in $$subdir"; \
+ if test "$$subdir" = "."; then \
+ local_target="$$target-am"; \
+ else \
+ local_target="$$target"; \
+ fi; \
+ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+ || eval $$failcom; \
+ done && test -z "$$fail"
+tags-recursive:
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
+ done
+ctags-recursive:
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \
+ done
+
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
@@ -466,10 +581,23 @@ ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
mkid -fID $$unique
tags: TAGS
-TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
set x; \
here=`pwd`; \
+ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
+ include_option=--etags-include; \
+ empty_fix=.; \
+ else \
+ include_option=--include; \
+ empty_fix=; \
+ fi; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ test ! -f $$subdir/TAGS || \
+ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \
+ fi; \
+ done; \
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
@@ -488,7 +616,7 @@ TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
fi; \
fi
ctags: CTAGS
-CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
@@ -589,14 +717,15 @@ check-TESTS: $(TESTS)
fi; \
dashes=`echo "$$dashes" | sed s/./=/g`; \
if test "$$failed" -eq 0; then \
- echo "$$grn$$dashes"; \
+ col="$$grn"; \
else \
- echo "$$red$$dashes"; \
+ col="$$red"; \
fi; \
- echo "$$banner"; \
- test -z "$$skipped" || echo "$$skipped"; \
- test -z "$$report" || echo "$$report"; \
- echo "$$dashes$$std"; \
+ echo "$${col}$$dashes$${std}"; \
+ echo "$${col}$$banner$${std}"; \
+ test -z "$$skipped" || echo "$${col}$$skipped$${std}"; \
+ test -z "$$report" || echo "$${col}$$report$${std}"; \
+ echo "$${col}$$dashes$${std}"; \
test "$$failed" -eq 0; \
else :; fi
@@ -630,25 +759,59 @@ distdir: $(DISTFILES)
|| exit 1; \
fi; \
done
+ @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ test -d "$(distdir)/$$subdir" \
+ || $(MKDIR_P) "$(distdir)/$$subdir" \
+ || exit 1; \
+ fi; \
+ done
+ @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \
+ $(am__relativize); \
+ new_distdir=$$reldir; \
+ dir1=$$subdir; dir2="$(top_distdir)"; \
+ $(am__relativize); \
+ new_top_distdir=$$reldir; \
+ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \
+ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \
+ ($(am__cd) $$subdir && \
+ $(MAKE) $(AM_MAKEFLAGS) \
+ top_distdir="$$new_top_distdir" \
+ distdir="$$new_distdir" \
+ am__remove_distdir=: \
+ am__skip_length_check=: \
+ am__skip_mode_fix=: \
+ distdir) \
+ || exit 1; \
+ fi; \
+ done
check-am: all-am
$(MAKE) $(AM_MAKEFLAGS) check-TESTS
-check: check-am
+check: check-recursive
all-am: Makefile $(LTLIBRARIES) $(PROGRAMS)
-installdirs:
-install: install-am
-install-exec: install-exec-am
-install-data: install-data-am
-uninstall: uninstall-am
+installdirs: installdirs-recursive
+installdirs-am:
+install: install-recursive
+install-exec: install-exec-recursive
+install-data: install-data-recursive
+uninstall: uninstall-recursive
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
-installcheck: installcheck-am
+installcheck: installcheck-recursive
install-strip:
- $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
- install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
- `test -z '$(STRIP)' || \
- echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
mostlyclean-generic:
clean-generic:
@@ -660,92 +823,94 @@ distclean-generic:
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
-clean: clean-am
+clean: clean-recursive
clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \
clean-noinstPROGRAMS mostlyclean-am
-distclean: distclean-am
+distclean: distclean-recursive
-rm -rf ./$(DEPDIR)
-rm -f Makefile
distclean-am: clean-am distclean-compile distclean-generic \
distclean-tags
-dvi: dvi-am
+dvi: dvi-recursive
dvi-am:
-html: html-am
+html: html-recursive
html-am:
-info: info-am
+info: info-recursive
info-am:
install-data-am:
-install-dvi: install-dvi-am
+install-dvi: install-dvi-recursive
install-dvi-am:
install-exec-am:
-install-html: install-html-am
+install-html: install-html-recursive
install-html-am:
-install-info: install-info-am
+install-info: install-info-recursive
install-info-am:
install-man:
-install-pdf: install-pdf-am
+install-pdf: install-pdf-recursive
install-pdf-am:
-install-ps: install-ps-am
+install-ps: install-ps-recursive
install-ps-am:
installcheck-am:
-maintainer-clean: maintainer-clean-am
+maintainer-clean: maintainer-clean-recursive
-rm -rf ./$(DEPDIR)
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
-mostlyclean: mostlyclean-am
+mostlyclean: mostlyclean-recursive
mostlyclean-am: mostlyclean-compile mostlyclean-generic \
mostlyclean-libtool
-pdf: pdf-am
+pdf: pdf-recursive
pdf-am:
-ps: ps-am
+ps: ps-recursive
ps-am:
uninstall-am:
-.MAKE: check-am install-am install-strip
+.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) check-am \
+ ctags-recursive install-am install-strip tags-recursive
-.PHONY: CTAGS GTAGS all all-am check check-TESTS check-am clean \
- clean-generic clean-libtool clean-noinstLTLIBRARIES \
- clean-noinstPROGRAMS ctags distclean distclean-compile \
+.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \
+ all all-am check check-TESTS check-am clean clean-generic \
+ clean-libtool clean-noinstLTLIBRARIES clean-noinstPROGRAMS \
+ ctags ctags-recursive distclean distclean-compile \
distclean-generic distclean-libtool distclean-tags distdir dvi \
dvi-am html html-am info info-am install install-am \
install-data install-data-am install-dvi install-dvi-am \
install-exec install-exec-am install-html install-html-am \
install-info install-info-am install-man install-pdf \
install-pdf-am install-ps install-ps-am install-strip \
- installcheck installcheck-am installdirs maintainer-clean \
- maintainer-clean-generic mostlyclean mostlyclean-compile \
- mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
- tags uninstall uninstall-am
+ installcheck installcheck-am installdirs installdirs-am \
+ maintainer-clean maintainer-clean-generic mostlyclean \
+ mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
+ pdf pdf-am ps ps-am tags tags-recursive uninstall uninstall-am
# Tell versions [3.59,3.63) of GNU make to not export all variables.
diff --git a/src/base/MathHelper.cpp b/src/base/MathHelper.cpp
index ea7093e..388859d 100644
--- a/src/base/MathHelper.cpp
+++ b/src/base/MathHelper.cpp
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -35,27 +35,17 @@ bool ispow2(int n)
int nextpow2(int n)
{
- int ret=1;
- while (ret < n) {
- ret *= 2;
- }
- return ret;
-/* TODO: Fix this fast version :-).
- int RetVal = 1;
- __asm__ __volatile__(
- "xorl %%ecx, %%ecx\n\t"
- "bsrl %1, %%ecx\n\t"
- "incl %%ecx\n\t"
- "shlb %%cl, %0\n\t"
- : "=m" (RetVal)
- : "m" (n)
- : "cc", "ecx"
- );
- return RetVal;
-*/
+ n--;
+ n |= n >> 1; // handle 2 bit numbers
+ n |= n >> 2; // handle 4 bit numbers
+ n |= n >> 4; // handle 8 bit numbers
+ n |= n >> 8; // handle 16 bit numbers
+ n |= n >> 16; // handle 32 bit numbers
+ n++;
+ return n;
}
-int safeCeil(double d)
+int safeCeil(float d)
{
if (fabs(d-int(d)) < EPSILON) {
return int(d);
@@ -80,7 +70,7 @@ float invSqrt(float x)
return 1/sqrt(x);
}
-bool almostEqual(double d1, double d2, double epsilon)
+bool almostEqual(float d1, float d2, float epsilon)
{
return (fabs(d1-d2)<epsilon);
}
diff --git a/src/base/MathHelper.h b/src/base/MathHelper.h
index 16132c4..587ff2c 100644
--- a/src/base/MathHelper.h
+++ b/src/base/MathHelper.h
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -24,6 +24,7 @@
#include "../api.h"
#include <vector>
+#include <set>
#include <math.h>
#ifndef M_PI
@@ -32,15 +33,16 @@
namespace avg {
-static const double EPSILON = 0.00001;
+static const float PI = 3.14159265358979323846f;
+static const float EPSILON = 0.00001f;
bool ispow2(int n);
int nextpow2(int n);
-int safeCeil(double d);
+int safeCeil(float d);
-bool almostEqual(double d1, double d2, double epsilon=EPSILON);
+bool almostEqual(float d1, float d2, float epsilon=EPSILON);
float invSqrt(float x);
@@ -82,7 +84,7 @@ std::vector<std::vector<T> > vector2DFromCArray(int n, int m, T* pData)
template<class T>
T round(T d)
{
- return floor( d + 0.5 );
+ return floor(d + 0.5f);
}
#endif
diff --git a/src/base/Matrix3x4.cpp b/src/base/Matrix3x4.cpp
deleted file mode 100644
index e065d2b..0000000
--- a/src/base/Matrix3x4.cpp
+++ /dev/null
@@ -1,128 +0,0 @@
-//
-// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
-//
-// This library is free software; you can redistribute it and/or
-// modify it under the terms of the GNU Lesser General Public
-// License as published by the Free Software Foundation; either
-// version 2 of the License, or (at your option) any later version.
-//
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public
-// License along with this library; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-//
-// Current versions can be found at www.libavg.de
-//
-
-#include "Matrix3x4.h"
-#include "MathHelper.h"
-
-#include <math.h>
-
-using namespace std;
-
-namespace avg {
-
-Matrix3x4::Matrix3x4()
-{
- setIdent();
-}
-
-Matrix3x4::Matrix3x4(const float *v)
-{
- for (int x=0; x<3; ++x) {
- for (int y=0; y<4; ++y) {
- val[x][y] = v[x*4+y];
- }
- }
-}
-
-Matrix3x4 Matrix3x4::createTranslate(float x, float y, float z)
-{
- Matrix3x4 mat;
- mat.val[0][3] = x;
- mat.val[1][3] = y;
- mat.val[2][3] = z;
- return mat;
-}
-
-Matrix3x4 Matrix3x4::createTranslate(const DTriple& tr)
-{
- return createTranslate(float(tr.x), float(tr.y), float(tr.z));
-}
-
-Matrix3x4 Matrix3x4::createScale(float x, float y, float z)
-{
- Matrix3x4 mat;
- mat.val[0][0] = x;
- mat.val[1][1] = y;
- mat.val[2][2] = z;
- return mat;
-}
-
-Matrix3x4 Matrix3x4::createScale(const DTriple& tr)
-{
- return createScale(float(tr.x), float(tr.y), float(tr.z));
-}
-
-const Matrix3x4& Matrix3x4::operator *=(const Matrix3x4& mat)
-{
- for (int x=0; x<3; ++x) {
- float t0 = val[x][0] * mat.val[0][0] + val[x][1] * mat.val[1][0]
- + val[x][2] * mat.val[2][0];
- float t1 = val[x][0] * mat.val[0][1] + val[x][1] * mat.val[1][1]
- + val[x][2] * mat.val[2][1];
- float t2 = val[x][0] * mat.val[0][2] + val[x][1] * mat.val[1][2]
- + val[x][2] * mat.val[2][2];
- val[x][3] = val[x][0] * mat.val[0][3] + val[x][1] * mat.val[1][3]
- + val[x][2] * mat.val[2][3] + val[x][3];
- val[x][0] = t0;
- val[x][1] = t1;
- val[x][2] = t2;
- }
- return *this;
-}
-
-void Matrix3x4::setIdent()
-{
- for (int x=0; x<3; ++x) {
- for (int y=0; y<4; ++y) {
- val[x][y] = 0.0;
- }
- }
- val[0][0] = 1.0;
- val[1][1] = 1.0;
- val[2][2] = 1.0;
-}
-
-bool almostEqual(const Matrix3x4& mat1, const Matrix3x4& mat2)
-{
- for (int x=0; x<3; ++x) {
- for (int y=0; y<4; ++y) {
- if (!almostEqual(mat1.val[x][y], mat2.val[x][y])) {
- return false;
- }
- }
- }
- return true;
-}
-
-std::ostream& operator<<(ostream& os, const Matrix3x4& mat)
-{
- os << "{" << endl;
- for (int y=0; y<4; ++y) {
- os << " {" << mat.val[0][y] << "," << mat.val[1][y] << "," << mat.val[2][y]
- << "}" << endl;
- }
- os << "}" << endl;
- return os;
-}
-
-
-}
-
diff --git a/src/base/OSHelper.cpp b/src/base/OSHelper.cpp
index 852a7f0..377e725 100644
--- a/src/base/OSHelper.cpp
+++ b/src/base/OSHelper.cpp
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -33,12 +33,15 @@
#elif defined(__APPLE__)
#include <mach-o/dyld.h>
#include <mach/mach.h>
+#include <sys/utsname.h>
#elif defined(__linux)
#include <fstream>
#include <unistd.h>
+#include <string.h>
#endif
#include <stdlib.h>
+#include <iostream>
#include <cstdlib>
using namespace std;
@@ -59,6 +62,107 @@ string getWinErrMsg(unsigned err)
}
#endif
+#if defined(__linux)
+// Adapted from binreloc
+static char *
+_br_find_exe_for_symbol (const void *symbol)
+{
+ #define SIZE 1024
+ FILE *f;
+ size_t address_string_len;
+ char *address_string, line[SIZE], *found;
+
+ if (symbol == NULL)
+ return (char *) NULL;
+
+ f = fopen ("/proc/self/maps", "r");
+ if (f == NULL)
+ return (char *) NULL;
+
+ address_string_len = 4;
+ address_string = (char *) malloc(address_string_len);
+ found = (char *) NULL;
+
+
+ while (!feof (f)) {
+ char *start_addr, *end_addr, *end_addr_end, *file;
+ void *start_addr_p, *end_addr_p;
+ size_t len;
+
+ if (fgets (line, SIZE, f) == NULL)
+ break;
+
+ /* Sanity check. */
+ if (strstr (line, " r-xp ") == NULL || strchr (line, '/') == NULL)
+ continue;
+
+ /* Parse line. */
+ start_addr = line;
+ end_addr = strchr (line, '-');
+ file = strchr (line, '/');
+
+ /* More sanity check. */
+ if (!(file > end_addr && end_addr != NULL && end_addr[0] == '-'))
+ continue;
+
+ end_addr[0] = '\0';
+ end_addr++;
+ end_addr_end = strchr (end_addr, ' ');
+ if (end_addr_end == NULL)
+ continue;
+
+ end_addr_end[0] = '\0';
+ len = strlen (file);
+ if (len == 0)
+ continue;
+ if (file[len - 1] == '\n')
+ file[len - 1] = '\0';
+
+ /* Get rid of "(deleted)" from the filename. */
+ len = strlen (file);
+ if (len > 10 && strcmp (file + len - 10, " (deleted)") == 0)
+ file[len - 10] = '\0';
+
+ /* I don't know whether this can happen but better safe than sorry. */
+ len = strlen (start_addr);
+ if (len != strlen (end_addr))
+ continue;
+
+
+ /* Transform the addresses into a string in the form of 0xdeadbeef,
+ * then transform that into a pointer. */
+ if (address_string_len < len + 3) {
+ address_string_len = len + 3;
+ address_string = (char *) realloc (address_string, address_string_len);
+ }
+
+ memcpy (address_string, "0x", 2);
+ memcpy (address_string + 2, start_addr, len);
+ address_string[2 + len] = '\0';
+ sscanf (address_string, "%p", &start_addr_p);
+
+ memcpy (address_string, "0x", 2);
+ memcpy (address_string + 2, end_addr, len);
+ address_string[2 + len] = '\0';
+ sscanf (address_string, "%p", &end_addr_p);
+
+
+ if (symbol >= start_addr_p && symbol < end_addr_p) {
+ found = file;
+ break;
+ }
+ }
+
+ free (address_string);
+ fclose (f);
+
+ if (found == NULL)
+ return (char *) NULL;
+ else
+ return strdup (found);
+}
+#endif
+
string getAvgLibPath()
{
#if defined(_WIN32)
@@ -66,7 +170,7 @@ string getAvgLibPath()
char szFilename[1024];
DWORD ok = GetModuleFileName(hModule, szFilename, sizeof(szFilename));
if (ok == 0) {
- AVG_TRACE(Logger::ERROR, "getAvgLibPath(): " << getWinErrMsg(GetLastError()));
+ AVG_LOG_ERROR("getAvgLibPath(): " << getWinErrMsg(GetLastError()));
exit(5);
}
string sPath=getPath(szFilename);
@@ -89,8 +193,9 @@ string getAvgLibPath()
_NSGetExecutablePath(path, &pathLen);
return getPath(path);
#else
- // For a linux solution, see http://www.autopackage.org/docs/binreloc/
- return "";
+ char* pszFilename;
+ pszFilename = _br_find_exe_for_symbol((const void *)"");
+ return pszFilename;
#endif
}
@@ -154,8 +259,7 @@ std::string convertUTF8ToFilename(const std::string & sName)
int err1 = MultiByteToWideChar(CP_UTF8, 0, sName.c_str(), sName.size()+1,
wideString, 2048);
if (err1 == 0) {
- AVG_TRACE(Logger::WARNING,
- "Error in unicode conversion (MultiByteToWideChar): " <<
+ AVG_LOG_WARNING("Error in unicode conversion (MultiByteToWideChar): " <<
getWinErrMsg(GetLastError()));
return sName;
}
@@ -166,8 +270,7 @@ std::string convertUTF8ToFilename(const std::string & sName)
err1 = WideCharToMultiByte(CP_UTF8, 0, wideShortFName, -1, pShortName,
1024, 0, 0);
if (err1 == 0) {
- AVG_TRACE(Logger::WARNING,
- "Error in unicode conversion (MultiByteToWideChar): " <<
+ AVG_LOG_WARNING("Error in unicode conversion (MultiByteToWideChar): " <<
getWinErrMsg(GetLastError()));
}
return pShortName;
@@ -179,4 +282,27 @@ std::string convertUTF8ToFilename(const std::string & sName)
#endif
}
+#ifdef __APPLE__
+int reallyGetOSXMajorVersion()
+{
+ utsname sysInfo;
+ int rc = uname(&sysInfo);
+ AVG_ASSERT(rc == 0);
+// cerr << sysInfo.sysname << ", " << sysInfo.nodename << ", " << sysInfo.release <<
+// ", " << sysInfo.version << ", " << sysInfo.machine << endl;
+ istringstream ss(sysInfo.release);
+ int major;
+ int minor;
+ int dot;
+ char c;
+ ss >> major >> c >> minor >> c >> dot;
+ return major;
+}
+
+int getOSXMajorVersion()
+{
+ static int major = reallyGetOSXMajorVersion(); // only called once for speed reasons.
+ return major;
+}
+#endif
}
diff --git a/src/base/OSHelper.h b/src/base/OSHelper.h
index de6924b..6abda5a 100644
--- a/src/base/OSHelper.h
+++ b/src/base/OSHelper.h
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -42,6 +42,10 @@ size_t getMemoryUsage();
// Under other operating systems, returns the input string.
AVG_API std::string convertUTF8ToFilename(const std::string & sName);
+#ifdef __APPLE__
+int getOSXMajorVersion();
+#endif
+
}
#endif
diff --git a/src/base/ObjectCounter.cpp b/src/base/ObjectCounter.cpp
index 00015aa..e8136b7 100644
--- a/src/base/ObjectCounter.cpp
+++ b/src/base/ObjectCounter.cpp
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -21,6 +21,7 @@
#include "ObjectCounter.h"
#include "Exception.h"
+#include "Logger.h"
#include <boost/thread/mutex.hpp>
@@ -80,7 +81,7 @@ ObjectCounter * ObjectCounter::get()
void ObjectCounter::incRef(const std::type_info* pType)
{
#ifdef DEBUG_ALLOC
- boost::mutex::scoped_lock Lock(*pCounterMutex);
+ lock_guard Lock(*pCounterMutex);
TypeMap::iterator MapEntry = m_TypeMap.find(pType);
if (MapEntry == m_TypeMap.end()) {
m_TypeMap[pType] = 1;
@@ -99,7 +100,7 @@ void ObjectCounter::decRef(const std::type_info* pType)
// s_pObjectCounter has been deleted.
return;
}
- boost::mutex::scoped_lock Lock(*pCounterMutex);
+ lock_guard Lock(*pCounterMutex);
TypeMap::iterator MapEntry = m_TypeMap.find(pType);
if (MapEntry == m_TypeMap.end()) {
cerr << "ObjectCounter for " << demangle(pType->name())
@@ -179,4 +180,8 @@ string ObjectCounter::demangle(string s)
return sResult;
}
+TypeMap ObjectCounter::getObjectCount(){
+ return m_TypeMap;
+}
+
}
diff --git a/src/base/ObjectCounter.h b/src/base/ObjectCounter.h
index 506a3c9..e370723 100644
--- a/src/base/ObjectCounter.h
+++ b/src/base/ObjectCounter.h
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -29,6 +29,8 @@
namespace avg {
+typedef std::map<const std::type_info *, int> TypeMap;
+
class AVG_API ObjectCounter {
public:
static ObjectCounter* get();
@@ -38,14 +40,15 @@ public:
void decRef(const std::type_info* pType);
int getCount(const std::type_info* pType);
+
+ std::string demangle(std::string s);
std::string dump();
+ TypeMap getObjectCount();
private:
ObjectCounter();
- std::string demangle(std::string s);
static void deleteSingleton();
- typedef std::map<const std::type_info *, int> TypeMap;
TypeMap m_TypeMap;
static ObjectCounter* s_pObjectCounter;
diff --git a/src/base/Point.cpp b/src/base/Point.cpp
deleted file mode 100644
index 24208ca..0000000
--- a/src/base/Point.cpp
+++ /dev/null
@@ -1,325 +0,0 @@
-//
-// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
-//
-// This library is free software; you can redistribute it and/or
-// modify it under the terms of the GNU Lesser General Public
-// License as published by the Free Software Foundation; either
-// version 2 of the License, or (at your option) any later version.
-//
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public
-// License along with this library; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-//
-// Current versions can be found at www.libavg.de
-//
-
-#include "Point.h"
-
-#include "MathHelper.h"
-#include "Exception.h"
-
-#if defined(__SSE__) || defined(_WIN32)
-#include <xmmintrin.h>
-#endif
-
-#include <math.h>
-#include <float.h>
-
-#include <string>
-
-namespace avg {
-
-template<class NUM>
-Point<NUM>::Point()
-{
-// ObjectCounter::get()->incRef(&typeid(*this));
-}
-
-template<class NUM>
-Point<NUM>::Point(NUM X, NUM Y)
-{
-// ObjectCounter::get()->incRef(&typeid(*this));
- x = X;
- y = Y;
-}
-
-template<class NUM>
-Point<NUM>::Point(const Point<NUM>& p)
-{
-// ObjectCounter::get()->incRef(&typeid(*this));
- x = p.x;
- y = p.y;
-}
-
-template<class NUM>
-Point<NUM>::Point(const std::vector<NUM>& v)
-{
- AVG_ASSERT_MSG(v.size() == 2,
- "Point can only be constructed from 2-component vector");
- x = v[0];
- y = v[1];
-}
-
-template<class NUM>
-Point<NUM>::~Point()
-{
-// ObjectCounter::get()->decRef(&typeid(*this));
-}
-
-template<class NUM>
-double Point<NUM>::getNorm() const
-{
- return sqrt(double(x*x+y*y));
-}
-
-template<class NUM>
-bool Point<NUM>::isNaN() const
-{
- return isnan(x) || isnan(y);
-}
-
-template<class NUM>
-bool Point<NUM>::isInf() const
-{
- return isinf(x) || isinf(y);
-}
-
-template<class NUM>
-Point<NUM> Point<NUM>::getRotated(double angle) const
-{
- double cosVal = cos(angle);
- double sinVal = sin(angle);
- return Point<NUM>(NUM(x*cosVal - y*sinVal), NUM(x*sinVal + y*cosVal));
-}
-
-template<class NUM>
-Point<NUM> Point<NUM>::getRotatedPivot(double angle, const Point<NUM>& pivot) const
-{
- // translate pivot to origin
- Point<NUM> translated = *this - pivot;
-
- // calculate rotated coordinates about the origin
- Point<NUM> rotated = translated.getRotated(angle);
-
- // re-translate pivot to original position
- rotated += pivot;
-
- return rotated;
-}
-
-template<class NUM>
-Point<NUM>& Point<NUM>::operator =(const Point<NUM>& p)
-{
- x = p.x;
- y = p.y;
- return *this;
-}
-
-template<class NUM>
-bool Point<NUM>::operator ==(const Point<NUM> & pt) const
-{
- return (x == pt.x && y == pt.y);
-}
-
-template<class NUM>
-bool Point<NUM>::operator !=(const Point<NUM> & pt) const
-{
- return (x != pt.x || y != pt.y);
-}
-
-template<class NUM>
-void Point<NUM>::operator +=(const Point<NUM>& pt)
-{
- x += pt.x;
- y += pt.y;
-}
-
-template<class NUM>
-void Point<NUM>::operator -=(const Point<NUM> & pt)
-{
- x -= pt.x;
- y -= pt.y;
-}
-
-template<class NUM>
-void Point<NUM>::operator *=(NUM f)
-{
- x *= f;
- y *= f;
-}
-
-template<class NUM>
-void Point<NUM>::operator /=(NUM f)
-{
- x /= f;
- y /= f;
-}
-
-template<class NUM>
-Point<NUM> Point<NUM>::operator -() const
-{
- return Point<NUM>(-x, -y);
-}
-
-template<class NUM>
-Point<NUM> Point<NUM>::operator +(const Point<NUM> & pt) const
-{
- return Point<NUM>(x + pt.x, y + pt.y);
-}
-
-template<class NUM>
-Point<NUM> Point<NUM>::operator -(const Point<NUM> & pt) const
-{
- return Point<NUM>(x - pt.x, y - pt.y);
-}
-
-template<class NUM>
-Point<NUM> Point<NUM>::operator /(double f) const
-{
- return Point<NUM> (NUM(x/f), NUM(y/f));
-}
-
-template<class NUM>
-Point<NUM> Point<NUM>::operator *(double f) const
-{
- return Point<NUM> (NUM(x*f), NUM(y*f));
-}
-
-template<class NUM>
-Point<NUM> Point<NUM>::operator *(const Point<NUM>& pt) const
-{
- return Point<NUM> (x*pt.x, y*pt.y);
-}
-
-template<>
-Point<int> Point<int>::fromPolar(double angle, double radius)
-{
- AVG_ASSERT_MSG(false, "fromPolar undefined for IntPoint");
- return Point<int>(0,0);
-}
-
-template<>
-Point<double> Point<double>::fromPolar(double angle, double radius)
-{
- return Point<double>(cos(angle)*radius, sin(angle)*radius);
-}
-
-template<class NUM>
-double Point<NUM>::getAngle() const
-{
- return atan2(double(y), double(x));
-}
-
-template<>
-Point<int> Point<int>::getNormalized() const
-{
- AVG_ASSERT_MSG(false, "getNormalized undefined for IntPoint");
- return Point<int>(0,0);
-}
-
-template<>
-Point<double> Point<double>::getNormalized() const
-{
- // This is imprecise but fast
-#if defined(__SSE__) || defined(_WIN32)
-#pragma pack(16)
- float result[4];
- float normSqr = float(x*x+y*y);
- __m128 src = _mm_setr_ps(float(x), float(y), 0, 0);
- __m128 normSqrVec = _mm_set_ps1(normSqr);
- __m128 invSqrt = _mm_rsqrt_ps(normSqrVec);
- __m128 resultVec = _mm_mul_ps(src, invSqrt);
- _mm_storeu_ps(result, resultVec);
- return Point<double>(result[0], result[1]);
-#pragma pack()
-#else
- double invNorm = invSqrt(float(x*x+y*y));
- if (invNorm != 0) {
- return Point<double>(x*invNorm, y*invNorm);
- } else {
- return *this;
- }
-#endif
-}
-
-template<>
-Point<double> Point<double>::safeGetNormalized() const
-{
- // This is precise but slower, and the version exported to python
- if (x==0 && y==0) {
- throw Exception(AVG_ERR_OUT_OF_RANGE, "Can't normalize (0,0).");
- } else {
- double invNorm = 1/sqrt(x*x+y*y);
- return Point<double>(x*invNorm, y*invNorm);
- }
-}
-
-template<>
-Point<int> Point<int>::safeGetNormalized() const
-{
- // Not implemented - done to silence compiler warnings.
- AVG_ASSERT(false);
- return Point<int>(0,0);
-}
-
-template<class NUM>
-std::ostream& operator<<( std::ostream& os, const Point<NUM> &p)
-{
- os << "(" << p.x << "," << p.y << ")";
- return os;
-}
-
-template<class NUM>
-Point<NUM> operator *(double f, const Point<NUM>& pt)
-{
- return pt*f;
-}
-
-template<class NUM>
-Point<NUM> operator /(double f, const Point<NUM>& pt)
-{
- return pt/f;
-}
-
-bool almostEqual(const DPoint& pt1, const DPoint& pt2)
-{
- return (fabs(pt1.x-pt2.x)+fabs(pt1.y-pt2.y)) < 0.0001;
-}
-
-double vecAngle(const DPoint& pt1, const DPoint pt2)
-{
- double angle = fmod((atan2(pt1.y, pt1.x) - atan2(pt2.y, pt2.x)), 2*M_PI);
- if (angle < 0) {
- angle += 2*M_PI;
- }
- return angle;
-}
-
-template<class NUM>
-double calcDist(const Point<NUM>& pt1, const Point<NUM>& pt2)
-{
- return sqrt(double(sqr(pt1.x-pt2.x)+sqr(pt1.y-pt2.y)));
-}
-
-// Explicit instantiations.
-template class Point<double>;
-template std::ostream& operator<<( std::ostream& os, const Point<double> &p);
-template Point<double> operator *(double f, const Point<double>& pt);
-template Point<double> operator /(double f, const Point<double>& pt);
-template double calcDist(const Point<double>& pt1, const Point<double>& pt2);
-template double calcDistSquared(const Point<double>& pt1, const Point<double>& pt2);
-
-template class Point<int>;
-template std::ostream& operator<<( std::ostream& os, const Point<int> &p);
-template Point<int> operator *(double f, const Point<int>& pt);
-template Point<int> operator /(double f, const Point<int>& pt);
-template double calcDist(const Point<int>& pt1, const Point<int>& pt2);
-template double calcDistSquared(const Point<int>& pt1, const Point<int>& pt2);
-
-}
diff --git a/src/base/Point.h b/src/base/Point.h
deleted file mode 100644
index 3156aed..0000000
--- a/src/base/Point.h
+++ /dev/null
@@ -1,124 +0,0 @@
-//
-// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
-//
-// This library is free software; you can redistribute it and/or
-// modify it under the terms of the GNU Lesser General Public
-// License as published by the Free Software Foundation; either
-// version 2 of the License, or (at your option) any later version.
-//
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public
-// License along with this library; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-//
-// Current versions can be found at www.libavg.de
-//
-
-#ifndef _Point_H_
-#define _Point_H_
-
-#include "../api.h"
-#include "MathHelper.h"
-
-#include <ostream>
-#include <vector>
-
-// Fix for non-C99 win compilers up to MSVC++2008
-#if defined _MSC_VER
-#define isinf(x) (!_finite(x))
-#define isnan(x) (_isnan(x))
-#endif
-
-namespace avg {
-
-template<class NUM>
-class AVG_TEMPLATE_API Point
-{
-public:
- NUM x;
- NUM y;
-
- Point ();
- template<class ORIGNUM> explicit Point(const Point<ORIGNUM>& p);
- Point(NUM X, NUM Y);
- Point(const Point<NUM>& p);
- Point(const std::vector<NUM>& v);
- ~Point();
-
- Point<NUM> getNormalized() const;
- Point<NUM> safeGetNormalized() const;
- double getNorm() const;
- bool isNaN() const;
- bool isInf() const;
- Point getRotated(double angle) const;
- Point getRotatedPivot(double angle, const Point& pivot = Point(0,0)) const;
-
- Point<NUM> & operator =(const Point<NUM>& p);
-
- bool operator ==(const Point<NUM> & pt) const;
- bool operator !=(const Point<NUM> & pt) const;
- void operator +=(const Point<NUM> & pt);
- void operator -=(const Point<NUM> & pt);
- void operator *=(NUM f);
- void operator /=(NUM f);
- Point<NUM> operator -() const;
- Point<NUM> operator +(const Point<NUM> & pt) const;
- Point<NUM> operator -(const Point<NUM> & pt) const;
- Point<NUM> operator /(double f) const;
- Point<NUM> operator *(double f) const;
- Point<NUM> operator *(const Point<NUM> & pt) const;
-
- static Point<NUM> fromPolar(double angle, double radius);
- double getAngle() const;
-};
-
-template<class NUM>
-std::ostream& operator<<( std::ostream& os, const Point<NUM> &p);
-
-template<class NUM>
-Point<NUM> operator *(double f, const Point<NUM>& pt);
-
-template<class NUM>
-Point<NUM> operator /(double f, const Point<NUM>& pt);
-
-template<class NUM>
-template<class ORIGNUM>
-Point<NUM>::Point(const Point<ORIGNUM>& p)
- : x(NUM(p.x)),
- y(NUM(p.y))
-{
-// ObjectCounter::get()->incRef(&typeid(*this));
-}
-
-template<class NUM>
-double calcDist(const Point<NUM>& pt1, const Point<NUM>& pt2);
-
-template<class NUM>
-double calcDistSquared(const Point<NUM>& pt1, const Point<NUM>& pt2)
-{
- return sqr(pt1.x-pt2.x)+sqr(pt1.y-pt2.y);
-}
-
-typedef Point<double> DPoint;
-typedef Point<int> IntPoint;
-
-bool almostEqual(const DPoint& pt1, const DPoint& pt2);
-
-inline
-double dotProduct(const DPoint& pt1, const DPoint pt2)
-{
- return pt1.x*pt2.x+pt1.y*pt2.y;
-}
-
-double vecAngle(const DPoint& pt1, const DPoint pt2);
-
-typedef std::vector<DPoint> DPointVector;
-
-}
-
-#endif
diff --git a/src/base/ProfilingZone.cpp b/src/base/ProfilingZone.cpp
index a12f5e3..9cdbbfe 100644
--- a/src/base/ProfilingZone.cpp
+++ b/src/base/ProfilingZone.cpp
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -30,12 +30,11 @@ using namespace std;
namespace avg {
ProfilingZone::ProfilingZone(const ProfilingZoneID& zoneID)
- : m_ZoneID(zoneID),
- m_TimeSum(0),
+ : m_TimeSum(0),
m_AvgTime(0),
m_NumFrames(0),
m_Indent(0),
- m_bIsRegistered(false)
+ m_ZoneID(zoneID)
{
ObjectCounter::get()->incRef(&typeid(*this));
}
@@ -45,6 +44,13 @@ ProfilingZone::~ProfilingZone()
ObjectCounter::get()->decRef(&typeid(*this));
}
+void ProfilingZone::restart()
+{
+ m_NumFrames = 0;
+ m_AvgTime = 0;
+ m_TimeSum = 0;
+}
+
void ProfilingZone::reset()
{
m_NumFrames++;
diff --git a/src/base/ProfilingZone.h b/src/base/ProfilingZone.h
index f226d59..0d0ee42 100644
--- a/src/base/ProfilingZone.h
+++ b/src/base/ProfilingZone.h
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -35,6 +35,7 @@ class AVG_API ProfilingZone
public:
ProfilingZone(const ProfilingZoneID& zoneID);
virtual ~ProfilingZone();
+ void restart();
void start()
{
@@ -53,13 +54,12 @@ public:
const std::string& getName() const;
private:
- const ProfilingZoneID& m_ZoneID;
long long m_TimeSum;
long long m_AvgTime;
long long m_StartTime;
int m_NumFrames;
int m_Indent;
- bool m_bIsRegistered;
+ const ProfilingZoneID& m_ZoneID;
};
typedef boost::shared_ptr<ProfilingZone> ProfilingZonePtr;
diff --git a/src/base/ProfilingZoneID.cpp b/src/base/ProfilingZoneID.cpp
index 025be66..7256887 100644
--- a/src/base/ProfilingZoneID.cpp
+++ b/src/base/ProfilingZoneID.cpp
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -20,13 +20,16 @@
//
#include "ProfilingZoneID.h"
+#include "ThreadProfiler.h"
using namespace std;
namespace avg {
-ProfilingZoneID::ProfilingZoneID(const string& sName)
- : m_sName(sName)
+ProfilingZoneID::ProfilingZoneID(const string& sName, bool bMultithreaded)
+ : m_sName(sName),
+ m_bMultithreaded(bMultithreaded),
+ m_pProfiler(0)
{
}
@@ -39,4 +42,16 @@ const string& ProfilingZoneID::getName() const
return m_sName;
}
+ThreadProfiler* ProfilingZoneID::getProfiler()
+{
+ if (!m_pProfiler) {
+ if (m_bMultithreaded) {
+ return ThreadProfiler::get();
+ } else {
+ m_pProfiler = ThreadProfiler::get();
+ }
+ }
+ return m_pProfiler;
+}
+
}
diff --git a/src/base/ProfilingZoneID.h b/src/base/ProfilingZoneID.h
index c590b3d..ca4d637 100644
--- a/src/base/ProfilingZoneID.h
+++ b/src/base/ProfilingZoneID.h
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -28,16 +28,21 @@
namespace avg {
+class ThreadProfiler;
+
class AVG_API ProfilingZoneID
{
public:
- ProfilingZoneID(const std::string& sName);
- virtual ~ProfilingZoneID();
+ ProfilingZoneID(const std::string& sName, bool bMultithreaded=false);
+ ~ProfilingZoneID();
const std::string& getName() const;
+ ThreadProfiler* getProfiler();
private:
std::string m_sName;
+ bool m_bMultithreaded;
+ ThreadProfiler* m_pProfiler;
};
}
diff --git a/src/base/Queue.h b/src/base/Queue.h
index 35c8d92..36a0eba 100644
--- a/src/base/Queue.h
+++ b/src/base/Queue.h
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -34,7 +34,7 @@
namespace avg {
-typedef boost::mutex::scoped_lock scoped_lock;
+typedef boost::unique_lock<boost::mutex> unique_lock;
template<class QElement>
class AVG_TEMPLATE_API Queue
@@ -42,18 +42,19 @@ class AVG_TEMPLATE_API Queue
public:
typedef boost::shared_ptr<QElement> QElementPtr;
- Queue(int MaxSize=-1);
+ Queue(int maxSize=-1);
virtual ~Queue();
bool empty() const;
QElementPtr pop(bool bBlock = true);
- void push(const QElementPtr& Elem);
+ void clear();
+ void push(const QElementPtr& pElem);
QElementPtr peek(bool bBlock = true) const;
int size() const;
int getMaxSize() const;
private:
- QElementPtr getFrontElement(bool bBlock, scoped_lock& Lock) const;
+ QElementPtr getFrontElement(bool bBlock, unique_lock& Lock) const;
std::deque<QElementPtr> m_pElements;
mutable boost::mutex m_Mutex;
@@ -62,8 +63,8 @@ private:
};
template<class QElement>
-Queue<QElement>::Queue(int MaxSize)
- : m_MaxSize(MaxSize)
+Queue<QElement>::Queue(int maxSize)
+ : m_MaxSize(maxSize)
{
}
@@ -75,15 +76,15 @@ Queue<QElement>::~Queue()
template<class QElement>
bool Queue<QElement>::empty() const
{
- scoped_lock Lock(m_Mutex);
+ unique_lock Lock(m_Mutex);
return m_pElements.empty();
}
template<class QElement>
typename Queue<QElement>::QElementPtr Queue<QElement>::pop(bool bBlock)
{
- scoped_lock Lock(m_Mutex);
- QElementPtr pElem = getFrontElement(bBlock, Lock);
+ unique_lock lock(m_Mutex);
+ QElementPtr pElem = getFrontElement(bBlock, lock);
if (pElem) {
m_pElements.pop_front();
m_Cond.notify_one();
@@ -92,10 +93,19 @@ typename Queue<QElement>::QElementPtr Queue<QElement>::pop(bool bBlock)
}
template<class QElement>
+void Queue<QElement>::clear()
+{
+ QElementPtr pElem;
+ do {
+ pElem = pop(false);
+ } while (pElem);
+}
+
+template<class QElement>
typename Queue<QElement>::QElementPtr Queue<QElement>::peek(bool bBlock) const
{
- scoped_lock Lock(m_Mutex);
- QElementPtr pElem = getFrontElement(bBlock, Lock);
+ unique_lock lock(m_Mutex);
+ QElementPtr pElem = getFrontElement(bBlock, lock);
if (pElem) {
m_Cond.notify_one();
}
@@ -106,10 +116,10 @@ template<class QElement>
void Queue<QElement>::push(const QElementPtr& pElem)
{
assert(pElem);
- scoped_lock Lock(m_Mutex);
+ unique_lock lock(m_Mutex);
if (m_pElements.size() == (unsigned)m_MaxSize) {
while (m_pElements.size() == (unsigned)m_MaxSize) {
- m_Cond.wait(Lock);
+ m_Cond.wait(lock);
}
}
m_pElements.push_back(pElem);
@@ -119,25 +129,25 @@ void Queue<QElement>::push(const QElementPtr& pElem)
template<class QElement>
int Queue<QElement>::size() const
{
- scoped_lock Lock(m_Mutex);
+ unique_lock lock(m_Mutex);
return int(m_pElements.size());
}
template<class QElement>
int Queue<QElement>::getMaxSize() const
{
- scoped_lock Lock(m_Mutex);
+ unique_lock lock(m_Mutex);
return m_MaxSize;
}
template<class QElement>
typename Queue<QElement>::QElementPtr
- Queue<QElement>::getFrontElement(bool bBlock, scoped_lock& Lock) const
+ Queue<QElement>::getFrontElement(bool bBlock, unique_lock& lock) const
{
if (m_pElements.empty()) {
if (bBlock) {
while (m_pElements.empty()) {
- m_Cond.wait(Lock);
+ m_Cond.wait(lock);
}
} else {
return QElementPtr();
diff --git a/src/base/Rect.h b/src/base/Rect.h
index 25756de..d668338 100644
--- a/src/base/Rect.h
+++ b/src/base/Rect.h
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -23,7 +23,9 @@
#define _Rect_H_
#include "../api.h"
-#include "Point.h"
+
+#include "../base/GLMHelper.h"
+#include "../glm/glm.hpp"
#include <algorithm>
@@ -36,29 +38,30 @@ template<class NUM>
class AVG_TEMPLATE_API Rect
{
public:
- Point<NUM> tl;
- Point<NUM> br;
+ typedef glm::detail::tvec2<NUM> Vec2;
+ Vec2 tl;
+ Vec2 br;
Rect();
Rect(NUM left, NUM top, NUM right, NUM bottom);
- Rect(const Point<NUM>& TL, const Point<NUM>& BR);
+ Rect(const Vec2& TL, const Vec2& BR);
template<class ORIGNUM> Rect(const Rect<ORIGNUM>& rc);
bool operator ==(const Rect<NUM>& rect) const;
bool operator !=(const Rect<NUM> & rect) const;
NUM width() const;
NUM height() const;
- Point<NUM> center() const;
+ Vec2 center() const;
void setWidth(NUM width);
void setHeight(NUM height);
- void setSize(const Point<NUM>& size);
- bool contains(const Point<NUM>& pt) const;
+ void setSize(const Vec2& size);
+ bool contains(const Vec2& pt) const;
bool contains(const Rect<NUM>& rect) const;
bool intersects(const Rect<NUM>& rect) const;
void expand(const Rect<NUM>& rect);
void intersect(const Rect<NUM>& rect);
- Point<NUM> size() const;
- Point<NUM> cropPoint(const Point<NUM>& pt) const;
+ Vec2 size() const;
+ Vec2 cropPoint(const Vec2& pt) const;
};
template<class NUM>
@@ -69,7 +72,7 @@ std::ostream& operator<<( std::ostream& os, const Rect<NUM> &r)
}
-typedef Rect<double> DRect;
+typedef Rect<float> FRect;
typedef Rect<int> IntRect;
template<class NUM>
@@ -77,7 +80,7 @@ Rect<NUM>::Rect()
{}
template<class NUM>
-Rect<NUM>::Rect(const Point<NUM>& TL, const Point<NUM>& BR)
+Rect<NUM>::Rect(const Vec2& TL, const Vec2& BR)
: tl(TL), br(BR)
{}
@@ -120,9 +123,9 @@ NUM Rect<NUM>::height() const
}
template<class NUM>
-Point<NUM> Rect<NUM>::center() const
+glm::detail::tvec2<NUM> Rect<NUM>::center() const
{
- return Point<NUM>(tl+br)/2;
+ return Vec2(tl+br)/2;
}
template<class NUM>
@@ -138,14 +141,14 @@ void Rect<NUM>::setHeight(NUM height)
}
template<class NUM>
-void Rect<NUM>::setSize(const Point<NUM>& size)
+void Rect<NUM>::setSize(const Vec2& size)
{
setWidth(size.x);
setHeight(size.y);
}
template<class NUM>
-bool Rect<NUM>::contains(const Point<NUM>& pt) const
+bool Rect<NUM>::contains(const Vec2& pt) const
{
return (pt.x >= tl.x && pt.x < br.x &&
pt.y >= tl.y && pt.y < br.y);
@@ -154,7 +157,7 @@ bool Rect<NUM>::contains(const Point<NUM>& pt) const
template<class NUM>
bool Rect<NUM>::contains(const Rect<NUM>& rect) const
{
- Point<NUM> brpt (rect.br.x-1, rect.br.y-1);
+ Vec2 brpt (rect.br.x-1, rect.br.y-1);
return Contains(rect.tl) && Contains(brpt);
}
@@ -171,31 +174,31 @@ bool Rect<NUM>::intersects(const Rect<NUM>& rect) const
template<class NUM>
void Rect<NUM>::expand(const Rect<NUM>& rect)
{
- tl.x = std::min(tl.x, rect.tl.x);
- tl.y = std::min(tl.y, rect.tl.y);
- br.x = std::max(br.x, rect.br.x);
- br.y = std::max(br.y, rect.br.y);
+ tl.x = glm::min(tl.x, rect.tl.x);
+ tl.y = glm::min(tl.y, rect.tl.y);
+ br.x = glm::max(br.x, rect.br.x);
+ br.y = glm::max(br.y, rect.br.y);
}
template<class NUM>
void Rect<NUM>::intersect(const Rect<NUM>& rect)
{
- tl.x = std::max(tl.x, rect.tl.x);
- tl.y = std::max(tl.y, rect.tl.y);
- br.x = std::min(br.x, rect.br.x);
- br.y = std::min(br.y, rect.br.y);
+ tl.x = glm::max(tl.x, rect.tl.x);
+ tl.y = glm::max(tl.y, rect.tl.y);
+ br.x = glm::min(br.x, rect.br.x);
+ br.y = glm::min(br.y, rect.br.y);
}
template<class NUM>
-Point<NUM> Rect<NUM>::size() const
+glm::detail::tvec2<NUM> Rect<NUM>::size() const
{
- return Point<NUM>(width(), height());
+ return Vec2(width(), height());
}
template<class NUM>
-Point<NUM> Rect<NUM>::cropPoint(const Point<NUM>& pt) const
+glm::detail::tvec2<NUM> Rect<NUM>::cropPoint(const Vec2& pt) const
{
- Point<NUM> Result;
+ Vec2 Result;
Result.x = std::min(std::max(pt.x, tl.x), br.x-1);
Result.y = std::min(std::max(pt.y, tl.y), br.y-1);
return Result;
diff --git a/src/base/ScopeTimer.cpp b/src/base/ScopeTimer.cpp
index 1a353e8..eb95736 100644
--- a/src/base/ScopeTimer.cpp
+++ b/src/base/ScopeTimer.cpp
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -20,21 +20,16 @@
//
#include "ScopeTimer.h"
-#include "ThreadProfiler.h"
using namespace std;
namespace avg {
-ScopeTimer::ScopeTimer(ProfilingZoneID& zoneID)
- : m_ZoneID(zoneID)
-{
- ThreadProfiler::get()->startZone(zoneID);
-}
+bool ScopeTimer::s_bTimersEnabled = false;
-ScopeTimer::~ScopeTimer()
+void ScopeTimer::enableTimers(bool bEnable)
{
- ThreadProfiler::get()->stopZone(m_ZoneID);
+ s_bTimersEnabled = bEnable;
}
}
diff --git a/src/base/ScopeTimer.h b/src/base/ScopeTimer.h
index de62eb2..a87263f 100644
--- a/src/base/ScopeTimer.h
+++ b/src/base/ScopeTimer.h
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -24,16 +24,35 @@
#include "../api.h"
#include "ProfilingZoneID.h"
+#include "ThreadProfiler.h"
namespace avg {
-
+
class AVG_API ScopeTimer {
public:
- ScopeTimer(ProfilingZoneID& zoneID);
- virtual ~ScopeTimer();
-
+ ScopeTimer(ProfilingZoneID& zoneID)
+ {
+ if (s_bTimersEnabled) {
+ m_pZoneID = &zoneID;
+ m_pZoneID->getProfiler()->startZone(zoneID);
+ } else {
+ m_pZoneID = 0;
+ }
+ };
+
+ ~ScopeTimer()
+ {
+ if (m_pZoneID) {
+ m_pZoneID->getProfiler()->stopZone(*m_pZoneID);
+ }
+ };
+
+ static void enableTimers(bool bEnable);
+
private:
- ProfilingZoneID& m_ZoneID;
+ ProfilingZoneID* m_pZoneID;
+
+ static bool s_bTimersEnabled;
};
}
diff --git a/src/base/Signal.h b/src/base/Signal.h
index 0e6beb2..b670822 100644
--- a/src/base/Signal.h
+++ b/src/base/Signal.h
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
diff --git a/src/base/StandardLogSink.cpp b/src/base/StandardLogSink.cpp
new file mode 100644
index 0000000..510aa0b
--- /dev/null
+++ b/src/base/StandardLogSink.cpp
@@ -0,0 +1,54 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+
+#include "StandardLogSink.h"
+#include "Logger.h"
+
+#include <iostream>
+#include <iomanip>
+
+using namespace std;
+
+namespace avg
+{
+
+StandardLogSink::StandardLogSink()
+{
+
+}
+
+StandardLogSink::~StandardLogSink()
+{
+
+}
+
+void StandardLogSink::logMessage(const tm* pTime, unsigned millis,
+ const category_t& category, severity_t severity, const UTF8String& sMsg)
+{
+ char timeString[256];
+ strftime(timeString, sizeof(timeString), "%y-%m-%d %H:%M:%S", pTime);
+ cerr << "[" << timeString << "." <<
+ setw(3) << setfill('0') << millis << setw(0) << "][";
+ cerr << setw(4) << setfill('.') << Logger::severityToString(severity) << "][";
+ cerr << setw(9) << setfill('.') << category << "] : " << sMsg << endl;
+ cerr.flush();
+}
+
+}
diff --git a/src/base/CmdLine.h b/src/base/StandardLogSink.h
index db57104..7cbfe2c 100644
--- a/src/base/CmdLine.h
+++ b/src/base/StandardLogSink.h
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -17,34 +17,23 @@
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// Current versions can be found at www.libavg.de
-//
-
-#ifndef _CmdLine_H_
-#define _CmdLine_H_
-#include "../api.h"
-#include <string>
-#include <vector>
-#include <map>
+#ifndef _StandardLogSink_H_
+#define _StandardLogSink_H_
-namespace avg {
+#include "ILogSink.h"
-typedef std::map<std::string, std::string> OptionMap;
+namespace avg{
-class AVG_API CmdLine {
+class StandardLogSink: public ILogSink
+{
public:
- CmdLine(int argc, char **argv);
+ StandardLogSink();
+ virtual ~StandardLogSink ();
- const OptionMap& getOptions() const;
- const std::string* getOption(const std::string& sName) const;
- int getNumArgs() const;
- const std::string* getArg(unsigned int i) const;
-
-private:
- OptionMap m_Options;
- std::vector<std::string> m_Args;
+ virtual void logMessage(const tm* pTime, unsigned millis, const category_t& category,
+ severity_t severity, const UTF8String& sMsg);
};
}
-#endif
-
+#endif
diff --git a/src/base/StringHelper.cpp b/src/base/StringHelper.cpp
index ba02038..6155859 100644
--- a/src/base/StringHelper.cpp
+++ b/src/base/StringHelper.cpp
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -71,9 +71,9 @@ int stringToInt(const string& s)
return i;
}
-double stringToDouble(const string& s)
+float stringToFloat(const string& s)
{
- double d;
+ float d;
fromString(s, d);
return d;
}
@@ -92,28 +92,17 @@ bool stringToBool(const string& s)
throw (Exception(AVG_ERR_TYPE, string("Could not convert ")+s+" to bool."));
}
-DPoint stringToDPoint(const std::string& s)
-{
- DPoint pt;
- fromString(s, pt);
- return pt;
-}
-
-IntTriple stringToIntTriple(const std::string& s)
-{
- IntTriple pt;
- fromString(s, pt);
- return pt;
-}
-
std::string removeStartEndSpaces(const string& s)
{
string sResult = s;
- while (sResult[0] == ' ' || sResult[0] == '\n' || sResult[0] == '\r'
- || sResult[0] == '\t')
+ while (sResult.size() > 0 && (sResult[0] == ' ' || sResult[0] == '\n'
+ || sResult[0] == '\r' || sResult[0] == '\t'))
{
sResult.erase(0, 1);
}
+ if (sResult.size() == 0) {
+ return sResult;
+ }
char c = sResult[sResult.length()-1];
while (c == ' ' || c == '\n' || c == '\r' || c == '\t') {
sResult.erase(sResult.length()-1, 1);
@@ -143,5 +132,14 @@ bool equalIgnoreCase(const string& s1, const string& s2)
return sUpper1 == sUpper2;
}
+string toString(const bool& b)
+{
+ if (b) {
+ return "true";
+ } else {
+ return "false";
+ }
+}
+
}
diff --git a/src/base/StringHelper.h b/src/base/StringHelper.h
index 154a5f0..82713eb 100644
--- a/src/base/StringHelper.h
+++ b/src/base/StringHelper.h
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -24,13 +24,12 @@
#include "../api.h"
#include "Exception.h"
-#include "Point.h"
-#include "Triple.h"
#include <string>
#include <sstream>
#include <typeinfo>
#include <iostream>
+#include <vector>
#ifdef __GNUC__
#include <cxxabi.h>
@@ -38,20 +37,9 @@
namespace avg {
-bool isWhitespace(const std::string& s);
-void skipWhitespace(std::istream& is);
-void skipToken(std::istream& is, char token);
-
-template<class NUM>
-std::istream& operator>>(std::istream& is, Point<NUM>& p)
-{
- skipToken(is, '(');
- is >> p.x;
- skipToken(is, ',');
- is >> p.y;
- skipToken(is, ')');
- return is;
-}
+bool AVG_API isWhitespace(const std::string& s);
+void AVG_API skipWhitespace(std::istream& is);
+void AVG_API skipToken(std::istream& is, char token);
template<class T>
std::istream& operator >>(std::istream& is, std::vector<T>& v)
@@ -86,17 +74,15 @@ std::istream& operator >>(std::istream& is, std::vector<T>& v)
return is;
}
-int stringToInt(const std::string& s);
-double stringToDouble(const std::string& s);
-bool stringToBool(const std::string& s);
-DPoint stringToDPoint(const std::string& s);
-IntTriple stringToIntTriple(const std::string& s);
+int AVG_API stringToInt(const std::string& s);
+float AVG_API stringToFloat(const std::string& s);
+bool AVG_API stringToBool(const std::string& s);
-std::string removeStartEndSpaces(const std::string& s);
+std::string AVG_API removeStartEndSpaces(const std::string& s);
-std::string toLowerCase(const std::string& s);
+std::string AVG_API toLowerCase(const std::string& s);
-bool equalIgnoreCase(const std::string& s1, const std::string& s2);
+bool AVG_API equalIgnoreCase(const std::string& s1, const std::string& s2);
template<class T>
std::string toString(const T& i)
@@ -106,6 +92,8 @@ std::string toString(const T& i)
return stream.str();
}
+std::string AVG_API toString(const bool& b);
+
template<class T>
std::string getFriendlyTypeName(const T& dummy)
{
diff --git a/src/base/Test.cpp b/src/base/Test.cpp
index 8825d45..b2c0b12 100644
--- a/src/base/Test.cpp
+++ b/src/base/Test.cpp
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -44,7 +44,7 @@ Test::~Test()
{
}
-void Test::test (bool b, const char * pszFile, int line)
+void Test::test(bool b, const char * pszFile, int line)
{
if (b) {
m_NumSucceeded++;
diff --git a/src/base/Test.h b/src/base/Test.h
index ef39bc5..0cc20ba 100644
--- a/src/base/Test.h
+++ b/src/base/Test.h
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -56,7 +56,6 @@ protected:
int m_IndentLevel;
private:
- bool m_bOk;
int m_NumSucceeded;
int m_NumFailed;
std::string m_sName;
diff --git a/src/base/TestSuite.cpp b/src/base/TestSuite.cpp
index 87130da..16a254c 100644
--- a/src/base/TestSuite.cpp
+++ b/src/base/TestSuite.cpp
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -53,6 +53,10 @@ void TestSuite::runTests()
} catch (Exception& ex) {
cerr << string(m_IndentLevel, ' ') << ex.getStr() << endl;
setFailed();
+ } catch (std::exception& ex) {
+ cerr << string(m_IndentLevel, ' ') << " ---->> failed, std::exception: "
+ << ex.what() << endl;
+ setFailed();
} catch (...) {
cerr << string(m_IndentLevel, ' ') <<
" ---->> failed, exception caught" << endl;
diff --git a/src/base/TestSuite.h b/src/base/TestSuite.h
index d85eef8..124bbc2 100644
--- a/src/base/TestSuite.h
+++ b/src/base/TestSuite.h
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
diff --git a/src/base/ThreadHelper.cpp b/src/base/ThreadHelper.cpp
new file mode 100644
index 0000000..105e116
--- /dev/null
+++ b/src/base/ThreadHelper.cpp
@@ -0,0 +1,94 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "ThreadHelper.h"
+#include "OSHelper.h"
+
+#ifdef _WIN32
+#include <Windows.h>
+#endif
+
+namespace avg {
+
+void setAffinityMask(bool bIsMainThread)
+{
+ // The main thread gets the first processor to itself. All other threads share the
+ // rest of the processors available, unless, of course, there is only one processor
+ // in the machine.
+#ifdef linux
+ static cpu_set_t allProcessors;
+ static bool bInitialized = false;
+ if (!bInitialized) {
+ int rc = sched_getaffinity(0, sizeof(allProcessors), &allProcessors);
+ AVG_ASSERT(rc == 0);
+// cerr << "All processors: ";
+// printAffinityMask(allProcessors);
+ bInitialized = true;
+ }
+ cpu_set_t mask;
+ if (bIsMainThread) {
+ CPU_ZERO(&mask);
+ CPU_SET(0, &mask);
+// cerr << "Main Thread: ";
+ } else {
+ mask = allProcessors;
+ if (CPU_COUNT(&mask) > 1) {
+ CPU_CLR(0, &mask);
+ }
+// cerr << "Aux Thread: ";
+ }
+// printAffinityMask(mask);
+ int rc = sched_setaffinity(0, sizeof(mask), &mask);
+ AVG_ASSERT(rc == 0);
+#elif defined _WIN32
+ DWORD processAffinityMask;
+ DWORD systemAffinityMask;
+ BOOL rc = GetProcessAffinityMask(GetCurrentProcess(), &processAffinityMask,
+ &systemAffinityMask);
+ AVG_ASSERT(rc == TRUE);
+ DWORD mainThreadMask = 1 << getLowestBitSet(processAffinityMask);
+ DWORD mask;
+ if (bIsMainThread) {
+ mask = mainThreadMask;
+ } else {
+ mask = processAffinityMask & ~mainThreadMask;
+ if (mask == 0) {
+ mask = processAffinityMask;
+ }
+ }
+ DWORD_PTR pPrevMask = SetThreadAffinityMask(GetCurrentThread(), mask);
+ AVG_ASSERT_MSG(pPrevMask != 0, getWinErrMsg(GetLastError()).c_str());
+#endif
+}
+
+unsigned getLowestBitSet(unsigned val)
+{
+ AVG_ASSERT(val != 0); // Doh
+
+ unsigned pos = 0;
+ while (!(val & 1)) {
+ val >>= 1;
+ ++pos;
+ }
+ return pos;
+}
+
+}
diff --git a/src/base/ThreadHelper.h b/src/base/ThreadHelper.h
new file mode 100644
index 0000000..7acf640
--- /dev/null
+++ b/src/base/ThreadHelper.h
@@ -0,0 +1,37 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef _ThreadHelper_H_
+#define _ThreadHelper_H_
+
+#include "Exception.h"
+#include <boost/thread.hpp>
+#include <boost/thread/locks.hpp>
+
+namespace avg {
+
+void AVG_API setAffinityMask(bool bIsMainThread);
+typedef boost::lock_guard<boost::mutex> lock_guard;
+unsigned getLowestBitSet(unsigned val);
+
+}
+
+#endif
diff --git a/src/base/ThreadProfiler.cpp b/src/base/ThreadProfiler.cpp
index 12715c7..1f1a354 100644
--- a/src/base/ThreadProfiler.cpp
+++ b/src/base/ThreadProfiler.cpp
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -20,8 +20,11 @@
//
#include "ThreadProfiler.h"
+
#include "Logger.h"
#include "Exception.h"
+#include "ProfilingZone.h"
+#include "ScopeTimer.h"
#include <sstream>
#include <iomanip>
@@ -32,33 +35,37 @@ using namespace boost;
namespace avg {
-thread_specific_ptr<ThreadProfilerPtr> ThreadProfiler::s_pInstance;
+thread_specific_ptr<ThreadProfiler*> ThreadProfiler::s_pInstance;
-ThreadProfilerPtr& ThreadProfiler::get()
+ThreadProfiler* ThreadProfiler::get()
{
if (s_pInstance.get() == 0) {
- s_pInstance.reset(new ThreadProfilerPtr(new ThreadProfiler()));
+ s_pInstance.reset(new (ThreadProfiler*));
+ *s_pInstance = new ThreadProfiler();
}
return *s_pInstance;
}
void ThreadProfiler::kill()
{
+ delete *s_pInstance;
s_pInstance.reset();
}
ThreadProfiler::ThreadProfiler()
: m_sName(""),
- m_LogCategory(Logger::PROFILE)
+ m_LogCategory(Logger::category::PROFILE)
{
m_bRunning = false;
+ ScopeTimer::enableTimers(Logger::get()->shouldLog(m_LogCategory,
+ Logger::severity::INFO));
}
ThreadProfiler::~ThreadProfiler()
{
}
-void ThreadProfiler::setLogCategory(long category)
+void ThreadProfiler::setLogCategory(category_t category)
{
AVG_ASSERT(!m_bRunning);
m_LogCategory = category;
@@ -69,9 +76,12 @@ void ThreadProfiler::start()
m_bRunning = true;
}
-bool ThreadProfiler::isRunning()
+void ThreadProfiler::restart()
{
- return m_bRunning;
+ ZoneVector::iterator it;
+ for (it = m_Zones.begin(); it != m_Zones.end(); ++it) {
+ (*it)->restart();
+ }
}
void ThreadProfiler::startZone(const ProfilingZoneID& zoneID)
@@ -93,47 +103,34 @@ void ThreadProfiler::startZone(const ProfilingZoneID& zoneID)
void ThreadProfiler::stopZone(const ProfilingZoneID& zoneID)
{
ZoneMap::iterator it = m_ZoneMap.find(&zoneID);
- AVG_ASSERT(it != m_ZoneMap.end());
ProfilingZonePtr& pZone = it->second;
- AVG_ASSERT(m_ActiveZones.back() == pZone);
pZone->stop();
m_ActiveZones.pop_back();
}
-void ThreadProfiler::dumpFrame()
-{
- AVG_TRACE(Logger::PROFILE_LATEFRAMES, "Frame Profile:");
- ZoneList::iterator it;
- for (it = m_Zones.begin(); it != m_Zones.end(); ++it) {
- AVG_TRACE(Logger::PROFILE_LATEFRAMES,
- std::setw(35) << std::left
- << ((*it)->getIndentString() + (*it)->getName())
- << std::setw(9) << std::right << (*it)->getUSecs());
- }
- AVG_TRACE(Logger::PROFILE_LATEFRAMES, "");
-}
-
void ThreadProfiler::dumpStatistics()
{
if (!m_Zones.empty()) {
- AVG_TRACE(m_LogCategory, "Thread " << m_sName);
- AVG_TRACE(m_LogCategory, "Zone name Avg. time");
- AVG_TRACE(m_LogCategory, "--------- ---------");
+ AVG_TRACE(m_LogCategory, Logger::severity::INFO, "Thread " << m_sName);
+ AVG_TRACE(m_LogCategory, Logger::severity::INFO,
+ "Zone name Avg. time");
+ AVG_TRACE(m_LogCategory, Logger::severity::INFO,
+ "--------- ---------");
- ZoneList::iterator it;
+ ZoneVector::iterator it;
for (it = m_Zones.begin(); it != m_Zones.end(); ++it) {
- AVG_TRACE(m_LogCategory,
+ AVG_TRACE(m_LogCategory, Logger::severity::INFO,
std::setw(35) << std::left
<< ((*it)->getIndentString()+(*it)->getName())
<< std::setw(9) << std::right << (*it)->getAvgUSecs());
}
- AVG_TRACE(m_LogCategory, "");
+ AVG_TRACE(m_LogCategory, Logger::severity::INFO, "");
}
}
void ThreadProfiler::reset()
{
- ZoneList::iterator it;
+ ZoneVector::iterator it;
for (it = m_Zones.begin(); it != m_Zones.end(); ++it) {
(*it)->reset();
}
@@ -159,7 +156,7 @@ ProfilingZonePtr ThreadProfiler::addZone(const ProfilingZoneID& zoneID)
{
ProfilingZonePtr pZone(new ProfilingZone(zoneID));
m_ZoneMap[&zoneID] = pZone;
- ZoneList::iterator it;
+ ZoneVector::iterator it;
int parentIndent = -2;
if (m_ActiveZones.empty()) {
it = m_Zones.end();
@@ -176,7 +173,7 @@ ProfilingZonePtr ThreadProfiler::addZone(const ProfilingZoneID& zoneID)
AVG_ASSERT(bParentFound);
parentIndent = pActiveZone->getIndentLevel();
++it;
- for (; it != m_Zones.end() && (*it)->getIndentLevel() > parentIndent; ++it);
+ for (; it != m_Zones.end() && (*it)->getIndentLevel() > parentIndent; ++it) {};
}
m_Zones.insert(it, pZone);
pZone->setIndentLevel(parentIndent+2);
diff --git a/src/base/ThreadProfiler.h b/src/base/ThreadProfiler.h
index a571220..a581271 100644
--- a/src/base/ThreadProfiler.h
+++ b/src/base/ThreadProfiler.h
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -23,34 +23,40 @@
#define _ThreadProfiler_H_
#include "../api.h"
-#include "ProfilingZone.h"
+#include "ILogSink.h"
#include <boost/thread.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/thread/tss.hpp>
-#include <list>
+#include <vector>
#include <map>
-
+#if defined(_WIN32) || defined(_LIBCPP_VERSION)
+#include <unordered_map>
+#else
+#include <tr1/unordered_map>
+#endif
namespace avg {
class ThreadProfiler;
typedef boost::shared_ptr<ThreadProfiler> ThreadProfilerPtr;
+class ProfilingZone;
+typedef boost::shared_ptr<ProfilingZone> ProfilingZonePtr;
+class ProfilingZoneID;
class AVG_API ThreadProfiler
{
public:
- static ThreadProfilerPtr& get();
+ static ThreadProfiler* get();
static void kill();
ThreadProfiler();
virtual ~ThreadProfiler();
- void setLogCategory(long category);
+ void setLogCategory(category_t category);
void start();
- bool isRunning();
+ void restart();
void startZone(const ProfilingZoneID& zoneID);
void stopZone(const ProfilingZoneID& zoneID);
- void dumpFrame();
void dumpStatistics();
void reset();
int getNumZones();
@@ -62,15 +68,19 @@ private:
ProfilingZonePtr addZone(const ProfilingZoneID& zoneID);
std::string m_sName;
- typedef std::map<const ProfilingZoneID*, ProfilingZonePtr> ZoneMap;
- typedef std::list<ProfilingZonePtr> ZoneList;
+#if defined(_WIN32) || defined(_LIBCPP_VERSION)
+ typedef std::unordered_map<const ProfilingZoneID*, ProfilingZonePtr> ZoneMap;
+#else
+ typedef std::tr1::unordered_map<const ProfilingZoneID*, ProfilingZonePtr> ZoneMap;
+#endif
+ typedef std::vector<ProfilingZonePtr> ZoneVector;
ZoneMap m_ZoneMap;
- ZoneList m_ActiveZones;
- ZoneList m_Zones;
+ ZoneVector m_ActiveZones;
+ ZoneVector m_Zones;
bool m_bRunning;
- long m_LogCategory;
+ category_t m_LogCategory;
- static boost::thread_specific_ptr<ThreadProfilerPtr> s_pInstance;
+ static boost::thread_specific_ptr<ThreadProfiler*> s_pInstance;
};
}
diff --git a/src/base/TimeSource.cpp b/src/base/TimeSource.cpp
index 320b3ff..e90575d 100644
--- a/src/base/TimeSource.cpp
+++ b/src/base/TimeSource.cpp
@@ -1,6 +1,6 @@
//
-// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -34,12 +34,12 @@
#endif
#include <sys/stat.h>
#include <sys/types.h>
-#include <unistd.h>
#include <errno.h>
#include <assert.h>
#include <iostream>
#include <sstream>
+#include <unistd.h>
using namespace std;
@@ -56,8 +56,8 @@ TimeSource * TimeSource::get()
MMRESULT err = timeGetDevCaps(&tc, sizeof(TIMECAPS));
AVG_ASSERT(err == TIMERR_NOERROR);
wTimerRes = max(tc.wPeriodMin, 1);
- timeBeginPeriod(wTimerRes);
-#endif
+ timeBeginPeriod(wTimerRes);
+#endif
m_pTimeSource = new TimeSource;
}
return m_pTimeSource;
@@ -92,15 +92,15 @@ long long TimeSource::getCurrentMicrosecs()
int rc = clock_gettime(CLOCK_MONOTONIC, &now);
assert(rc == 0);
return ((long long)now.tv_sec)*1000000+now.tv_nsec/1000;
-#endif
-#endif
+#endif
+#endif
}
void TimeSource::sleepUntil(long long targetTime)
{
long long now = getCurrentMillisecs();
#ifdef __APPLE__
- if (targetTime > now) {
+ if (targetTime > now) {
msleep(targetTime-now);
}
#else
@@ -114,7 +114,7 @@ void TimeSource::sleepUntil(long long targetTime)
}
#endif
}
-
+
void msleep(int millisecs)
{
#if _WIN32
diff --git a/src/base/TimeSource.h b/src/base/TimeSource.h
index 63679fe..a4ca9ae 100644
--- a/src/base/TimeSource.h
+++ b/src/base/TimeSource.h
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
diff --git a/src/base/Triangle.cpp b/src/base/Triangle.cpp
index 039c643..7efe9f7 100644
--- a/src/base/Triangle.cpp
+++ b/src/base/Triangle.cpp
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -21,11 +21,13 @@
#include "Triangle.h"
+#include "GLMHelper.h"
+
#include <math.h>
namespace avg {
-Triangle::Triangle(const DPoint& P0, const DPoint& P1, const DPoint& P2)
+Triangle::Triangle(const glm::vec2& P0, const glm::vec2& P1, const glm::vec2& P2)
: p0(P0),
p1(P1),
p2(P2)
@@ -41,48 +43,48 @@ bool Triangle::operator ==(const Triangle & tri) const
return (p0 == tri.p0 && p1 == tri.p1 && p2 == tri.p2);
}
-bool Triangle::isInside(const DPoint& pt) const
+bool Triangle::isInside(const glm::vec2& pt) const
{
/* Slower func that only works for cw triangles.
- DPoint a = p2-p1;
- DPoint bp = pt-p1;
- double aCROSSbp = a.x*bp.y - a.y*bp.x;
+ glm::vec2 a = p2-p1;
+ glm::vec2 bp = pt-p1;
+ float aCROSSbp = a.x*bp.y - a.y*bp.x;
if (aCROSSbp < 0.0) {
return false;
}
- DPoint b = p0-p2;
- DPoint cp = pt-p2;
- double bCROSScp = b.x*cp.y - b.y*cp.x;
+ glm::vec2 b = p0-p2;
+ glm::vec2 cp = pt-p2;
+ float bCROSScp = b.x*cp.y - b.y*cp.x;
if (bCROSScp < 0.0) {
return false;
}
- DPoint c = p1-p0;
- DPoint ap = pt-p0;
- double cCROSSap = c.x*ap.y - c.y*ap.x;
+ glm::vec2 c = p1-p0;
+ glm::vec2 ap = pt-p0;
+ float cCROSSap = c.x*ap.y - c.y*ap.x;
return cCROSSap >= 0.0;
*/
- DPoint v0 = p2 - p0;
- DPoint v1 = p1 - p0;
- DPoint v2 = pt - p0;
+ glm::vec2 v0 = p2 - p0;
+ glm::vec2 v1 = p1 - p0;
+ glm::vec2 v2 = pt - p0;
- double dot00 = dotProduct(v0, v0);
- double dot01 = dotProduct(v0, v1);
- double dot02 = dotProduct(v0, v2);
- double dot11 = dotProduct(v1, v1);
- double dot12 = dotProduct(v1, v2);
+ float dot00 = glm::dot(v0, v0);
+ float dot01 = glm::dot(v0, v1);
+ float dot02 = glm::dot(v0, v2);
+ float dot11 = glm::dot(v1, v1);
+ float dot12 = glm::dot(v1, v2);
- double invDenom = 1 / (dot00 * dot11 - dot01 * dot01);
- double u = (dot11 * dot02 - dot01 * dot12) * invDenom;
- double v = (dot00 * dot12 - dot01 * dot02) * invDenom;
+ float invDenom = 1 / (dot00 * dot11 - dot01 * dot01);
+ float u = (dot11 * dot02 - dot01 * dot12) * invDenom;
+ float v = (dot00 * dot12 - dot01 * dot02) * invDenom;
return (u > 0) && (v > 0) && (u + v < 1);
}
-double Triangle::getArea() const
+float Triangle::getArea() const
{
return fabs((((p1.x-p0.x)*(p2.y-p0.y)) - ((p1.y-p0.y)*(p2.x-p0.x)))/2);
}
diff --git a/src/base/Triangle.h b/src/base/Triangle.h
index a9722fb..21ad35f 100644
--- a/src/base/Triangle.h
+++ b/src/base/Triangle.h
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -24,22 +24,24 @@
#include "../api.h"
-#include "Point.h"
+#include "../glm/glm.hpp"
+
+#include <iostream>
namespace avg {
struct AVG_API Triangle {
public:
- DPoint p0;
- DPoint p1;
- DPoint p2;
+ glm::vec2 p0;
+ glm::vec2 p1;
+ glm::vec2 p2;
- Triangle(const DPoint& P0, const DPoint& P1, const DPoint& P2);
+ Triangle(const glm::vec2& P0, const glm::vec2& P1, const glm::vec2& P2);
Triangle();
bool operator ==(const Triangle & tri) const;
- bool isInside(const DPoint& pt) const;
- double getArea() const;
+ bool isInside(const glm::vec2& pt) const;
+ float getArea() const;
bool isClockwise() const;
};
diff --git a/src/base/Triangulate.cpp b/src/base/Triangulate.cpp
deleted file mode 100644
index bbd9ef5..0000000
--- a/src/base/Triangulate.cpp
+++ /dev/null
@@ -1,139 +0,0 @@
-// Original code by John W. Ratcliff presumed to be in the public domain. Found
-// at http://www.flipcode.com/archives/Efficient_Polygon_Triangulation.shtml.
-
-#include "Triangulate.h"
-#include "Exception.h"
-
-#include "../base/Exception.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <iostream>
-
-namespace avg {
-
-using namespace std;
-
-double getPolygonArea(const DPointVector &contour)
-{
- int n = contour.size();
-
- double A=0.0;
-
- for (int p=n-1,q=0; q<n; p=q++) {
- A += contour[p].x*contour[q].y - contour[q].x*contour[p].y;
- }
- return A*0.5;
-}
-
-
-bool snip(const DPointVector &contour,int u,int v,int w,int n,int *V)
-{
- int p;
- Triangle tri;
- tri.p0 = contour[V[u]];
- tri.p1 = contour[V[v]];
- tri.p2 = contour[V[w]];
-
-// double area = tri.getArea();
-
- if (tri.isClockwise()) {
- return false;
- }
-
- for (p=0; p<n; p++) {
- if( (p == u) || (p == v) || (p == w) ) {
- continue;
- }
- if (tri.isInside(contour[V[p]])) {
- return false;
- }
- }
-
- return true;
-}
-
-
-// TODO: There's code that's probably faster in Graphics Gems V:
-// http://tog.acm.org/resources/GraphicsGems/gemsv/ch7-5/
-void triangulatePolygon(const DPointVector &contour, vector<int> &resultIndexes)
-{
- /* allocate and initialize list of Vertices in polygon */
-
- int n = contour.size();
- AVG_ASSERT(n>2);
-
- int *V = new int[n];
-
- // we want a counter-clockwise polygon in V.
- if (0.0 < getPolygonArea(contour)) {
- for (int v=0; v<n; v++) {
- V[v] = v;
- }
- } else {
- for(int v=0; v<n; v++) {
- V[v] = (n-1)-v;
- }
- }
-
- int nv = n;
-
- /* remove nv-2 Vertices, creating 1 triangle every time */
- int count = 2*nv; /* error detection */
-
- for(int m=0, v=nv-1; nv>2; )
- {
- if (count <= 0) {
- delete V;
- throw Exception(AVG_ERR_INVALID_ARGS,
- "Non-simple polygon: Self-intersecting polygons or degenerate polygons are not supported.");
- }
- count--;
-
- /* three consecutive vertices in current polygon, <u,v,w> */
- int u = v;
- if (nv <= u) {
- u = 0; /* previous */
- }
- v = u+1;
- if (nv <= v) {
- v = 0;
- }
- int w = v+1;
- if (nv <= w) {
- w = 0;
- }
-
- if (snip(contour,u,v,w,nv,V))
- {
- int a,b,c,s,t;
-
- /* true names of the vertices */
- a = V[u]; b = V[v]; c = V[w];
-
- /* output Triangle */
-
- resultIndexes.push_back(a);
- resultIndexes.push_back(b);
- resultIndexes.push_back(c);
-
- m++;
-
- /* remove v from remaining polygon */
- for(s=v,t=v+1; t<nv; s++,t++) {
- V[s] = V[t];
- }
- nv--;
-
- /* resest error detection counter */
- count = 2*nv;
-
- }
- }
-
- delete[] V;
-}
-
-}
-
diff --git a/src/base/Triangulate.h b/src/base/Triangulate.h
deleted file mode 100644
index d2b4ef6..0000000
--- a/src/base/Triangulate.h
+++ /dev/null
@@ -1,22 +0,0 @@
-// Original code by John W. Ratcliff presumed to be in the public domain. Found
-// at http://www.flipcode.com/archives/Efficient_Polygon_Triangulation.shtml.
-
-#ifndef _Triangulate_H_
-#define _Triangulate_H_
-
-#include "Point.h"
-#include "Triangle.h"
-
-#include <vector>
-
-namespace avg {
-
-// Result type is suitable for use in a Triangle Vertex Array.
-void triangulatePolygon(const DPointVector &contour, std::vector<int> &resultIndexes);
-
-double getPolygonArea(const DPointVector &contour);
-
-}
-
-#endif
-
diff --git a/src/base/Triple.cpp b/src/base/Triple.cpp
deleted file mode 100644
index 8249f72..0000000
--- a/src/base/Triple.cpp
+++ /dev/null
@@ -1,107 +0,0 @@
-//
-// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
-//
-// This library is free software; you can redistribute it and/or
-// modify it under the terms of the GNU Lesser General Public
-// License as published by the Free Software Foundation; either
-// version 2 of the License, or (at your option) any later version.
-//
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public
-// License along with this library; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-//
-// Current versions can be found at www.libavg.de
-//
-
-#include "Triple.h"
-
-#include "MathHelper.h"
-#include "StringHelper.h"
-#include "Exception.h"
-
-#if defined(__SSE__) || defined(_WIN32)
-#include <xmmintrin.h>
-#endif
-
-#include <math.h>
-#include <float.h>
-
-#include <string>
-
-namespace avg {
-
-template<class NUM>
-Triple<NUM>::Triple()
-{
- x = 0;
- y = 0;
- z = 0;
-}
-
-template<class NUM>
-Triple<NUM>::Triple(NUM X, NUM Y, NUM Z)
-{
- x = X;
- y = Y;
- z = Z;
-}
-
-template<class NUM>
-Triple<NUM>::Triple(const Triple<NUM>& p)
-{
- x = p.x;
- y = p.y;
- z = p.z;
-}
-
-
-template<class NUM>
-Triple<NUM>::Triple(const std::vector<NUM>& v)
-{
- AVG_ASSERT(v.size() == 3);
- x = v[0];
- y = v[1];
- z = v[2];
-}
-
-template<class NUM>
-Triple<NUM>::~Triple()
-{
-}
-
-template<class NUM>
-std::ostream& operator<<(std::ostream& os, const Triple<NUM> &p)
-{
- os << "(" << p.x << "," << p.y << "," << p.z << ")";
- return os;
-}
-
-template<class NUM>
-std::istream& operator>>(std::istream& is, Triple<NUM>& p)
-{
- skipToken(is, '(');
- is >> p.x;
- skipToken(is, ',');
- is >> p.y;
- skipToken(is, ',');
- is >> p.z;
- skipToken(is, ')');
- return is;
-}
-
-// Explicit instantiations.
-template class Triple<double>;
-template std::ostream& operator<<(std::ostream& os, const Triple<double> &p);
-template std::istream& operator>>(std::istream& is, Triple<double>& p);
-
-template class Triple<int>;
-template std::ostream& operator<<(std::ostream& os, const Triple<int> &p);
-template std::istream& operator>>(std::istream& is, Triple<int>& p);
-
-}
diff --git a/src/base/UTF8String.cpp b/src/base/UTF8String.cpp
index 214901b..4855364 100644
--- a/src/base/UTF8String.cpp
+++ b/src/base/UTF8String.cpp
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -54,4 +54,9 @@ UTF8String& UTF8String::operator =(const char* psz)
return *this;
}
+std::size_t hash_value(const avg::UTF8String& x)
+{
+ boost::hash<std::string> hasher;
+ return hasher(x);
+};
}
diff --git a/src/base/UTF8String.h b/src/base/UTF8String.h
index 2c0f1be..3cee69d 100644
--- a/src/base/UTF8String.h
+++ b/src/base/UTF8String.h
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -23,6 +23,7 @@
#define _UTF8String_H_
#include "../api.h"
+#include <boost/functional/hash.hpp>
#include <string>
namespace avg {
@@ -39,5 +40,7 @@ public:
};
+std::size_t hash_value(const avg::UTF8String& x);
+
}
#endif
diff --git a/src/base/WideLine.cpp b/src/base/WideLine.cpp
index 04e3162..84f4096 100644
--- a/src/base/WideLine.cpp
+++ b/src/base/WideLine.cpp
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -21,24 +21,26 @@
#include "WideLine.h"
+#include "GLMHelper.h"
+
namespace avg {
-WideLine::WideLine(const DPoint& p0, const DPoint& p1, double width)
+WideLine::WideLine(const glm::vec2& p0, const glm::vec2& p1, float width)
: pt0(p0),
pt1(p1)
{
- DPoint m = (pt1-pt0).getNormalized();
- DPoint w = DPoint(m.y, -m.x)*width/2;
+ glm::vec2 m = glm::normalize(pt1-pt0);
+ glm::vec2 w = glm::vec2(m.y, -m.x)*(width/2);
pl0 = p0-w;
pr0 = p0+w;
pl1 = p1-w;
pr1 = p1+w;
- dir = DPoint(w.y, -w.x);
+ dir = glm::vec2(w.y, -w.x);
}
-double WideLine::getLen() const
+float WideLine::getLen() const
{
- return calcDist(pt0, pt1);
+ return glm::length(pt1-pt0);
}
std::ostream& operator<<(std::ostream& os, const WideLine& line)
diff --git a/src/base/WideLine.h b/src/base/WideLine.h
index 0235c20..28584ef 100644
--- a/src/base/WideLine.h
+++ b/src/base/WideLine.h
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -24,21 +24,21 @@
#include "../api.h"
-#include "Point.h"
+#include "../glm/glm.hpp"
#include <iostream>
namespace avg {
struct AVG_API WideLine {
- WideLine(const DPoint& p0, const DPoint& p1, double width);
+ WideLine(const glm::vec2& p0, const glm::vec2& p1, float width);
- double getLen() const;
+ float getLen() const;
- DPoint pt0, pt1;
- DPoint pl0, pl1;
- DPoint pr0, pr1;
- DPoint dir;
+ glm::vec2 pt0, pt1;
+ glm::vec2 pl0, pl1;
+ glm::vec2 pr0, pr1;
+ glm::vec2 dir;
};
std::ostream& operator<<(std::ostream& os, const WideLine& line);
diff --git a/src/base/WorkerThread.cpp b/src/base/WorkerThread.cpp
new file mode 100644
index 0000000..f2efb0a
--- /dev/null
+++ b/src/base/WorkerThread.cpp
@@ -0,0 +1,41 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "WorkerThread.h"
+
+#include "OSHelper.h"
+
+namespace avg {
+
+using namespace std;
+
+#ifdef linux
+void printAffinityMask(cpu_set_t& mask)
+{
+ for (int i=0; i<32; ++i) {
+ cerr << int(CPU_ISSET(i, &mask));
+ }
+ cerr << endl;
+}
+#endif
+
+}
+
diff --git a/src/base/WorkerThread.h b/src/base/WorkerThread.h
index 6e5dba0..c4cc3c4 100644
--- a/src/base/WorkerThread.h
+++ b/src/base/WorkerThread.h
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -27,8 +27,8 @@
#include "Exception.h"
#include "Logger.h"
#include "Queue.h"
+#include "ThreadHelper.h"
#include "ThreadProfiler.h"
-#include "ObjectCounter.h"
#include "CmdQueue.h"
#include <boost/shared_ptr.hpp>
@@ -47,7 +47,7 @@ public:
typedef typename boost::shared_ptr<CQueue> CQueuePtr;
WorkerThread(const std::string& sName, CQueue& CmdQ,
- long logCategory=Logger::PROFILE);
+ category_t logCategory=Logger::category::PROFILE);
WorkerThread(WorkerThread const& other);
virtual ~WorkerThread();
void operator()();
@@ -55,6 +55,9 @@ public:
void waitForCommand();
void stop();
+protected:
+ int getNumCmdsInQueue() const;
+
private:
virtual bool init();
virtual bool work() = 0;
@@ -65,18 +68,17 @@ private:
std::string m_sName;
bool m_bShouldStop;
CQueue& m_CmdQ;
- long m_LogCategory;
+ category_t m_LogCategory;
};
template<class DERIVED_THREAD>
WorkerThread<DERIVED_THREAD>::WorkerThread(const std::string& sName, CQueue& CmdQ,
- long logCategory)
+ category_t logCategory)
: m_sName(sName),
m_bShouldStop(false),
m_CmdQ(CmdQ),
m_LogCategory(logCategory)
{
- ObjectCounter::get()->incRef(&typeid(*this));
}
template<class DERIVED_THREAD>
@@ -86,20 +88,19 @@ WorkerThread<DERIVED_THREAD>::WorkerThread(WorkerThread const& other)
m_sName = other.m_sName;
m_bShouldStop = other.m_bShouldStop;
m_LogCategory = other.m_LogCategory;
- ObjectCounter::get()->incRef(&typeid(*this));
}
template<class DERIVED_THREAD>
WorkerThread<DERIVED_THREAD>::~WorkerThread()
{
- ObjectCounter::get()->decRef(&typeid(*this));
}
template<class DERIVED_THREAD>
void WorkerThread<DERIVED_THREAD>::operator()()
{
try {
- ThreadProfilerPtr pProfiler = ThreadProfiler::get();
+ setAffinityMask(false);
+ ThreadProfiler* pProfiler = ThreadProfiler::get();
pProfiler->setName(m_sName);
pProfiler->setLogCategory(m_LogCategory);
bool bOK;
@@ -112,7 +113,8 @@ void WorkerThread<DERIVED_THREAD>::operator()()
bOK = work();
if (!bOK) {
m_bShouldStop = true;
- } else {
+ }
+ if (!m_bShouldStop) {
processCommands();
}
}
@@ -120,8 +122,7 @@ void WorkerThread<DERIVED_THREAD>::operator()()
pProfiler->dumpStatistics();
pProfiler->kill();
} catch (const Exception& e) {
- AVG_TRACE(Logger::ERROR, "Uncaught exception in thread " << m_sName << ": "
- << e.getStr());
+ AVG_LOG_ERROR("Uncaught exception in thread " << m_sName << ": " << e.getStr());
throw;
}
}
@@ -140,6 +141,12 @@ void WorkerThread<DERIVED_THREAD>::stop()
}
template<class DERIVED_THREAD>
+int WorkerThread<DERIVED_THREAD>::getNumCmdsInQueue() const
+{
+ return m_CmdQ.size();
+}
+
+template<class DERIVED_THREAD>
bool WorkerThread<DERIVED_THREAD>::init()
{
return true;
@@ -148,17 +155,13 @@ bool WorkerThread<DERIVED_THREAD>::init()
template<class DERIVED_THREAD>
void WorkerThread<DERIVED_THREAD>::processCommands()
{
- try {
- CmdPtr pCmd = m_CmdQ.pop(false);
- while (pCmd) {
- pCmd->execute(dynamic_cast<DERIVED_THREAD*>(this));
+ CmdPtr pCmd = m_CmdQ.pop(false);
+ while (pCmd && !m_bShouldStop) {
+ pCmd->execute(dynamic_cast<DERIVED_THREAD*>(this));
+ if (!m_bShouldStop) {
pCmd = m_CmdQ.pop(false);
}
- } catch (const Exception& e) {
- AVG_TRACE(Logger::ERROR, "Uncaught exception in thread "
- << m_sName << ": " << e.getStr());
}
-
}
}
diff --git a/src/base/XMLHelper.cpp b/src/base/XMLHelper.cpp
index 0fa6bdf..6f362e8 100644
--- a/src/base/XMLHelper.cpp
+++ b/src/base/XMLHelper.cpp
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -20,6 +20,8 @@
//
#include "XMLHelper.h"
+#include "Exception.h"
+#include "Logger.h"
#include <libxml/parserInternals.h>
#include <cstring>
@@ -75,4 +77,149 @@ void registerDTDEntityLoader(const string& sID, const string& sDTD)
xmlSetExternalEntityLoader(DTDExternalEntityLoader);
}
+
+XMLParser::XMLParser()
+ : m_SchemaParserCtxt(0),
+ m_Schema(0),
+ m_SchemaValidCtxt(0),
+ m_DTD(0),
+ m_DTDValidCtxt(0),
+ m_Doc(0)
+{
+ xmlPedanticParserDefault(1);
+ xmlSetGenericErrorFunc(this, errorOutputFunc);
+ xmlDoValidityCheckingDefaultValue = 0;
+}
+
+XMLParser::~XMLParser()
+{
+ if (m_Schema) {
+ xmlSchemaFree(m_Schema);
+ }
+ if (m_SchemaParserCtxt) {
+ xmlSchemaFreeParserCtxt(m_SchemaParserCtxt);
+ }
+ if (m_SchemaValidCtxt) {
+ xmlSchemaFreeValidCtxt(m_SchemaValidCtxt);
+ }
+ if (m_DTD) {
+ xmlFreeDtd(m_DTD);
+ }
+ if (m_DTDValidCtxt) {
+ xmlFreeValidCtxt(m_DTDValidCtxt);
+ }
+ if (m_Doc) {
+ xmlFreeDoc(m_Doc);
+ }
+ xmlSetGenericErrorFunc(0, 0);
+}
+
+void XMLParser::setSchema(const string& sSchema, const string& sSchemaName)
+{
+ AVG_ASSERT(!m_SchemaParserCtxt);
+ AVG_ASSERT(!m_Schema);
+ AVG_ASSERT(!m_SchemaValidCtxt);
+ AVG_ASSERT(!m_DTD);
+ AVG_ASSERT(!m_DTDValidCtxt);
+
+ m_SchemaParserCtxt = xmlSchemaNewMemParserCtxt(sSchema.c_str(), sSchema.length());
+ checkError(!m_SchemaParserCtxt, sSchemaName);
+
+ m_Schema = xmlSchemaParse(m_SchemaParserCtxt);
+ checkError(!m_Schema, sSchemaName);
+
+ m_SchemaValidCtxt = xmlSchemaNewValidCtxt(m_Schema);
+ checkError(!m_SchemaValidCtxt, sSchemaName);
+}
+
+void XMLParser::setDTD(const std::string& sDTD, const std::string& sDTDName)
+{
+ AVG_ASSERT(!m_SchemaParserCtxt);
+ AVG_ASSERT(!m_Schema);
+ AVG_ASSERT(!m_SchemaValidCtxt);
+ AVG_ASSERT(!m_DTD);
+ AVG_ASSERT(!m_DTDValidCtxt);
+
+ registerDTDEntityLoader("memory.dtd", sDTD.c_str());
+ string sDTDFName = "memory.dtd";
+ m_DTD = xmlParseDTD(NULL, (const xmlChar*) sDTDFName.c_str());
+ checkError(!m_DTD, sDTDName);
+
+ m_DTDValidCtxt = xmlNewValidCtxt();
+ checkError(!m_DTDValidCtxt, sDTDName);
+ m_DTDValidCtxt->error = xmlParserValidityError;
+ m_DTDValidCtxt->warning = xmlParserValidityWarning;
+}
+
+void XMLParser::parse(const string& sXML, const string& sXMLName)
+{
+ if (m_Doc) {
+ xmlFreeDoc(m_Doc);
+ }
+ m_Doc = xmlParseMemory(sXML.c_str(), int(sXML.length()));
+ checkError(!m_Doc, sXMLName);
+
+ bool bOK = true;
+ if (m_SchemaValidCtxt) {
+ int err = xmlSchemaValidateDoc(m_SchemaValidCtxt, m_Doc);
+ AVG_ASSERT(err != -1);
+ bOK = (err == 0);
+ }
+ if (m_DTD) {
+ int err = xmlValidateDtd(m_DTDValidCtxt, m_Doc, m_DTD);
+ bOK = (err != 0);
+ }
+ if (!bOK) {
+ xmlFreeDoc(m_Doc);
+ m_Doc = 0;
+ checkError(true, sXMLName);
+ }
+}
+
+xmlDocPtr XMLParser::getDoc()
+{
+ AVG_ASSERT(m_Doc);
+ return m_Doc;
+}
+
+xmlNodePtr XMLParser::getRootNode()
+{
+ AVG_ASSERT(m_Doc);
+ return xmlDocGetRootElement(m_Doc);
+}
+
+void XMLParser::errorOutputFunc(void * ctx, const char * msg, ...)
+{
+ va_list args;
+ va_start(args, msg);
+ ((XMLParser*)ctx)->internalErrorHandler(msg, args);
+ va_end(args);
+}
+
+void XMLParser::internalErrorHandler(const char * msg, va_list args)
+{
+ char psz[1024];
+ vsnprintf(psz, 1024, msg, args);
+ m_sError += psz;
+}
+
+void XMLParser::checkError(bool bError, const string& sXMLName)
+{
+ if (bError) {
+ string sError = "Error parsing "+sXMLName+".\n";
+ sError += m_sError;
+ m_sError = "";
+ throw (Exception(AVG_ERR_XML_PARSE, sError));
+ }
+}
+
+void validateXml(const string& sXML, const string& sSchema, const string& sXMLName,
+ const string& sSchemaName)
+{
+ XMLParser parser;
+ parser.setSchema(sSchema, sSchemaName);
+
+ parser.parse(sXML, sXMLName);
+}
+
}
diff --git a/src/base/XMLHelper.h b/src/base/XMLHelper.h
index 5557faf..e258de2 100644
--- a/src/base/XMLHelper.h
+++ b/src/base/XMLHelper.h
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -23,10 +23,10 @@
#define _XMLHelper_H_
#include "../api.h"
-#include "Point.h"
#include <libxml/parser.h>
#include <libxml/xmlwriter.h>
+#include <libxml/xmlschemas.h>
#include <string>
#include <map>
@@ -38,7 +38,41 @@ std::string getXmlChildrenAsString(const xmlDocPtr xmlDoc, const xmlNodePtr& xml
void registerDTDEntityLoader(const std::string& sID, const std::string& sDTD);
+class XMLParser
+{
+public:
+ XMLParser();
+ virtual ~XMLParser();
+
+ void setSchema(const std::string& sSchema, const std::string& sSchemaName);
+ void setDTD(const std::string& sDTD, const std::string& sDTDName);
+ void parse(const std::string& sXML, const std::string& sXMLName);
+
+ xmlDocPtr getDoc();
+ xmlNodePtr getRootNode();
+
+private:
+ static void errorOutputFunc(void * ctx, const char * msg, ...);
+ void internalErrorHandler(const char * msg, va_list args);
+
+ void checkError(bool bError, const std::string& sXMLName);
+
+ xmlSchemaParserCtxtPtr m_SchemaParserCtxt;
+ xmlSchemaPtr m_Schema;
+ xmlSchemaValidCtxtPtr m_SchemaValidCtxt;
+
+ xmlDtdPtr m_DTD;
+ xmlValidCtxtPtr m_DTDValidCtxt;
+
+ xmlDocPtr m_Doc;
+
+ std::string m_sError;
+};
+
+void validateXml(const std::string& sXML, const std::string& sSchema,
+ const std::string& sXMLName, const std::string& sSchemaName);
+
}
-#endif //_XMLHelper_H_
+#endif
diff --git a/src/base/testbase.cpp b/src/base/testbase.cpp
index 656714e..57faf36 100644
--- a/src/base/testbase.cpp
+++ b/src/base/testbase.cpp
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -19,13 +19,13 @@
// Current versions can be found at www.libavg.de
//
+#include "DAG.h"
#include "Queue.h"
#include "Command.h"
#include "WorkerThread.h"
#include "ObjectCounter.h"
-#include "Point.h"
-#include "Matrix3x4.h"
-#include "Triangulate.h"
+#include "triangulate/Triangulate.h"
+#include "GLMHelper.h"
#include "GeomHelper.h"
#include "OSHelper.h"
#include "FileHelper.h"
@@ -35,9 +35,13 @@
#include "BezierCurve.h"
#include "Signal.h"
#include "Backtrace.h"
-
+#include "WideLine.h"
+#include "Rect.h"
+#include "Triangle.h"
#include "TestSuite.h"
#include "TimeSource.h"
+#include "XMLHelper.h"
+#include "Logger.h"
#include <boost/thread/thread.hpp>
@@ -52,6 +56,102 @@ using namespace avg;
using namespace std;
using namespace boost;
+class DAGTest: public Test
+{
+public:
+ DAGTest()
+ : Test("DAGTest", 2)
+ {
+ }
+
+ void runTests()
+ {
+ {
+ DAG dag;
+
+ dag.addNode(1, set<long>());
+ long outgoing2[] = {1};
+ dag.addNode(0, makeOutgoing(1, outgoing2));
+
+ long expected[] = {0, 1};
+ checkResults(&dag, expected);
+ }
+ {
+ DAG dag;
+
+ dag.addNode(2, set<long>());
+ long outgoing2[] = {1};
+ dag.addNode(0, makeOutgoing(1, outgoing2));
+ long outgoing3[] = {2};
+ dag.addNode(1, makeOutgoing(1, outgoing3));
+
+ long expected[] = {0, 1, 2};
+ checkResults(&dag, expected);
+ }
+ {
+ DAG dag;
+
+ long outgoing2[] = {1};
+ dag.addNode(0, makeOutgoing(1, outgoing2));
+ dag.addNode(2, set<long>());
+ long outgoing3[] = {2};
+ dag.addNode(1, makeOutgoing(1, outgoing3));
+
+ long expected[] = {0, 1, 2};
+ checkResults(&dag, expected);
+ }
+ {
+ DAG dag;
+
+ dag.addNode(2, set<long>());
+ long outgoing2[] = {1, 2};
+ dag.addNode(0, makeOutgoing(1, outgoing2));
+ long outgoing3[] = {2};
+ dag.addNode(1, makeOutgoing(1, outgoing3));
+
+ long expected[] = {0, 1, 2};
+ checkResults(&dag, expected);
+ }
+ {
+ DAG dag;
+
+ long outgoing2[] = {1};
+ dag.addNode(0, makeOutgoing(1, outgoing2));
+ long outgoing3[] = {0};
+ dag.addNode(1, makeOutgoing(1, outgoing3));
+
+ bool bExceptionThrown = false;
+ long expected[] = {0, 1, 2};
+ try {
+ checkResults(&dag, expected);
+ } catch (const Exception&) {
+ bExceptionThrown = true;
+ }
+ TEST(bExceptionThrown);
+ }
+ }
+
+private:
+ set<long> makeOutgoing(int n, long ids[])
+ {
+ set<long> v;
+ for (int i=0; i<n; ++i) {
+ v.insert(ids[i]);
+ }
+ return v;
+ }
+
+ void checkResults(DAG* pDAG, long expected[])
+ {
+ vector<long> results;
+ pDAG->sort(results);
+
+ for (unsigned i=0; i<results.size(); ++i) {
+ QUIET_TEST(results[i] == expected[i]);
+ }
+ }
+};
+
class QueueTest: public Test
{
public:
@@ -67,6 +167,8 @@ public:
}
private:
+ typedef Queue<int>::QElementPtr ElemPtr;
+
void runSingleThreadTests()
{
Queue<string> q;
@@ -92,7 +194,7 @@ private:
void runMultiThreadTests()
{
{
- Queue<string> q(10);
+ Queue<int> q(10);
thread pusher(boost::bind(&pushThread, &q, 100));
thread popper(boost::bind(&popThread, &q, 100));
pusher.join();
@@ -100,7 +202,7 @@ private:
TEST(q.empty());
}
{
- Queue<string> q(10);
+ Queue<int> q(10);
thread pusher1(boost::bind(&pushThread, &q, 100));
thread pusher2(boost::bind(&pushThread, &q, 100));
thread popper(boost::bind(&popThread, &q, 200));
@@ -109,21 +211,25 @@ private:
popper.join();
TEST(q.empty());
}
+ {
+ Queue<int> q(10);
+ thread pusher(boost::bind(&pushClearThread, &q, 100));
+ thread popper(boost::bind(&popClearThread, &q));
+ pusher.join();
+ popper.join();
+ TEST(q.empty());
+ }
}
- static void pushThread(Queue<string>* pq, int numPushes)
+ static void pushThread(Queue<int>* pq, int numPushes)
{
- typedef Queue<string>::QElementPtr ElemPtr;
for (int i=0; i<numPushes; ++i) {
- stringstream ss;
- ss << i;
- string s = ss.str();
- pq->push(ElemPtr(new string(s)));
+ pq->push(ElemPtr(new int(i)));
msleep(1);
}
}
- static void popThread(Queue<string>* pq, int numPops)
+ static void popThread(Queue<int>* pq, int numPops)
{
for (int i=0; i<numPops; ++i) {
pq->peek();
@@ -131,6 +237,27 @@ private:
msleep(3);
}
}
+
+ static void pushClearThread(Queue<int>* pq, int numPushes)
+ {
+ typedef Queue<int>::QElementPtr ElemPtr;
+ for (int i=0; i<numPushes; ++i) {
+ pq->push(ElemPtr(new int(i)));
+ if (i%7 == 0) {
+ pq->clear();
+ }
+ msleep(1);
+ }
+ pq->push(ElemPtr(new int(-1)));
+ }
+
+ static void popClearThread(Queue<int>* pq)
+ {
+ ElemPtr pElem;
+ do {
+ pElem = pq->pop();
+ } while (*pElem != -1);
+ }
};
class TestWorkerThread: public WorkerThread<TestWorkerThread>
@@ -248,103 +375,79 @@ public:
#pragma warning(push)
#pragma warning(disable:4723)
#endif
-class PointTest: public Test
+class GeomTest: public Test
{
public:
- PointTest()
- : Test("PointTest", 2)
+ GeomTest()
+ : Test("GeomTest", 2)
{
}
void runTests()
{
- double one = 1;
- double zero = 0;
-
- TEST(isinf(-one/zero) != 0);
- TEST(isinf(one/zero) != 0);
- TEST(isinf(one) == 0);
- TEST(isnan(sqrt(-one)) != 0);
- TEST(isnan(sqrt(one+one)) == 0);
-
// TODO: Move to a separate math test once we're done here.
TEST(almostEqual(invSqrt(1), 1));
TEST(almostEqual(invSqrt(4), 0.5));
- // TODO: The point tests aren't complete!
- DPoint pt1(0,0);
- DPoint pt2(3,4);
- TEST(calcDist(pt1, pt2)-5 < 0.0001);
- TEST(!almostEqual(pt1, pt2));
- TEST(almostEqual(pt1, pt1));
- std::vector<double> v;
- v.push_back(3);
- v.push_back(4);
- DPoint pt3(v);
- TEST(almostEqual(pt2, pt3));
- TEST(almostEqual(pt3.getNorm(), 5));
- DPoint pt4 = pt3.getNormalized();
- TEST(almostEqual(pt4.getNorm(), 1, 0.0001));
{
- DLineSegment l1(DPoint(0,0), DPoint(2,2));
- DLineSegment l2(DPoint(2,0), DPoint(0,2));
+ LineSegment l1(glm::vec2(0,0), glm::vec2(2,2));
+ LineSegment l2(glm::vec2(2,0), glm::vec2(0,2));
TEST(lineSegmentsIntersect(l1, l2));
TEST(lineSegmentsIntersect(l2, l1));
}
{
- DLineSegment l1(DPoint(0,0), DPoint(0,2));
- DLineSegment l2(DPoint(2,0), DPoint(2,2));
+ LineSegment l1(glm::vec2(0,0), glm::vec2(0,2));
+ LineSegment l2(glm::vec2(2,0), glm::vec2(2,2));
TEST(!lineSegmentsIntersect(l1, l2));
}
{
- DLineSegment l1(DPoint(0,0), DPoint(2,0));
- DLineSegment l2(DPoint(0,2), DPoint(2,2));
+ LineSegment l1(glm::vec2(0,0), glm::vec2(2,0));
+ LineSegment l2(glm::vec2(0,2), glm::vec2(2,2));
TEST(!lineSegmentsIntersect(l1, l2));
}
{
- DLineSegment l1(DPoint(0,0), DPoint(2,0));
- TEST(l1.isPointOver(DPoint(1,23)));
- TEST(l1.isPointOver(DPoint(1.9,-5)));
- TEST(!l1.isPointOver(DPoint(-1,1)));
- TEST(!l1.isPointOver(DPoint(3,-1)));
+ LineSegment l1(glm::vec2(0,0), glm::vec2(2,0));
+ TEST(l1.isPointOver(glm::vec2(1,23)));
+ TEST(l1.isPointOver(glm::vec2(1.9,-5)));
+ TEST(!l1.isPointOver(glm::vec2(-1,1)));
+ TEST(!l1.isPointOver(glm::vec2(3,-1)));
}
{
- DPoint pt0(DPoint(1,1));
- DPoint pt1(DPoint(1,3));
- DPoint pt2(DPoint(1,-2));
- vector<DPoint> poly;
- poly.push_back(DPoint(0,0));
- poly.push_back(DPoint(2,0));
- poly.push_back(DPoint(2,2));
- poly.push_back(DPoint(0,2));
+ glm::vec2 pt0(glm::vec2(1,1));
+ glm::vec2 pt1(glm::vec2(1,3));
+ glm::vec2 pt2(glm::vec2(1,-2));
+ vector<glm::vec2> poly;
+ poly.push_back(glm::vec2(0,0));
+ poly.push_back(glm::vec2(2,0));
+ poly.push_back(glm::vec2(2,2));
+ poly.push_back(glm::vec2(0,2));
TEST(pointInPolygon(pt0, poly));
TEST(!pointInPolygon(pt1, poly));
TEST(!pointInPolygon(pt2, poly));
- poly.push_back(DPoint(2,1));
+ poly.push_back(glm::vec2(2,1));
TEST(!pointInPolygon(pt0, poly));
}
{
- DPoint p1(DPoint(0,0));
- DPoint v1(DPoint(1,1));
- DPoint p2(DPoint(2,1));
- DPoint v2(DPoint(1,0));
- TEST(getLineLineIntersection(p1, v1, p2, v2) == DPoint(1,1));
- }
- TEST(almostEqual(DPoint(10,0).getRotatedPivot(M_PI, DPoint(15,5)), DPoint(20,10)));
- TEST(almostEqual(DPoint(10,0).getRotatedPivot(M_PI*0.5, DPoint(15,5)),
- DPoint(20,0)));
- TEST(almostEqual(DPoint(10,0).getRotatedPivot(M_PI*1.5, DPoint(15,5)),
- DPoint(10,10)));
- TEST(almostEqual(DPoint(10,0).getRotatedPivot(M_PI*2, DPoint(15,5)),
- DPoint(10,0)));
- TEST(almostEqual(DPoint(23,0).getRotatedPivot(M_PI*0.5), DPoint(0,23)));
-
- TEST(almostEqual(DPoint(10,0), DPoint::fromPolar(0, 10)));
- TEST(almostEqual(DPoint(0,10), DPoint::fromPolar(M_PI*0.5, 10)));
- TEST(almostEqual(DPoint(0,-1), DPoint::fromPolar(M_PI*1.5, 1)));
- TEST(almostEqual(vecAngle(DPoint(0,1),DPoint(1,0)), M_PI*0.5));
- TEST(almostEqual(vecAngle(DPoint(0,-1),DPoint(1,0)), M_PI*1.5));
- TEST(almostEqual(vecAngle(DPoint(0,2),DPoint(1,0)), M_PI*0.5));
+ glm::vec2 p1(glm::vec2(0,0));
+ glm::vec2 v1(glm::vec2(1,1));
+ glm::vec2 p2(glm::vec2(2,1));
+ glm::vec2 v2(glm::vec2(1,0));
+ TEST(getLineLineIntersection(p1, v1, p2, v2) == glm::vec2(1,1));
+ }
+ TEST(almostEqual(getRotatedPivot(glm::vec2(10,0), M_PI, glm::vec2(15,5)),
+ glm::vec2(20,10)));
+ TEST(almostEqual(getRotatedPivot(glm::vec2(10,0), M_PI*0.5, glm::vec2(15,5)),
+ glm::vec2(20,0)));
+ TEST(almostEqual(getRotatedPivot(glm::vec2(10,0), M_PI*1.5, glm::vec2(15,5)),
+ glm::vec2(10,10)));
+ TEST(almostEqual(getRotatedPivot(glm::vec2(10,0), M_PI*2, glm::vec2(15,5)),
+ glm::vec2(10,0)));
+ TEST(almostEqual(getRotatedPivot(glm::vec2(23,0), M_PI*0.5), glm::vec2(0,23)));
+
+ {
+ // TODO: More tests
+ FRect(0,0,10,10);
+ }
}
};
#ifdef _MSC_VER
@@ -353,32 +456,6 @@ public:
#endif
-class Matrix3x4Test: public Test
-{
-public:
- Matrix3x4Test()
- : Test("Matrix3x4Test", 2)
- {
- }
-
- void runTests()
- {
- Matrix3x4 mat1;
- Matrix3x4 mat2;
- mat1 *= mat2;
- TEST(almostEqual(mat1, Matrix3x4()));
-
- mat2 = Matrix3x4::createTranslate(0,0,0);
- mat1 *= mat2;
- TEST(almostEqual(mat1, Matrix3x4()));
-
- mat2 = Matrix3x4::createScale(1,1,1);
- mat1 *= mat2;
- TEST(almostEqual(mat1, Matrix3x4()));
- }
-};
-
-
class TriangleTest: public Test
{
public:
@@ -389,31 +466,30 @@ public:
void runTests()
{
- Triangle tri(DPoint(0,0), DPoint(4,4), DPoint(4,8));
- TEST(tri.isInside(DPoint(3,4)));
- TEST(!tri.isInside(DPoint(1,4)));
- TEST(!tri.isInside(DPoint(2,1)));
- TEST(!tri.isInside(DPoint(-2,5)));
- TEST(!tri.isInside(DPoint(5,5)));
- tri = Triangle(DPoint(0,0), DPoint(4,8), DPoint(4,4));
- TEST(tri.isInside(DPoint(3,4)));
-
- DPoint polyArray[] = {DPoint(0,0), DPoint(8,2), DPoint(9,0), DPoint(9,3),
- DPoint(1,1), DPoint(0,3)};
-
- DPointVector poly = vectorFromCArray(6, polyArray);
-
- vector<int> triangulation;
- triangulatePolygon(poly, triangulation);
+ Triangle tri(glm::vec2(0,0), glm::vec2(4,4), glm::vec2(4,8));
+ TEST(tri.isInside(glm::vec2(3,4)));
+ TEST(!tri.isInside(glm::vec2(1,4)));
+ TEST(!tri.isInside(glm::vec2(2,1)));
+ TEST(!tri.isInside(glm::vec2(-2,5)));
+ TEST(!tri.isInside(glm::vec2(5,5)));
+ tri = Triangle(glm::vec2(0,0), glm::vec2(4,8), glm::vec2(4,4));
+ TEST(tri.isInside(glm::vec2(3,4)));
+
+ glm::vec2 polyArray[] = {glm::vec2(0,0), glm::vec2(8,2), glm::vec2(9,0), glm::vec2(9,3),
+ glm::vec2(1,1), glm::vec2(0,3)};
+
+ Vec2Vector poly = vectorFromCArray(6, polyArray);
+ vector<unsigned int> triangulation;
+ triangulatePolygon(triangulation, poly);
TEST(triangulation.size() == 4*3);
- int baselineIndexes[] = {1,2,3, 4,5,0, 0,1,3, 3,4,0};
+ unsigned int baselineIndexes[] = {5,0,4, 1,4,0, 4,1,3, 1,2,3};
TEST(triangulation == vectorFromCArray(12, baselineIndexes));
-/*
+/*
for (unsigned int i=0; i<triangulation.size(); i++) {
cerr << i << ":" << triangulation[i] << endl;
}
-*/
+*/
}
};
@@ -445,9 +521,8 @@ public:
void runTests()
{
-#if defined(__APPLE__) || defined(_WIN32)
+ cerr << getAvgLibPath() << endl;
TEST(getAvgLibPath() != "");
-#endif
#ifdef __APPLE__
TEST(getMemoryUsage() != 0);
#endif
@@ -466,7 +541,7 @@ public:
void runTests()
{
TEST(stringToInt("5") == 5);
- TEST(almostEqual(stringToDouble("5.5"), 5.5));
+ TEST(almostEqual(stringToFloat("5.5"), 5.5f));
TEST(stringToBool("False") == false);
bool bExceptionThrown = false;
try {
@@ -477,8 +552,8 @@ public:
}
}
TEST(bExceptionThrown);
- TEST(stringToDPoint(" ( 3.4 , 2.1 ) ") == DPoint(3.4, 2.1));
- vector<double> v;
+ TEST(stringToVec2(" ( 3.4 , 2.1 ) ") == glm::vec2(3.4f, 2.1f));
+ vector<float> v;
fromString("(1,2,3,4,5)", v);
TEST(v.size() == 5 && v[0] == 1 && v[4] == 5);
v.clear();
@@ -499,10 +574,10 @@ public:
void runTests()
{
{
- double xd[] = {0,1,2,3};
- vector<double> x = vectorFromCArray(4, xd);
- double yd[] = {3,2,1,0};
- vector<double> y = vectorFromCArray(4, yd);
+ float xd[] = {0,1,2,3};
+ vector<float> x = vectorFromCArray(4, xd);
+ float yd[] = {3,2,1,0};
+ vector<float> y = vectorFromCArray(4, yd);
CubicSpline spline(x, y);
TEST(almostEqual(spline.interpolate(-1), 4));
TEST(almostEqual(spline.interpolate(0), 3));
@@ -511,19 +586,46 @@ public:
TEST(almostEqual(spline.interpolate(3.5), -0.5));
}
{
- double xd[] = {2,4,6,8};
- vector<double> x = vectorFromCArray(4, xd);
- double yd[] = {0,1,3,6};
- vector<double> y = vectorFromCArray(4, yd);
+ float xd[] = {2,4,6,8};
+ vector<float> x = vectorFromCArray(4, xd);
+ float yd[] = {0,1,3,6};
+ vector<float> y = vectorFromCArray(4, yd);
CubicSpline spline(x, y);
TEST(almostEqual(spline.interpolate(0), -1));
- TEST(almostEqual(spline.interpolate(1), -0.5));
TEST(almostEqual(spline.interpolate(2), 0));
TEST(spline.interpolate(3) < 0.5);
+ TEST(spline.interpolate(3) > 0);
+ TEST(spline.interpolate(7) > 4);
+ TEST(spline.interpolate(7) < 5);
TEST(almostEqual(spline.interpolate(8), 6));
- TEST(almostEqual(spline.interpolate(9), 7.5));
TEST(almostEqual(spline.interpolate(10), 9));
}
+ {
+ float xd[] = {0,1,1};
+ vector<float> x = vectorFromCArray(3, xd);
+ float yd[] = {1,2,1};
+ vector<float> y = vectorFromCArray(3, yd);
+ bool bExceptionThrown = false;
+ try {
+ CubicSpline spline(x, y);
+ } catch (const Exception&) {
+ bExceptionThrown = true;
+ }
+ TEST(bExceptionThrown);
+ }
+/*
+ {
+ float xd[] = {0,1,2};
+ vector<float> x = vectorFromCArray(3, xd);
+ float yd[] = {1,2,1};
+ vector<float> y = vectorFromCArray(3, yd);
+ CubicSpline spline(x, y, true);
+ TEST(almostEqual(spline.interpolate(0), 1));
+ TEST(almostEqual(spline.interpolate(0.5), 1.5));
+ TEST(almostEqual(spline.interpolate(2), 1));
+ TEST(almostEqual(spline.interpolate(3), 2));
+ }
+*/
}
};
@@ -538,12 +640,28 @@ public:
void runTests()
{
- BezierCurve curve(DPoint(0,0), DPoint(1,0), DPoint(1,1), DPoint(0,1));
- TEST(almostEqual(curve.interpolate(0), DPoint(0,0)));
- TEST(almostEqual(curve.getDeriv(0), DPoint(3, 0)));
- TEST(almostEqual(curve.interpolate(1), DPoint(0,1)));
- TEST(almostEqual(curve.getDeriv(1), DPoint(-3, 0)));
- TEST(almostEqual(curve.interpolate(0.5), DPoint(0.75,0.5)));
+ BezierCurve curve(glm::vec2(0,0), glm::vec2(1,0), glm::vec2(1,1), glm::vec2(0,1));
+ TEST(almostEqual(curve.interpolate(0), glm::vec2(0,0)));
+ TEST(almostEqual(curve.getDeriv(0), glm::vec2(3, 0)));
+ TEST(almostEqual(curve.interpolate(1), glm::vec2(0,1)));
+ TEST(almostEqual(curve.getDeriv(1), glm::vec2(-3, 0)));
+ TEST(almostEqual(curve.interpolate(0.5), glm::vec2(0.75,0.5)));
+ }
+};
+
+
+class WideLineTest: public Test
+{
+public:
+ WideLineTest()
+ : Test("WideLineTest", 2)
+ {
+ }
+
+ void runTests()
+ {
+ WideLine line(glm::vec2(0,0), glm::vec2(4,3), 2);
+ TEST(almostEqual(line.getLen(), 5));
}
};
@@ -731,17 +849,151 @@ public:
};
+class PolygonTest: public Test
+{
+public:
+ PolygonTest()
+ : Test("PolygonTest", 2)
+ {
+ }
+
+ void runTests()
+ {
+ glm::vec2 polyArray[] = {glm::vec2(30,0), glm::vec2(40,20), glm::vec2(60,30),
+ glm::vec2(40,40), glm::vec2(30,60), glm::vec2(20,40), glm::vec2(0,30),
+ glm::vec2(20,20)};
+
+ Vec2Vector poly = vectorFromCArray(8, polyArray);
+ vector<unsigned int> triangulation;
+ triangulatePolygon(triangulation, poly);
+
+ TEST(triangulation.size() == 6*3);
+ unsigned int baselineIndexes[] = {6,7,5, 5,7,1, 7,0,1, 5,1,3, 3,1,2, 4,5,3};
+ TEST(triangulation == vectorFromCArray(18, baselineIndexes));
+/*
+ for (unsigned int i=0; i<triangulation.size(); i++) {
+ cerr << i << ":" << triangulation[i] << endl;
+ }/
+*/
+ }
+
+};
+
+
+class XmlParserTest: public Test
+{
+public:
+ XmlParserTest()
+ : Test("XmlParserTest", 2)
+ {
+ }
+
+ void runTests()
+ {
+ string sXmlString = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
+ "<shiporder orderid=\"889923\">"
+ " <orderperson>John Smith</orderperson>"
+ "</shiporder>";
+
+ {
+ string sSchema = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
+ "<xs:schema xmlns:xs=\"http://www.w3.org/2001/XMLSchema\">"
+ "<xs:element name=\"shiporder\">"
+ " <xs:complexType>"
+ " <xs:sequence>"
+ " <xs:element name=\"orderperson\" type=\"xs:string\"/>"
+ " </xs:sequence>"
+ " <xs:attribute name=\"orderid\" type=\"xs:string\" use=\"required\"/>"
+ " </xs:complexType>"
+ "</xs:element>"
+ "</xs:schema>";
+
+ XMLParser parser;
+ parser.setSchema(sSchema, "shiporder.xsd");
+ parser.parse(sXmlString, "shiporder.xml");
+ }
+ {
+ string sDTD =
+ "<!ELEMENT shiporder (orderperson)* >"
+ "<!ATTLIST shiporder"
+ " orderid CDATA #IMPLIED>"
+ "<!ELEMENT orderperson (#PCDATA) >";
+ XMLParser parser;
+ parser.setDTD(sDTD, "shiporder.dtd");
+ parser.parse(sXmlString, "shiporder.xml");
+ }
+ }
+};
+
+
+class StandardLoggerTest: public Test
+{
+public:
+ StandardLoggerTest()
+ : Test("StandardLoggerTest", 2)
+ {
+ }
+
+ void runTests()
+ {
+ std::stringstream buffer;
+ std::streambuf *sbuf = std::cerr.rdbuf();
+ Logger *logger = Logger::get();
+ {
+ std::cerr.rdbuf(buffer.rdbuf());
+ string msg("Test log message");
+ AVG_TRACE(Logger::category::NONE, Logger::severity::WARNING, msg);
+ std::cerr.rdbuf(sbuf);
+ TEST(buffer.str().find(msg) != string::npos);
+ buffer.str(string());
+
+ std::cerr.rdbuf(buffer.rdbuf());
+ AVG_TRACE(Logger::category::NONE, Logger::severity::DEBUG, msg);
+ std::cerr.rdbuf(sbuf);
+ std::cout << buffer.str();
+ TEST(buffer.str().find(msg) == string::npos);
+ buffer.str(string());
+ }
+ {
+ std::cerr.rdbuf(buffer.rdbuf());
+ category_t CUSTOM_CAT = logger->configureCategory("CUSTOM_CAT 1");
+ string msg("CUSTOM_CAT LOG");
+ AVG_TRACE(CUSTOM_CAT, Logger::severity::WARNING, msg);
+ std::cerr.rdbuf(sbuf);
+ TEST(buffer.str().find(msg) != string::npos);
+ buffer.str(string());
+ }
+ {
+ std::cerr.rdbuf(buffer.rdbuf());
+ category_t CUSTOM_CAT = logger->configureCategory("CUSTOM_CAT 1",
+ Logger::severity::CRITICAL);
+ string msg_info("CUSTOM_CAT LOG INFO");
+ AVG_TRACE(CUSTOM_CAT, Logger::severity::WARNING, msg_info);
+ std::cerr.rdbuf(sbuf);
+ TEST(buffer.str().find(msg_info) == string::npos);
+ buffer.str(string());
+
+ std::cerr.rdbuf(buffer.rdbuf());
+ string msg_critical("CUSTOM_CAT LOG CRITICAL");
+ AVG_TRACE(CUSTOM_CAT, Logger::severity::CRITICAL, msg_critical);
+ std::cerr.rdbuf(sbuf);
+ TEST(buffer.str().find(msg_critical) != string::npos);
+ buffer.str(string());
+ }
+ }
+};
+
class BaseTestSuite: public TestSuite
{
public:
BaseTestSuite()
: TestSuite("BaseTestSuite")
{
+ addTest(TestPtr(new DAGTest));
addTest(TestPtr(new QueueTest));
addTest(TestPtr(new WorkerThreadTest));
addTest(TestPtr(new ObjectCounterTest));
- addTest(TestPtr(new PointTest));
- addTest(TestPtr(new Matrix3x4Test));
+ addTest(TestPtr(new GeomTest));
addTest(TestPtr(new TriangleTest));
addTest(TestPtr(new FileTest));
addTest(TestPtr(new OSTest));
@@ -750,6 +1002,9 @@ public:
addTest(TestPtr(new BezierCurveTest));
addTest(TestPtr(new SignalTest));
addTest(TestPtr(new BacktraceTest));
+ addTest(TestPtr(new PolygonTest));
+ addTest(TestPtr(new XmlParserTest));
+ addTest(TestPtr(new StandardLoggerTest));
}
};
diff --git a/src/base/triangulate/AdvancingFront.cpp b/src/base/triangulate/AdvancingFront.cpp
new file mode 100644
index 0000000..d14f1d3
--- /dev/null
+++ b/src/base/triangulate/AdvancingFront.cpp
@@ -0,0 +1,104 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+//
+// Based on Poly2Tri algorithm.
+// Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors
+// http://code.google.com/p/poly2tri/
+//
+
+#include "AdvancingFront.h"
+
+namespace avg {
+
+AdvancingFront::AdvancingFront(Node& head, Node& tail)
+{
+ m_Head = &head;
+ m_Tail = &tail;
+ m_SearchNode = &head;
+}
+
+Node* AdvancingFront::locateNode(const double& x)
+{
+ Node* node = m_SearchNode;
+
+ if (x < node->m_Value) {
+ while ((node = node->m_Prev) != NULL) {
+ if (x >= node->m_Value) {
+ m_SearchNode = node;
+ return node;
+ }
+ }
+ } else {
+ while ((node = node->m_Next) != NULL) {
+ if (x < node->m_Value) {
+ m_SearchNode = node->m_Prev;
+ return node->m_Prev;
+ }
+ }
+ }
+ return NULL;
+}
+
+Node* AdvancingFront::findSearchNode(const double& x)
+{
+ // TO DO: implement BST index
+ return m_SearchNode;
+}
+
+Node* AdvancingFront::locatePoint(const Point* point)
+{
+ const double px = point->m_X;
+ Node* node = findSearchNode(px);
+ const double nx = node->m_Point->m_X;
+
+ if (px == nx) {
+ if (point != node->m_Point) {
+ // We might have two nodes with same x value for a short time
+ if (point == node->m_Prev->m_Point) {
+ node = node->m_Prev;
+ } else if (point == node->m_Next->m_Point) {
+ node = node->m_Next;
+ } else {
+ assert(0);
+ }
+ }
+ } else if (px < nx) {
+ while ((node = node->m_Prev) != NULL) {
+ if (point == node->m_Point) {
+ break;
+ }
+ }
+ } else {
+ while ((node = node->m_Next) != NULL) {
+ if (point == node->m_Point)
+ break;
+ }
+ }
+ if (node)
+ m_SearchNode = node;
+ return node;
+}
+
+AdvancingFront::~AdvancingFront() {}
+
+}
+
diff --git a/src/base/triangulate/AdvancingFront.h b/src/base/triangulate/AdvancingFront.h
new file mode 100644
index 0000000..3bb0d5b
--- /dev/null
+++ b/src/base/triangulate/AdvancingFront.h
@@ -0,0 +1,118 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+//
+// Based on Poly2Tri algorithm.
+// Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors
+// http://code.google.com/p/poly2tri/
+//
+
+#ifndef ADVANCED_FRONT_H
+#define ADVANCED_FRONT_H
+
+#include "Shapes.h"
+
+namespace avg {
+
+struct Node;
+
+struct Node
+{
+ Point* m_Point;
+ TriangulationTriangle* m_Triangle;
+
+ Node* m_Next;
+ Node* m_Prev;
+
+ double m_Value;
+
+ Node() : m_Point(NULL), m_Triangle(NULL), m_Next(NULL), m_Prev(NULL), m_Value(0)
+ {}
+
+ Node(Point& p) : m_Point(&p), m_Triangle(NULL), m_Next(NULL), m_Prev(NULL), m_Value(p.m_X)
+ {}
+
+ Node(Point& p, TriangulationTriangle& t) : m_Point(&p), m_Triangle(&t), m_Next(NULL), m_Prev(NULL), m_Value(p.m_X)
+ {}
+
+};
+
+
+class AdvancingFront
+{
+
+public:
+
+AdvancingFront(Node& head, Node& tail);
+
+~AdvancingFront();
+
+Node* head();
+void setHead(Node* node);
+Node* tail();
+void setTail(Node* node);
+Node* search();
+void setSearch(Node* node);
+
+/// Locate insertion point along advancing front
+Node* locateNode(const double& x);
+
+Node* locatePoint(const Point* point);
+
+private:
+
+Node* m_Head, *m_Tail, *m_SearchNode;
+
+Node* findSearchNode(const double& x);
+};
+
+
+inline Node* AdvancingFront::head()
+{
+ return m_Head;
+}
+inline void AdvancingFront::setHead(Node* node)
+{
+ m_Head = node;
+}
+
+inline Node* AdvancingFront::tail()
+{
+ return m_Tail;
+}
+inline void AdvancingFront::setTail(Node* node)
+{
+ m_Tail = node;
+}
+
+inline Node* AdvancingFront::search()
+{
+ return m_SearchNode;
+}
+
+inline void AdvancingFront::setSearch(Node* node)
+{
+ m_SearchNode = node;
+}
+
+}
+
+#endif
diff --git a/src/base/triangulate/Makefile.am b/src/base/triangulate/Makefile.am
new file mode 100644
index 0000000..9381e58
--- /dev/null
+++ b/src/base/triangulate/Makefile.am
@@ -0,0 +1,8 @@
+AM_CPPFLAGS = -I.. @XML2_CFLAGS@ @PTHREAD_CFLAGS@
+ALL_H = Triangulate.h Shapes.h Utils.h \
+ AdvancingFront.h Sweep.h SweepContext.h
+
+noinst_LTLIBRARIES = libtriangulate.la
+libtriangulate_la_SOURCES = Triangulate.cpp Shapes.cpp \
+ AdvancingFront.cpp Sweep.cpp SweepContext.cpp \
+ $(ALL_H)
diff --git a/src/base/triangulate/Makefile.in b/src/base/triangulate/Makefile.in
new file mode 100644
index 0000000..4b8384a
--- /dev/null
+++ b/src/base/triangulate/Makefile.in
@@ -0,0 +1,593 @@
+# Makefile.in generated by automake 1.11.3 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software
+# Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+target_triplet = @target@
+subdir = src/base/triangulate
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/ac_cxx_namespaces.m4 \
+ $(top_srcdir)/m4/ac_path_generic.m4 \
+ $(top_srcdir)/m4/ax_boost_thread.m4 \
+ $(top_srcdir)/m4/ax_check_gl.m4 \
+ $(top_srcdir)/m4/ax_python_devel.m4 \
+ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
+ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
+ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/pkg.m4 \
+ $(top_srcdir)/m4/avg_version.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = $(top_builddir)/src/avgconfig.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+LTLIBRARIES = $(noinst_LTLIBRARIES)
+libtriangulate_la_LIBADD =
+am__objects_1 =
+am_libtriangulate_la_OBJECTS = Triangulate.lo Shapes.lo \
+ AdvancingFront.lo Sweep.lo SweepContext.lo $(am__objects_1)
+libtriangulate_la_OBJECTS = $(am_libtriangulate_la_OBJECTS)
+AM_V_lt = $(am__v_lt_@AM_V@)
+am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
+am__v_lt_0 = --silent
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/src
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
+LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CXXFLAGS) $(CXXFLAGS)
+AM_V_CXX = $(am__v_CXX_@AM_V@)
+am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@)
+am__v_CXX_0 = @echo " CXX " $@;
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+CXXLD = $(CXX)
+CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \
+ $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CXXLD = $(am__v_CXXLD_@AM_V@)
+am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@)
+am__v_CXXLD_0 = @echo " CXXLD " $@;
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_@AM_V@)
+am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
+am__v_CC_0 = @echo " CC " $@;
+CCLD = $(CC)
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CCLD = $(am__v_CCLD_@AM_V@)
+am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
+am__v_CCLD_0 = @echo " CCLD " $@;
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
+SOURCES = $(libtriangulate_la_SOURCES)
+DIST_SOURCES = $(libtriangulate_la_SOURCES)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BOOST_PYTHON_LIBS = @BOOST_PYTHON_LIBS@
+BOOST_THREAD_LIBS = @BOOST_THREAD_LIBS@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DC1394_2_CFLAGS = @DC1394_2_CFLAGS@
+DC1394_2_LIBS = @DC1394_2_LIBS@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FFMPEG_CFLAGS = @FFMPEG_CFLAGS@
+FFMPEG_LIBS = @FFMPEG_LIBS@
+FGREP = @FGREP@
+FONTCONFIG_CFLAGS = @FONTCONFIG_CFLAGS@
+FONTCONFIG_LIBS = @FONTCONFIG_LIBS@
+FREETYPE_CFLAGS = @FREETYPE_CFLAGS@
+FREETYPE_CONFIG = @FREETYPE_CONFIG@
+FREETYPE_LIBS = @FREETYPE_LIBS@
+GDK_PIXBUF_CFLAGS = @GDK_PIXBUF_CFLAGS@
+GDK_PIXBUF_LIBS = @GDK_PIXBUF_LIBS@
+GLU_CFLAGS = @GLU_CFLAGS@
+GLU_LIBS = @GLU_LIBS@
+GL_CFLAGS = @GL_CFLAGS@
+GL_LIBS = @GL_LIBS@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBFFMPEG = @LIBFFMPEG@
+LIBOBJS = @LIBOBJS@
+LIBRSVG_CFLAGS = @LIBRSVG_CFLAGS@
+LIBRSVG_LIBS = @LIBRSVG_LIBS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIBVIDEO_LDADD = @LIBVIDEO_LDADD@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+MTDEV_CFLAGS = @MTDEV_CFLAGS@
+MTDEV_LIBS = @MTDEV_LIBS@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJC = @OBJC@
+OBJCDEPMODE = @OBJCDEPMODE@
+OBJCFLAGS = @OBJCFLAGS@
+OBJCLDFLAGS = @OBJCLDFLAGS@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PANGOFT2_CFLAGS = @PANGOFT2_CFLAGS@
+PANGOFT2_LIBS = @PANGOFT2_LIBS@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+PREFIX = @PREFIX@
+PTHREAD_CC = @PTHREAD_CC@
+PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
+PTHREAD_LIBS = @PTHREAD_LIBS@
+PYTHON = @PYTHON@
+PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@
+PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
+PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@
+PYTHON_LDFLAGS = @PYTHON_LDFLAGS@
+PYTHON_PLATFORM = @PYTHON_PLATFORM@
+PYTHON_PREFIX = @PYTHON_PREFIX@
+PYTHON_SITE_PKG = @PYTHON_SITE_PKG@
+PYTHON_VERSION = @PYTHON_VERSION@
+RANLIB = @RANLIB@
+SDL_CFLAGS = @SDL_CFLAGS@
+SDL_CONFIG = @SDL_CONFIG@
+SDL_LIBS = @SDL_LIBS@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+VERSION = @VERSION@
+XI2_1_CFLAGS = @XI2_1_CFLAGS@
+XI2_1_LIBS = @XI2_1_LIBS@
+XI2_2_CFLAGS = @XI2_2_CFLAGS@
+XI2_2_LIBS = @XI2_2_LIBS@
+XMKMF = @XMKMF@
+XML2_CFLAGS = @XML2_CFLAGS@
+XML2_CONFIG = @XML2_CONFIG@
+XML2_LIBS = @XML2_LIBS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+acx_pthread_config = @acx_pthread_config@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+pkgpyexecdir = @pkgpyexecdir@
+pkgpythondir = @pkgpythondir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+pyexecdir = @pyexecdir@
+pythondir = @pythondir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target = @target@
+target_alias = @target_alias@
+target_cpu = @target_cpu@
+target_os = @target_os@
+target_vendor = @target_vendor@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+AM_CPPFLAGS = -I.. @XML2_CFLAGS@ @PTHREAD_CFLAGS@
+ALL_H = Triangulate.h Shapes.h Utils.h \
+ AdvancingFront.h Sweep.h SweepContext.h
+
+noinst_LTLIBRARIES = libtriangulate.la
+libtriangulate_la_SOURCES = Triangulate.cpp Shapes.cpp \
+ AdvancingFront.cpp Sweep.cpp SweepContext.cpp \
+ $(ALL_H)
+
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .cpp .lo .o .obj
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/base/triangulate/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --foreign src/base/triangulate/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+clean-noinstLTLIBRARIES:
+ -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
+ @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \
+ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
+ test "$$dir" != "$$p" || dir=.; \
+ echo "rm -f \"$${dir}/so_locations\""; \
+ rm -f "$${dir}/so_locations"; \
+ done
+libtriangulate.la: $(libtriangulate_la_OBJECTS) $(libtriangulate_la_DEPENDENCIES) $(EXTRA_libtriangulate_la_DEPENDENCIES)
+ $(AM_V_CXXLD)$(CXXLINK) $(libtriangulate_la_OBJECTS) $(libtriangulate_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/AdvancingFront.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Shapes.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Sweep.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SweepContext.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Triangulate.Plo@am__quote@
+
+.cpp.o:
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $<
+
+.cpp.obj:
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.cpp.lo:
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LTCXXCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ set x; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: CTAGS
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(LTLIBRARIES)
+installdirs:
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \
+ mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+ clean-libtool clean-noinstLTLIBRARIES ctags distclean \
+ distclean-compile distclean-generic distclean-libtool \
+ distclean-tags distdir dvi dvi-am html html-am info info-am \
+ install install-am install-data install-data-am install-dvi \
+ install-dvi-am install-exec install-exec-am install-html \
+ install-html-am install-info install-info-am install-man \
+ install-pdf install-pdf-am install-ps install-ps-am \
+ install-strip installcheck installcheck-am installdirs \
+ maintainer-clean maintainer-clean-generic mostlyclean \
+ mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
+ pdf pdf-am ps ps-am tags uninstall uninstall-am
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/src/base/triangulate/Shapes.cpp b/src/base/triangulate/Shapes.cpp
new file mode 100644
index 0000000..08e2e13
--- /dev/null
+++ b/src/base/triangulate/Shapes.cpp
@@ -0,0 +1,353 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+//
+// Based on Poly2Tri algorithm.
+// Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors
+// http://code.google.com/p/poly2tri/
+//
+
+#include "Shapes.h"
+#include <iostream>
+
+namespace avg {
+
+TriangulationTriangle::TriangulationTriangle(Point& a, Point& b, Point& c)
+{
+ m_Points[0] = &a;
+ m_Points[1] = &b;
+ m_Points[2] = &c;
+ m_Neighbors[0] = NULL;
+ m_Neighbors[1] = NULL;
+ m_Neighbors[2] = NULL;
+ m_ConstrainedEdge[0] = m_ConstrainedEdge[1] = m_ConstrainedEdge[2] = false;
+ m_DelaunayEdge[0] = m_DelaunayEdge[1] = m_DelaunayEdge[2] = false;
+ m_Interior = false;
+}
+
+// Update neighbor pointers
+void TriangulationTriangle::markNeighbor(Point* p1, Point* p2,
+ TriangulationTriangle* t)
+{
+ if ((p1 == m_Points[2] && p2 == m_Points[1])
+ || (p1 == m_Points[1] && p2 == m_Points[2])) {
+ m_Neighbors[0] = t;
+ } else if ((p1 == m_Points[0] && p2 == m_Points[2])
+ || (p1 == m_Points[2] && p2 == m_Points[0])) {
+ m_Neighbors[1] = t;
+ } else if ((p1 == m_Points[0] && p2 == m_Points[1])
+ || (p1 == m_Points[1] && p2 == m_Points[0])) {
+ m_Neighbors[2] = t;
+ } else {
+ assert(0);
+ }
+
+}
+
+// Exhaustive search to update neighbor pointers
+void TriangulationTriangle::markNeighbor(TriangulationTriangle& t)
+{
+ if (t.contains(m_Points[1], m_Points[2])) {
+ m_Neighbors[0] = &t;
+ t.markNeighbor(m_Points[1], m_Points[2], this);
+ } else if (t.contains(m_Points[0], m_Points[2])) {
+ m_Neighbors[1] = &t;
+ t.markNeighbor(m_Points[0], m_Points[2], this);
+ } else if (t.contains(m_Points[0], m_Points[1])) {
+ m_Neighbors[2] = &t;
+ t.markNeighbor(m_Points[0], m_Points[1], this);
+ }
+}
+
+void TriangulationTriangle::clear()
+{
+ TriangulationTriangle *t;
+ for (int i = 0; i < 3; i++) {
+ t = m_Neighbors[i];
+ if (t != NULL) {
+ t->clearNeighbor(this);
+ }
+ }
+ clearNeighbors();
+ m_Points[0] = m_Points[1] = m_Points[2] = NULL;
+}
+
+void TriangulationTriangle::clearNeighbor(TriangulationTriangle *triangle)
+{
+ if (m_Neighbors[0] == triangle) {
+ m_Neighbors[0] = NULL;
+ } else if (m_Neighbors[1] == triangle) {
+ m_Neighbors[1] = NULL;
+ } else {
+ m_Neighbors[2] = NULL;
+ }
+}
+
+void TriangulationTriangle::clearNeighbors()
+{
+ m_Neighbors[0] = NULL;
+ m_Neighbors[1] = NULL;
+ m_Neighbors[2] = NULL;
+}
+
+void TriangulationTriangle::clearDelunayEdges()
+{
+ m_DelaunayEdge[0] = m_DelaunayEdge[1] = m_DelaunayEdge[2] = false;
+}
+
+Point* TriangulationTriangle::oppositePoint(TriangulationTriangle& t,
+ Point& p) {
+ Point *cw = t.pointCW(p);
+ return pointCW(*cw);
+}
+
+// Legalized triangle by rotating clockwise around point(0)
+void TriangulationTriangle::legalize(Point& point)
+{
+ m_Points[1] = m_Points[0];
+ m_Points[0] = m_Points[2];
+ m_Points[2] = &point;
+}
+
+// Legalize triagnle by rotating clockwise around oPoint
+void TriangulationTriangle::legalize(Point& opoint, Point& npoint)
+{
+ if (&opoint == m_Points[0]) {
+ m_Points[1] = m_Points[0];
+ m_Points[0] = m_Points[2];
+ m_Points[2] = &npoint;
+ } else if (&opoint == m_Points[1]) {
+ m_Points[2] = m_Points[1];
+ m_Points[1] = m_Points[0];
+ m_Points[0] = &npoint;
+ } else if (&opoint == m_Points[2]) {
+ m_Points[0] = m_Points[2];
+ m_Points[2] = m_Points[1];
+ m_Points[1] = &npoint;
+ } else {
+ assert(0);
+ }
+}
+
+unsigned int TriangulationTriangle::index(const Point* p)
+{
+ if (p == m_Points[0]) {
+ return 0;
+ } else if (p == m_Points[1]) {
+ return 1;
+ } else if (p == m_Points[2]) {
+ return 2;
+ }
+ assert(0);
+ return 0;
+}
+
+unsigned int TriangulationTriangle::edgeIndex(const Point* p1, const Point* p2)
+{
+ if (m_Points[0] == p1) {
+ if (m_Points[1] == p2) {
+ return 2;
+ } else if (m_Points[2] == p2) {
+ return 1;
+ }
+ } else if (m_Points[1] == p1) {
+ if (m_Points[2] == p2) {
+ return 0;
+ } else if (m_Points[0] == p2) {
+ return 2;
+ }
+ } else if (m_Points[2] == p1) {
+ if (m_Points[0] == p2) {
+ return 1;
+ } else if (m_Points[1] == p2) {
+ return 0;
+ }
+ }
+ return -1;
+}
+
+void TriangulationTriangle::markConstrainedEdge(const int index)
+{
+ m_ConstrainedEdge[index] = true;
+}
+
+void TriangulationTriangle::markConstrainedEdge(Edge& edge)
+{
+ markConstrainedEdge(edge.m_P, edge.m_Q);
+}
+
+void TriangulationTriangle::markConstrainedEdge(Point* p, Point* q)
+{
+ if ((q == m_Points[0] && p == m_Points[1])
+ || (q == m_Points[1] && p == m_Points[0])) {
+ m_ConstrainedEdge[2] = true;
+ } else if ((q == m_Points[0] && p == m_Points[2])
+ || (q == m_Points[2] && p == m_Points[0])) {
+ m_ConstrainedEdge[1] = true;
+ } else if ((q == m_Points[1] && p == m_Points[2])
+ || (q == m_Points[2] && p == m_Points[1])) {
+ m_ConstrainedEdge[0] = true;
+ }
+}
+
+// The point counter-clockwise to given point
+Point* TriangulationTriangle::pointCW(Point& point)
+{
+ if (&point == m_Points[0]) {
+ return m_Points[2];
+ } else if (&point == m_Points[1]) {
+ return m_Points[0];
+ } else if (&point == m_Points[2]) {
+ return m_Points[1];
+ }
+ assert(0);
+ return 0; // Silence compiler warning
+}
+
+Point* TriangulationTriangle::pointCCW(Point& point)
+{
+ if (&point == m_Points[0]) {
+ return m_Points[1];
+ } else if (&point == m_Points[1]) {
+ return m_Points[2];
+ } else if (&point == m_Points[2]) {
+ return m_Points[0];
+ }
+ assert(0);
+ return 0; // Silence compiler warning
+}
+
+TriangulationTriangle* TriangulationTriangle::neighborCW(Point& point)
+{
+ if (&point == m_Points[0]) {
+ return m_Neighbors[1];
+ } else if (&point == m_Points[1]) {
+ return m_Neighbors[2];
+ }
+ return m_Neighbors[0];
+}
+
+TriangulationTriangle* TriangulationTriangle::neighborCCW(Point& point)
+{
+ if (&point == m_Points[0]) {
+ return m_Neighbors[2];
+ } else if (&point == m_Points[1]) {
+ return m_Neighbors[0];
+ }
+ return m_Neighbors[1];
+}
+
+bool TriangulationTriangle::getConstrainedEdgeCCW(Point& p)
+{
+ if (&p == m_Points[0]) {
+ return m_ConstrainedEdge[2];
+ } else if (&p == m_Points[1]) {
+ return m_ConstrainedEdge[0];
+ }
+ return m_ConstrainedEdge[1];
+}
+
+bool TriangulationTriangle::getConstrainedEdgeCW(Point& p)
+{
+ if (&p == m_Points[0]) {
+ return m_ConstrainedEdge[1];
+ } else if (&p == m_Points[1]) {
+ return m_ConstrainedEdge[2];
+ }
+ return m_ConstrainedEdge[0];
+}
+
+void TriangulationTriangle::setConstrainedEdgeCCW(Point& p, bool ce)
+{
+ if (&p == m_Points[0]) {
+ m_ConstrainedEdge[2] = ce;
+ } else if (&p == m_Points[1]) {
+ m_ConstrainedEdge[0] = ce;
+ } else {
+ m_ConstrainedEdge[1] = ce;
+ }
+}
+
+void TriangulationTriangle::setConstrainedEdgeCW(Point& p, bool ce)
+{
+ if (&p == m_Points[0]) {
+ m_ConstrainedEdge[1] = ce;
+ } else if (&p == m_Points[1]) {
+ m_ConstrainedEdge[2] = ce;
+ } else {
+ m_ConstrainedEdge[0] = ce;
+ }
+}
+
+bool TriangulationTriangle::getDelunayEdgeCCW(Point& p)
+{
+ if (&p == m_Points[0]) {
+ return m_DelaunayEdge[2];
+ } else if (&p == m_Points[1]) {
+ return m_DelaunayEdge[0];
+ }
+ return m_DelaunayEdge[1];
+}
+
+bool TriangulationTriangle::getDelunayEdgeCW(Point& p)
+{
+ if (&p == m_Points[0]) {
+ return m_DelaunayEdge[1];
+ } else if (&p == m_Points[1]) {
+ return m_DelaunayEdge[2];
+ }
+ return m_DelaunayEdge[0];
+}
+
+void TriangulationTriangle::setDelunayEdgeCCW(Point& p, bool e)
+{
+ if (&p == m_Points[0]) {
+ m_DelaunayEdge[2] = e;
+ } else if (&p == m_Points[1]) {
+ m_DelaunayEdge[0] = e;
+ } else {
+ m_DelaunayEdge[1] = e;
+ }
+}
+
+void TriangulationTriangle::setDelunayEdgeCW(Point& p, bool e)
+{
+ if (&p == m_Points[0]) {
+ m_DelaunayEdge[1] = e;
+ } else if (&p == m_Points[1]) {
+ m_DelaunayEdge[2] = e;
+ } else {
+ m_DelaunayEdge[0] = e;
+ }
+}
+
+TriangulationTriangle& TriangulationTriangle::neighborAcross(Point& opoint)
+{
+ if (&opoint == m_Points[0]) {
+ return *m_Neighbors[0];
+ } else if (&opoint == m_Points[1]) {
+ return *m_Neighbors[1];
+ }
+ return *m_Neighbors[2];
+}
+
+}
+
diff --git a/src/base/triangulate/Shapes.h b/src/base/triangulate/Shapes.h
new file mode 100644
index 0000000..0417d7c
--- /dev/null
+++ b/src/base/triangulate/Shapes.h
@@ -0,0 +1,296 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+//
+// Based on Poly2Tri algorithm.
+// Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors
+// http://code.google.com/p/poly2tri/
+//
+
+#ifndef SHAPES_H
+#define SHAPES_H
+
+#include <vector>
+#include <cstddef>
+#include <assert.h>
+#include <cmath>
+
+namespace avg {
+
+struct Edge;
+
+struct Point
+{
+ double m_X, m_Y;
+ int m_Index;
+
+ /// The edges this point constitutes an upper ending point
+ std::vector<Edge*> m_EdgeList;
+
+ /// Default constructor does nothing (for performance).
+ Point() {
+ m_X = 0.0;
+ m_Y = 0.0;
+ m_Index = 0;
+ }
+
+ Point(double x, double y, int index) :
+ m_X(x), m_Y(y), m_Index(index) {}
+
+ void set_zero()
+ {
+ m_X = 0.0;
+ m_Y = 0.0;
+ }
+
+ void set(double x_, double y_)
+ {
+ m_X = x_;
+ m_Y = y_;
+ }
+
+ Point operator -() const
+ {
+ Point v;
+ v.set(-m_X, -m_Y);
+ return v;
+ }
+
+ void operator +=(const Point& v)
+ {
+ m_X += v.m_X;
+ m_Y += v.m_Y;
+ }
+
+ void operator -=(const Point& v)
+ {
+ m_X -= v.m_X;
+ m_Y -= v.m_Y;
+ }
+
+ void operator *=(double a)
+ {
+ m_X *= a;
+ m_Y *= a;
+ }
+
+ double length() const
+ {
+ return sqrt(m_X * m_X + m_Y * m_Y);
+ }
+
+ /// Convert this point into a unit point. Returns the Length.
+ double normalize()
+ {
+ double len = length();
+ m_X /= len;
+ m_Y /= len;
+ return len;
+ }
+
+};
+
+
+// Represents a simple polygon's edge
+struct Edge
+{
+ Point* m_P, *m_Q;
+
+ Edge(Point& p1, Point& p2) :m_P(&p1), m_Q(&p2)
+ {
+ if (p1.m_Y > p2.m_Y) {
+ m_Q = &p1;
+ m_P = &p2;
+ } else if (p1.m_Y == p2.m_Y) {
+ if (p1.m_X > p2.m_X) {
+ m_Q = &p1;
+ m_P = &p2;
+ } else if (p1.m_X == p2.m_X) {
+ // Repeat points
+ assert(false);
+ }
+ }
+ m_Q->m_EdgeList.push_back(this);
+ }
+};
+
+
+class TriangulationTriangle
+{
+
+public:
+
+ TriangulationTriangle(Point& a, Point& b, Point& c);
+
+/// Flags to determine if an edge is a Constrained edge
+ bool m_ConstrainedEdge[3];
+/// Flags to determine if an edge is a Delauney edge
+ bool m_DelaunayEdge[3];
+
+ Point* getPoint(const int& index);
+ Point* pointCW(Point& point);
+ Point* pointCCW(Point& point);
+ Point* oppositePoint(TriangulationTriangle& t, Point& p);
+
+ TriangulationTriangle* getNeighbor(const int& index);
+ void markNeighbor(Point* p1, Point* p2, TriangulationTriangle* t);
+ void markNeighbor(TriangulationTriangle& t);
+
+ void markConstrainedEdge(const int index);
+ void markConstrainedEdge(Edge& edge);
+ void markConstrainedEdge(Point* p, Point* q);
+
+ unsigned int index(const Point* p);
+ unsigned int edgeIndex(const Point* p1, const Point* p2);
+
+ TriangulationTriangle* neighborCW(Point& point);
+ TriangulationTriangle* neighborCCW(Point& point);
+ bool getConstrainedEdgeCCW(Point& p);
+ bool getConstrainedEdgeCW(Point& p);
+ void setConstrainedEdgeCCW(Point& p, bool ce);
+ void setConstrainedEdgeCW(Point& p, bool ce);
+ bool getDelunayEdgeCCW(Point& p);
+ bool getDelunayEdgeCW(Point& p);
+ void setDelunayEdgeCCW(Point& p, bool e);
+ void setDelunayEdgeCW(Point& p, bool e);
+
+ bool contains(Point* p);
+ bool contains(const Edge& e);
+ bool contains(Point* p, Point* q);
+ void legalize(Point& point);
+ void legalize(Point& opoint, Point& npoint);
+
+ void clear();
+ void clearNeighbor(TriangulationTriangle *triangle);
+ void clearNeighbors();
+ void clearDelunayEdges();
+
+ inline bool isInterior();
+ inline void isInterior(bool b);
+
+ TriangulationTriangle& neighborAcross(Point& opoint);
+
+private:
+
+ Point* m_Points[3];
+
+ TriangulationTriangle* m_Neighbors[3];
+
+ bool m_Interior;
+};
+
+inline bool cmp(const Point* a, const Point* b)
+{
+ if (a->m_Y < b->m_Y) {
+ return true;
+ } else if (a->m_Y == b->m_Y) {
+ // Make sure q is point with greater x value
+ if (a->m_X < b->m_X) {
+ return true;
+ }
+ }
+ return false;
+}
+/*
+ inline Point operator +(const Point& a, const Point& b)
+ {
+ return Point(a.x + b.x, a.y + b.y);
+ }
+
+ inline Point operator -(const Point& a, const Point& b)
+ {
+ return Point(a.x - b.x, a.y - b.y);
+ }
+
+ inline Point operator *(double s, const Point& a)
+ {
+ return Point(s * a.x, s * a.y, a.index);
+ } */
+
+inline bool operator ==(const Point& a, const Point& b)
+{
+ return a.m_X == b.m_X && a.m_Y == b.m_Y;
+}
+
+inline bool operator !=(const Point& a, const Point& b)
+{
+ return a.m_X != b.m_X && a.m_Y != b.m_Y;
+}
+
+inline double dot(const Point& a, const Point& b)
+{
+ return a.m_X * b.m_X + a.m_Y * b.m_Y;
+}
+
+inline double cross(const Point& a, const Point& b)
+{
+ return a.m_X * b.m_Y - a.m_Y * b.m_X;
+}
+
+inline Point cross(const Point& a, double s)
+{
+ return Point(s * a.m_Y, -s * a.m_X, a.m_Index);
+}
+
+inline Point cross(const double s, const Point& a)
+{
+ return Point(-s * a.m_Y, s * a.m_X, a.m_Index);
+}
+
+inline Point* TriangulationTriangle::getPoint(const int& index)
+{
+ return m_Points[index];
+}
+
+inline TriangulationTriangle* TriangulationTriangle::getNeighbor(
+ const int& index)
+{
+ return m_Neighbors[index];
+}
+
+inline bool TriangulationTriangle::contains(Point* p)
+{
+ return p == m_Points[0] || p == m_Points[1] || p == m_Points[2];
+}
+
+inline bool TriangulationTriangle::contains(const Edge& e)
+{
+ return contains(e.m_P) && contains(e.m_Q);
+}
+
+inline bool TriangulationTriangle::contains(Point* p, Point* q)
+{
+ return contains(p) && contains(q);
+}
+
+inline bool TriangulationTriangle::isInterior()
+{
+ return m_Interior;
+}
+
+inline void TriangulationTriangle::isInterior(bool b)
+{
+ m_Interior = b;
+}
+
+}
+
+#endif
diff --git a/src/base/triangulate/Sweep.cpp b/src/base/triangulate/Sweep.cpp
new file mode 100644
index 0000000..2655cb0
--- /dev/null
+++ b/src/base/triangulate/Sweep.cpp
@@ -0,0 +1,796 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+//
+// Based on Poly2Tri algorithm.
+// Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors
+// http://code.google.com/p/poly2tri/
+//
+
+#include <stdexcept>
+#include "Sweep.h"
+#include "SweepContext.h"
+#include "AdvancingFront.h"
+#include "Utils.h"
+
+namespace avg {
+
+void Sweep::Triangulate(SweepContext& sc)
+{
+ arrayCount = 0;
+ for (unsigned int i = 0; i < (unsigned)sc.pointCount(); i++) {
+ m_Nodes.push_back(new Node());
+ }
+ sc.initTriangulation();
+ sc.createAdvancingFront();
+ // Sweep points; build mesh
+ sweepPoints(sc);
+ // Clean up
+ finalizationPolygon(sc);
+}
+
+void Sweep::sweepPoints(SweepContext& sc)
+{
+ for (int i = 1; i < sc.pointCount(); i++) {
+ Point& point = *sc.getPoint(i);
+ Node* node = &pointEvent(sc, point);
+ for (unsigned int i = 0; i < point.m_EdgeList.size(); i++) {
+ edgeEvent(sc, point.m_EdgeList[i], node);
+ }
+ }
+}
+
+void Sweep::finalizationPolygon(SweepContext& sc)
+{
+ // Get an Internal triangle to start with
+ TriangulationTriangle* t = sc.front()->head()->m_Next->m_Triangle;
+ Point* p = sc.front()->head()->m_Next->m_Point;
+ while (!t->getConstrainedEdgeCW(*p)) {
+ t = t->neighborCCW(*p);
+ }
+
+ // Collect interior triangles constrained by edges
+ sc.meshClean(*t);
+}
+
+Node& Sweep::pointEvent(SweepContext& sc, Point& point)
+{
+ Node& node = sc.locateNode(point);
+ Node& new_node = newFrontTriangle(sc, point, node);
+
+ // Only need to check +epsilon since point never have smaller
+ // x value than node due to how we fetch nodes from the front
+ if (point.m_X <= node.m_Point->m_X + EPSILON) {
+ fill(sc, node);
+ }
+
+ //tcx.AddNode(new_node);
+
+ fillAdvancingFront(sc, new_node);
+ return new_node;
+}
+
+void Sweep::edgeEvent(SweepContext& sc, Edge* edge, Node* node)
+{
+ sc.m_EdgeEvent.m_ConstrainedEdge = edge;
+ sc.m_EdgeEvent.m_Right = (edge->m_P->m_X > edge->m_Q->m_X);
+
+ if (isEdgeSideOfTriangle(*node->m_Triangle, *edge->m_P, *edge->m_Q)) {
+ return;
+ }
+
+ // to do: integrate with flip process might give some better performance
+ // but for now this avoid the issue with cases that needs both flips and fills
+ fillEdgeEvent(sc, edge, node);
+ edgeEvent(sc, *edge->m_P, *edge->m_Q, node->m_Triangle, *edge->m_Q);
+}
+
+void Sweep::edgeEvent(SweepContext& sc, Point& ep, Point& eq,
+ TriangulationTriangle* triangle, Point& point)
+{
+ if (isEdgeSideOfTriangle(*triangle, ep, eq)) {
+ return;
+ }
+
+ Point* p1 = triangle->pointCCW(point);
+ Orientation o1 = orient2d(eq, *p1, ep);
+ if (o1 == COLLINEAR) {
+ if (triangle->contains(&eq, p1)) {
+ triangle->markConstrainedEdge(&eq, p1);
+ // We are modifying the constraint maybe it would be better to
+ // not change the given constraint and just keep a variable for the new constraint
+ sc.m_EdgeEvent.m_ConstrainedEdge->m_Q = p1;
+ triangle = &triangle->neighborAcross(point);
+ edgeEvent(sc, ep, *p1, triangle, *p1);
+ } else {
+ std::runtime_error("EdgeEvent - collinear points not supported");
+ assert(0);
+ }
+ return;
+ }
+
+ Point* p2 = triangle->pointCW(point);
+ Orientation o2 = orient2d(eq, *p2, ep);
+ if (o2 == COLLINEAR) {
+ if (triangle->contains(&eq, p2)) {
+ triangle->markConstrainedEdge(&eq, p2);
+ // We are modifying the constraint maybe it would be better to
+ // not change the given constraint and just keep a variable for the new constraint
+ sc.m_EdgeEvent.m_ConstrainedEdge->m_Q = p2;
+ triangle = &triangle->neighborAcross(point);
+ edgeEvent(sc, ep, *p2, triangle, *p2);
+ } else {
+ std::runtime_error("EdgeEvent - collinear points not supported");
+ assert(0);
+ }
+ return;
+ }
+
+ if (o1 == o2) {
+ // Need to decide if we are rotating CW or CCW to get to a triangle
+ // that will cross edge
+ if (o1 == CW) {
+ triangle = triangle->neighborCCW(point);
+ } else {
+ triangle = triangle->neighborCW(point);
+ }
+ edgeEvent(sc, ep, eq, triangle, point);
+ } else {
+ // This triangle crosses constraint so lets flippin start!
+ flipEdgeEvent(sc, ep, eq, triangle, point);
+ }
+}
+
+bool Sweep::isEdgeSideOfTriangle(TriangulationTriangle& triangle, Point& ep,
+ Point& eq)
+{
+ int index = triangle.edgeIndex(&ep, &eq);
+
+ if (index != -1) {
+ triangle.markConstrainedEdge(index);
+ TriangulationTriangle* t = triangle.getNeighbor(index);
+ if (t) {
+ t->markConstrainedEdge(&ep, &eq);
+ }
+ return true;
+ }
+ return false;
+}
+
+Node& Sweep::newFrontTriangle(SweepContext& sc, Point& point, Node& node)
+{
+ TriangulationTriangle* triangle = new TriangulationTriangle(point,
+ *node.m_Point, *node.m_Next->m_Point);
+
+ triangle->markNeighbor(*node.m_Triangle);
+ sc.addToMap(triangle);
+
+ Node* newNode = m_Nodes[arrayCount++]; //new Node(point);
+ newNode->m_Point = &point;
+ newNode->m_Value = point.m_X;
+// m_Nodes.push_back(newNode);
+
+ newNode->m_Next = node.m_Next;
+ newNode->m_Prev = &node;
+ node.m_Next->m_Prev = newNode;
+ node.m_Next = newNode;
+
+ if (!legalize(sc, *triangle)) {
+ sc.mapTriangleToNodes(*triangle);
+ }
+
+ return *newNode;
+}
+
+void Sweep::fill(SweepContext& sc, Node& node)
+{
+ TriangulationTriangle* triangle = new TriangulationTriangle(
+ *node.m_Prev->m_Point, *node.m_Point, *node.m_Next->m_Point);
+
+ // TO DO: should copy the constrained_edge value from neighbor triangles
+ // for now constrained_edge values are copied during the legalize
+ triangle->markNeighbor(*node.m_Prev->m_Triangle);
+ triangle->markNeighbor(*node.m_Triangle);
+
+ sc.addToMap(triangle);
+
+ // Update the advancing front
+ node.m_Prev->m_Next = node.m_Next;
+ node.m_Next->m_Prev = node.m_Prev;
+
+ // If it was legalized the triangle has already been mapped
+ if (!legalize(sc, *triangle)) {
+ sc.mapTriangleToNodes(*triangle);
+ }
+
+}
+
+void Sweep::fillAdvancingFront(SweepContext& sc, Node& n)
+{
+ Node* node = n.m_Next;
+
+ while (node->m_Next) {
+ double angle = holeAngle(*node);
+ if (angle > M_PI_2 || angle < -M_PI_2)
+ break;
+// ---------- LEAK FIX --------------
+// Fill(tcx, *node);
+// node = node->m_next;
+
+
+ Node *tmp = node;
+ node = node->m_Next;
+ fill(sc, *tmp);
+// ----------------------------------
+ }
+
+ node = n.m_Prev;
+
+ while (node->m_Prev) {
+ double angle = holeAngle(*node);
+ if (angle > M_PI_2 || angle < -M_PI_2)
+ break;
+ fill(sc, *node);
+ node = node->m_Prev;
+ }
+
+ if (n.m_Next && n.m_Next->m_Next) {
+ double angle = basinAngle(n);
+ if (angle < PI_3div4) {
+ fillBasin(sc, n);
+ }
+ }
+}
+
+double Sweep::basinAngle(Node& node)
+{
+ double ax = node.m_Point->m_X - node.m_Next->m_Next->m_Point->m_X;
+ double ay = node.m_Point->m_Y - node.m_Next->m_Next->m_Point->m_Y;
+ return atan2(ay, ax);
+}
+
+double Sweep::holeAngle(Node& node)
+{
+ /* Complex plane
+ * ab = cosA +i*sinA
+ * ab = (ax + ay*i)(bx + by*i) = (ax*bx + ay*by) + i(ax*by-ay*bx)
+ * atan2(y,x) computes the principal value of the argument function
+ * applied to the complex number x+iy
+ * Where x = ax*bx + ay*by
+ * y = ax*by - ay*bx
+ */
+ double ax = node.m_Next->m_Point->m_X - node.m_Point->m_X;
+ double ay = node.m_Next->m_Point->m_Y - node.m_Point->m_Y;
+ double bx = node.m_Prev->m_Point->m_X - node.m_Point->m_X;
+ double by = node.m_Prev->m_Point->m_Y - node.m_Point->m_Y;
+ return atan2(ax * by - ay * bx, ax * bx + ay * by);
+}
+
+bool Sweep::legalize(SweepContext& sc, TriangulationTriangle& t)
+{
+ // To legalize a triangle we start by finding if any of the three edges
+ // violate the Delaunay condition
+ for (int i = 0; i < 3; i++) {
+ if (t.m_DelaunayEdge[i])
+ continue;
+
+ TriangulationTriangle* ot = t.getNeighbor(i);
+
+ if (ot) {
+ Point* p = t.getPoint(i);
+ Point* op = ot->oppositePoint(t, *p);
+ int oi = ot->index(op);
+
+ // If this is a Constrained Edge or a Delaunay Edge(only during recursive legalization)
+ // then we should not try to legalize
+ if (ot->m_ConstrainedEdge[oi] || ot->m_DelaunayEdge[oi]) {
+ t.m_ConstrainedEdge[i] = ot->m_ConstrainedEdge[oi];
+ continue;
+ }
+
+ bool inside = incircle(*p, *t.pointCCW(*p), *t.pointCW(*p), *op);
+
+ if (inside) {
+ // Lets mark this shared edge as Delaunay
+ t.m_DelaunayEdge[i] = true;
+ ot->m_DelaunayEdge[oi] = true;
+
+ // Lets rotate shared edge one vertex CW to legalize it
+ rotateTrianglePair(t, *p, *ot, *op);
+
+ // We now got one valid Delaunay Edge shared by two triangles
+ // This gives us 4 new edges to check for Delaunay
+
+ // Make sure that triangle to node mapping is done only one time for a specific triangle
+ bool notLegalized = !legalize(sc, t);
+ if (notLegalized) {
+ sc.mapTriangleToNodes(t);
+ }
+
+ notLegalized = !legalize(sc, *ot);
+ if (notLegalized)
+ sc.mapTriangleToNodes(*ot);
+
+ // Reset the Delaunay edges, since they only are valid Delaunay edges
+ // until we add a new triangle or point.
+ // XX X: need to think about this. Can these edges be tried after we
+ // return to previous recursive level?
+ t.m_DelaunayEdge[i] = false;
+ ot->m_DelaunayEdge[oi] = false;
+
+ // If triangle have been legalized no need to check the other edges since
+ // the recursive legalization will handles those so we can end here.
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+bool Sweep::incircle(Point& pa, Point& pb, Point& pc, Point& pd)
+{
+ double adx = pa.m_X - pd.m_X;
+ double ady = pa.m_Y - pd.m_Y;
+ double bdx = pb.m_X - pd.m_X;
+ double bdy = pb.m_Y - pd.m_Y;
+
+ double adxbdy = adx * bdy;
+ double bdxady = bdx * ady;
+ double oabd = adxbdy - bdxady;
+
+ if (oabd <= 0) {
+ return false;
+ }
+
+ double cdx = pc.m_X - pd.m_X;
+ double cdy = pc.m_Y - pd.m_Y;
+
+ double cdxady = cdx * ady;
+ double adxcdy = adx * cdy;
+ double ocad = cdxady - adxcdy;
+
+ if (ocad <= 0) {
+ return false;
+ }
+
+ double bdxcdy = bdx * cdy;
+ double cdxbdy = cdx * bdy;
+
+ double alift = adx * adx + ady * ady;
+ double blift = bdx * bdx + bdy * bdy;
+ double clift = cdx * cdx + cdy * cdy;
+
+ double det = alift * (bdxcdy - cdxbdy) + blift * ocad + clift * oabd;
+
+ return det > 0;
+}
+
+void Sweep::rotateTrianglePair(TriangulationTriangle& t, Point& p,
+ TriangulationTriangle& ot, Point& op)
+{
+ TriangulationTriangle* n1, *n2, *n3, *n4;
+ n1 = t.neighborCCW(p);
+ n2 = t.neighborCW(p);
+ n3 = ot.neighborCCW(op);
+ n4 = ot.neighborCW(op);
+
+ bool ce1, ce2, ce3, ce4;
+ ce1 = t.getConstrainedEdgeCCW(p);
+ ce2 = t.getConstrainedEdgeCW(p);
+ ce3 = ot.getConstrainedEdgeCCW(op);
+ ce4 = ot.getConstrainedEdgeCW(op);
+
+ bool de1, de2, de3, de4;
+ de1 = t.getDelunayEdgeCCW(p);
+ de2 = t.getDelunayEdgeCW(p);
+ de3 = ot.getDelunayEdgeCCW(op);
+ de4 = ot.getDelunayEdgeCW(op);
+
+ t.legalize(p, op);
+ ot.legalize(op, p);
+
+ // Remap delaunay_edge
+ ot.setDelunayEdgeCCW(p, de1);
+ t.setDelunayEdgeCW(p, de2);
+ t.setDelunayEdgeCCW(op, de3);
+ ot.setDelunayEdgeCW(op, de4);
+
+ // Remap constrained_edge
+ ot.setConstrainedEdgeCCW(p, ce1);
+ t.setConstrainedEdgeCW(p, ce2);
+ t.setConstrainedEdgeCCW(op, ce3);
+ ot.setConstrainedEdgeCW(op, ce4);
+
+ // Remap neighbors
+ // XX X: might optimize the markNeighbor by keeping track of
+ // what side should be assigned to what neighbor after the
+ // rotation. Now mark neighbor does lots of testing to find
+ // the right side.
+ t.clearNeighbors();
+ ot.clearNeighbors();
+ if (n1) {
+ ot.markNeighbor(*n1);
+ }
+ if (n2) {
+ t.markNeighbor(*n2);
+ }
+ if (n3) {
+ t.markNeighbor(*n3);
+ }
+ if (n4) {
+ ot.markNeighbor(*n4);
+ }
+ t.markNeighbor(ot);
+}
+
+void Sweep::fillBasin(SweepContext& sc, Node& node)
+{
+ if (orient2d(*node.m_Point, *node.m_Next->m_Point, *node.m_Next->m_Next->m_Point)
+ == CCW) {
+ sc.m_Basin.m_LeftNode = node.m_Next->m_Next;
+ } else {
+ sc.m_Basin.m_LeftNode = node.m_Next;
+ }
+
+ // Find the bottom and right node
+ sc.m_Basin.m_BottomNode = sc.m_Basin.m_LeftNode;
+ while (sc.m_Basin.m_BottomNode->m_Next
+ && sc.m_Basin.m_BottomNode->m_Point->m_Y
+ >= sc.m_Basin.m_BottomNode->m_Next->m_Point->m_Y) {
+ sc.m_Basin.m_BottomNode = sc.m_Basin.m_BottomNode->m_Next;
+ }
+ if (sc.m_Basin.m_BottomNode == sc.m_Basin.m_LeftNode) {
+ // No valid basin
+ return;
+ }
+
+ sc.m_Basin.m_RightNode = sc.m_Basin.m_BottomNode;
+ while (sc.m_Basin.m_RightNode->m_Next
+ && sc.m_Basin.m_RightNode->m_Point->m_Y
+ < sc.m_Basin.m_RightNode->m_Next->m_Point->m_Y) {
+ sc.m_Basin.m_RightNode = sc.m_Basin.m_RightNode->m_Next;
+ }
+ if (sc.m_Basin.m_RightNode == sc.m_Basin.m_BottomNode) {
+ // No valid basins
+ return;
+ }
+
+ sc.m_Basin.m_Width = sc.m_Basin.m_RightNode->m_Point->m_X
+ - sc.m_Basin.m_LeftNode->m_Point->m_X;
+ sc.m_Basin.m_LeftHighest = sc.m_Basin.m_LeftNode->m_Point->m_Y
+ > sc.m_Basin.m_RightNode->m_Point->m_Y;
+
+ fillBasinReq(sc, sc.m_Basin.m_BottomNode);
+}
+
+void Sweep::fillBasinReq(SweepContext& sc, Node* node)
+{
+ // if shallow stop filling
+ if (isShallow(sc, *node)) {
+ return;
+ }
+
+ fill(sc, *node);
+
+ if (node->m_Prev == sc.m_Basin.m_LeftNode
+ && node->m_Next == sc.m_Basin.m_RightNode) {
+ return;
+ } else if (node->m_Prev == sc.m_Basin.m_LeftNode) {
+ Orientation o = orient2d(*node->m_Point, *node->m_Next->m_Point,
+ *node->m_Next->m_Next->m_Point);
+ if (o == CW) {
+ return;
+ }
+ node = node->m_Next;
+ } else if (node->m_Next == sc.m_Basin.m_RightNode) {
+ Orientation o = orient2d(*node->m_Point, *node->m_Prev->m_Point,
+ *node->m_Prev->m_Prev->m_Point);
+ if (o == CCW) {
+ return;
+ }
+ node = node->m_Prev;
+ } else {
+ // Continue with the neighbor node with lowest Y value
+ if (node->m_Prev->m_Point->m_Y < node->m_Next->m_Point->m_Y) {
+ node = node->m_Prev;
+ } else {
+ node = node->m_Next;
+ }
+ }
+
+ fillBasinReq(sc, node);
+}
+
+bool Sweep::isShallow(SweepContext& sc, Node& node)
+{
+ double height;
+
+ if (sc.m_Basin.m_LeftHighest) {
+ height = sc.m_Basin.m_LeftNode->m_Point->m_Y - node.m_Point->m_Y;
+ } else {
+ height = sc.m_Basin.m_RightNode->m_Point->m_Y - node.m_Point->m_Y;
+ }
+
+ // if shallow stop filling
+ if (sc.m_Basin.m_Width > height) {
+ return true;
+ }
+ return false;
+}
+
+void Sweep::fillEdgeEvent(SweepContext& sc, Edge* edge, Node* node)
+{
+ if (sc.m_EdgeEvent.m_Right) {
+ fillRightAboveEdgeEvent(sc, edge, node);
+ } else {
+ fillLeftAboveEdgeEvent(sc, edge, node);
+ }
+}
+
+void Sweep::fillRightAboveEdgeEvent(SweepContext& sc, Edge* edge, Node* node)
+{
+ while (node->m_Next->m_Point->m_X < edge->m_P->m_X) {
+ // Check if next node is below the edge
+ if (orient2d(*edge->m_Q, *node->m_Next->m_Point, *edge->m_P) == CCW) {
+ fillRightBelowEdgeEvent(sc, edge, *node);
+ } else {
+ node = node->m_Next;
+ }
+ }
+}
+
+void Sweep::fillRightBelowEdgeEvent(SweepContext& sc, Edge* edge, Node& node)
+{
+ if (node.m_Point->m_X < edge->m_P->m_X) {
+ if (orient2d(*node.m_Point, *node.m_Next->m_Point, *node.m_Next->m_Next->m_Point)
+ == CCW) {
+ // Concave
+ fillRightConcaveEdgeEvent(sc, edge, node);
+ } else {
+ // Convex
+ fillRightConvexEdgeEvent(sc, edge, node);
+ // Retry this one
+ fillRightBelowEdgeEvent(sc, edge, node);
+ }
+ }
+}
+
+void Sweep::fillRightConcaveEdgeEvent(SweepContext& sc, Edge* edge, Node& node)
+{
+ fill(sc, *node.m_Next);
+ if (node.m_Next->m_Point != edge->m_P) {
+ // Next above or below edge?
+ if (orient2d(*edge->m_Q, *node.m_Next->m_Point, *edge->m_P) == CCW) {
+ // Below
+ if (orient2d(*node.m_Point, *node.m_Next->m_Point,
+ *node.m_Next->m_Next->m_Point) == CCW) {
+ // Next is concave
+ fillRightConcaveEdgeEvent(sc, edge, node);
+ } else {
+ // Next is convex
+ }
+ }
+ }
+
+}
+
+void Sweep::fillRightConvexEdgeEvent(SweepContext& sc, Edge* edge, Node& node)
+{
+ // Next concave or convex?
+ if (orient2d(*node.m_Next->m_Point, *node.m_Next->m_Next->m_Point,
+ *node.m_Next->m_Next->m_Next->m_Point) == CCW) {
+ // Concave
+ fillRightConcaveEdgeEvent(sc, edge, *node.m_Next);
+ } else {
+ // Convex
+ // Next above or below edge?
+ if (orient2d(*edge->m_Q, *node.m_Next->m_Next->m_Point, *edge->m_P) == CCW) {
+ // Below
+ fillRightConvexEdgeEvent(sc, edge, *node.m_Next);
+ } else {
+ // Above
+ }
+ }
+}
+
+void Sweep::fillLeftAboveEdgeEvent(SweepContext& sc, Edge* edge, Node* node)
+{
+ while (node->m_Prev->m_Point->m_X > edge->m_P->m_X) {
+ // Check if next node is below the edge
+ if (orient2d(*edge->m_Q, *node->m_Prev->m_Point, *edge->m_P) == CW) {
+ fillLeftBelowEdgeEvent(sc, edge, *node);
+ } else {
+ node = node->m_Prev;
+ }
+ }
+}
+
+void Sweep::fillLeftBelowEdgeEvent(SweepContext& sc, Edge* edge, Node& node)
+{
+ if (node.m_Point->m_X > edge->m_P->m_X) {
+ if (orient2d(*node.m_Point, *node.m_Prev->m_Point, *node.m_Prev->m_Prev->m_Point)
+ == CW) {
+ // Concave
+ fillLeftConcaveEdgeEvent(sc, edge, node);
+ } else {
+ // Convex
+ fillLeftConvexEdgeEvent(sc, edge, node);
+ // Retry this one
+ fillLeftBelowEdgeEvent(sc, edge, node);
+ }
+ }
+}
+
+void Sweep::fillLeftConvexEdgeEvent(SweepContext& sc, Edge* edge, Node& node)
+{
+ // Next concave or convex?
+ if (orient2d(*node.m_Prev->m_Point, *node.m_Prev->m_Prev->m_Point,
+ *node.m_Prev->m_Prev->m_Prev->m_Point) == CW) {
+ // Concave
+ fillLeftConcaveEdgeEvent(sc, edge, *node.m_Prev);
+ } else {
+ // Convex
+ // Next above or below edge?
+ if (orient2d(*edge->m_Q, *node.m_Prev->m_Prev->m_Point, *edge->m_P) == CW) {
+ // Below
+ fillLeftConvexEdgeEvent(sc, edge, *node.m_Prev);
+ } else {
+ // Above
+ }
+ }
+}
+
+void Sweep::fillLeftConcaveEdgeEvent(SweepContext& sc, Edge* edge, Node& node)
+{
+ fill(sc, *node.m_Prev);
+ if (node.m_Prev->m_Point != edge->m_P) {
+ // Next above or below edge?
+ if (orient2d(*edge->m_Q, *node.m_Prev->m_Point, *edge->m_P) == CW) {
+ // Below
+ if (orient2d(*node.m_Point, *node.m_Prev->m_Point,
+ *node.m_Prev->m_Prev->m_Point) == CW) {
+ // Next is concave
+ fillLeftConcaveEdgeEvent(sc, edge, node);
+ } else {
+ // Next is convex
+ }
+ }
+ }
+
+}
+
+void Sweep::flipEdgeEvent(SweepContext& sc, Point& ep, Point& eq,
+ TriangulationTriangle* t, Point& p)
+{
+ TriangulationTriangle& ot = t->neighborAcross(p);
+ Point& op = *ot.oppositePoint(*t, p);
+
+ if (&ot == NULL) {
+ // If we want to integrate the fillEdgeEvent do it here
+ // With current implementation we should never get here
+ //throw new RuntimeException( "[BUG:FIXM E] FLIP failed due to missing triangle");
+ assert(0);
+ }
+
+ if (inScanArea(p, *t->pointCCW(p), *t->pointCW(p), op)) {
+ // Lets rotate shared edge one vertex CW
+ rotateTrianglePair(*t, p, ot, op);
+ sc.mapTriangleToNodes(*t);
+ sc.mapTriangleToNodes(ot);
+
+ if (p == eq && op == ep) {
+ if (eq == *sc.m_EdgeEvent.m_ConstrainedEdge->m_Q
+ && ep == *sc.m_EdgeEvent.m_ConstrainedEdge->m_P) {
+ t->markConstrainedEdge(&ep, &eq);
+ ot.markConstrainedEdge(&ep, &eq);
+ legalize(sc, *t);
+ legalize(sc, ot);
+ } else {
+ // One of the triangles should be legalized here?
+ }
+ } else {
+ Orientation o = orient2d(eq, op, ep);
+ t = &nextFlipTriangle(sc, (int) o, *t, ot, p, op);
+ flipEdgeEvent(sc, ep, eq, t, p);
+ }
+ } else {
+ Point& newP = nextFlipPoint(ep, eq, ot, op);
+ flipScanEdgeEvent(sc, ep, eq, *t, ot, newP);
+ edgeEvent(sc, ep, eq, t, p);
+ }
+}
+
+TriangulationTriangle& Sweep::nextFlipTriangle(SweepContext& sc, int o,
+ TriangulationTriangle& t, TriangulationTriangle& ot, Point& p, Point& op)
+{
+ if (o == CCW) {
+ // ot is not crossing edge after flip
+ int edgeIndex = ot.edgeIndex(&p, &op);
+ ot.m_DelaunayEdge[edgeIndex] = true;
+ legalize(sc, ot);
+ ot.clearDelunayEdges();
+ return t;
+ }
+
+ // t is not crossing edge after flip
+ int edgeIndex = t.edgeIndex(&p, &op);
+
+ t.m_DelaunayEdge[edgeIndex] = true;
+ legalize(sc, t);
+ t.clearDelunayEdges();
+ return ot;
+}
+
+Point& Sweep::nextFlipPoint(Point& ep, Point& eq, TriangulationTriangle& ot, Point& op)
+{
+ Orientation o2d = orient2d(eq, op, ep);
+ if (o2d == CW) {
+ // Right
+ return *ot.pointCCW(op);
+ } else if (o2d == CCW) {
+ // Left
+ return *ot.pointCW(op);
+ } else {
+ //throw new RuntimeException("[Unsupported] Opposing point on constrained edge");
+ assert(0);
+ return ep; // Silence compiler warning.
+ }
+}
+
+void Sweep::flipScanEdgeEvent(SweepContext& sc, Point& ep, Point& eq,
+ TriangulationTriangle& flipTriangle, TriangulationTriangle& t, Point& p)
+{
+ TriangulationTriangle& ot = t.neighborAcross(p);
+ Point& op = *ot.oppositePoint(t, p);
+
+ if (&t.neighborAcross(p) == NULL) {
+ // If we want to integrate the fillEdgeEvent do it here
+ // With current implementation we should never get here
+ //throw new RuntimeException( "[BUG:FIXM E] FLIP failed due to missing triangle");
+ assert(0);
+ }
+
+ if (inScanArea(eq, *flipTriangle.pointCCW(eq), *flipTriangle.pointCW(eq),
+ op)) {
+ // flip with new edge op->eq
+ flipEdgeEvent(sc, eq, op, &ot, op);
+ // To do: Actually I just figured out that it should be possible to
+ // improve this by getting the next ot and op before the the above
+ // flip and continue the flipScanEdgeEvent here
+ // set new ot and op here and loop back to inScanArea test
+ // also need to set a new flip_triangle first
+ // Turns out at first glance that this is somewhat complicated
+ // so it will have to wait.
+ } else {
+ Point& newP = nextFlipPoint(ep, eq, ot, op);
+ flipScanEdgeEvent(sc, ep, eq, flipTriangle, ot, newP);
+ }
+}
+
+Sweep::~Sweep()
+{
+ for (unsigned int i = 0; i < m_Nodes.size(); i++) {
+ delete m_Nodes[i];
+ }
+
+}
+
+}
diff --git a/src/base/triangulate/Sweep.h b/src/base/triangulate/Sweep.h
new file mode 100644
index 0000000..48cd13a
--- /dev/null
+++ b/src/base/triangulate/Sweep.h
@@ -0,0 +1,201 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+//
+// Based on Poly2Tri algorithm.
+// Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors
+// http://code.google.com/p/poly2tri/
+//
+
+#ifndef SWEEP_H
+#define SWEEP_H
+
+#include <vector>
+
+namespace avg {
+
+class SweepContext;
+struct Node;
+struct Point;
+struct Edge;
+class TriangulationTriangle;
+
+class Sweep
+{
+
+public:
+
+ void Triangulate(SweepContext& sc);
+
+ ~Sweep();
+
+private:
+
+ void sweepPoints(SweepContext& sc);
+
+ Node& pointEvent(SweepContext& sc, Point& point);
+
+ void edgeEvent(SweepContext& sc, Edge* edge, Node* node);
+
+ void edgeEvent(SweepContext& sc, Point& ep, Point& eq,
+ TriangulationTriangle* triangle, Point& point);
+
+ Node& newFrontTriangle(SweepContext& sc, Point& point, Node& node);
+
+ void fill(SweepContext& sc, Node& node);
+
+ bool legalize(SweepContext& sc, TriangulationTriangle& t);
+
+ /**
+ * <b>Requirement</b>:<br>
+ * 1. a,b and c form a triangle.<br>
+ * 2. a and d is know to be on opposite side of bc<br>
+ * <pre>
+ * a
+ * +
+ * / \
+ * / \
+ * b/ \c
+ * +-------+
+ * / d \
+ * / \
+ * </pre>
+ * <b>Fact</b>: d has to be in area B to have a chance to be inside the circle formed by
+ * a,b and c<br>
+ * d is outside B if orient2d(a,b,d) or orient2d(c,a,d) is CW<br>
+ * This preknowledge gives us a way to optimize the incircle test
+ * @param a - triangle point, opposite d
+ * @param b - triangle point
+ * @param c - triangle point
+ * @param d - point opposite a
+ * @return true if d is inside circle, false if on circle edge
+ */
+ bool incircle(Point& pa, Point& pb, Point& pc, Point& pd);
+
+ /**
+ * Rotates a triangle pair one vertex CW
+ *<pre>
+ * n2 n2
+ * P +-----+ P +-----+
+ * | t /| |\ t |
+ * | / | | \ |
+ * n1| / |n3 n1| \ |n3
+ * | / | after CW | \ |
+ * |/ oT | | oT \|
+ * +-----+ oP +-----+
+ * n4 n4
+ * </pre>
+ */
+ void rotateTrianglePair(TriangulationTriangle& t, Point& p, TriangulationTriangle& ot,
+ Point& op);
+
+ void fillAdvancingFront(SweepContext& sc, Node& n);
+
+ double holeAngle(Node& node);
+
+ /**
+ * The basin angle is decided against the horizontal line [1,0]
+ */
+ double basinAngle(Node& node);
+
+ void fillBasin(SweepContext& sc, Node& node);
+
+ void fillBasinReq(SweepContext& sc, Node* node);
+
+ bool isShallow(SweepContext& sc, Node& node);
+
+ bool isEdgeSideOfTriangle(TriangulationTriangle& triangle, Point& ep, Point& eq);
+
+ void fillEdgeEvent(SweepContext& sc, Edge* edge, Node* node);
+
+ void fillRightAboveEdgeEvent(SweepContext& sc, Edge* edge, Node* node);
+
+ void fillRightBelowEdgeEvent(SweepContext& sc, Edge* edge, Node& node);
+
+ void fillRightConcaveEdgeEvent(SweepContext& sc, Edge* edge, Node& node);
+
+ void fillRightConvexEdgeEvent(SweepContext& sc, Edge* edge, Node& node);
+
+ void fillLeftAboveEdgeEvent(SweepContext& sc, Edge* edge, Node* node);
+
+ void fillLeftBelowEdgeEvent(SweepContext& sc, Edge* edge, Node& node);
+
+ void fillLeftConcaveEdgeEvent(SweepContext& sc, Edge* edge, Node& node);
+
+ void fillLeftConvexEdgeEvent(SweepContext& sc, Edge* edge, Node& node);
+
+ void flipEdgeEvent(SweepContext& sc, Point& ep, Point& eq, TriangulationTriangle* t,
+ Point& p);
+
+ /**
+ * After a flip we have two triangles and know that only one will still be
+ * intersecting the edge. So decide which to contiune with and legalize the other
+ *
+ * @param sc
+ * @param o - should be the result of an orient2d( eq, op, ep )
+ * @param t - triangle 1
+ * @param ot - triangle 2
+ * @param p - a point shared by both triangles
+ * @param op - another point shared by both triangles
+ * @return returns the triangle still intersecting the edge
+ */
+ TriangulationTriangle& nextFlipTriangle(SweepContext& sc, int o,
+ TriangulationTriangle& t, TriangulationTriangle& ot, Point& p, Point& op);
+
+ /**
+ * When we need to traverse from one triangle to the next we need
+ * the point in current triangle that is the opposite point to the next
+ * triangle.
+ *
+ * @param ep
+ * @param eq
+ * @param ot
+ * @param op
+ * @return
+ */
+ Point& nextFlipPoint(Point& ep, Point& eq, TriangulationTriangle& ot, Point& op);
+
+ /**
+ * Scan part of the FlipScan algorithm<br>
+ * When a triangle pair isn't flippable we will scan for the next
+ * point that is inside the flip triangle scan area. When found
+ * we generate a new flipEdgeEvent
+ *
+ * @param sc
+ * @param ep - last point on the edge we are traversing
+ * @param eq - first point on the edge we are traversing
+ * @param flipTriangle - the current triangle sharing the point eq with edge
+ * @param t
+ * @param p
+ */
+ void flipScanEdgeEvent(SweepContext& sc, Point& ep, Point& eq,
+ TriangulationTriangle& flip_triangle, TriangulationTriangle& t, Point& p);
+
+ void finalizationPolygon(SweepContext& sc);
+
+ std::vector<Node*> m_Nodes;
+ unsigned int arrayCount;
+
+};
+
+}
+
+#endif
diff --git a/src/base/triangulate/SweepContext.cpp b/src/base/triangulate/SweepContext.cpp
new file mode 100644
index 0000000..16e642e
--- /dev/null
+++ b/src/base/triangulate/SweepContext.cpp
@@ -0,0 +1,196 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+//
+// Based on Poly2Tri algorithm.
+// Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors
+// http://code.google.com/p/poly2tri/
+//
+
+#include "SweepContext.h"
+#include <algorithm>
+#include "AdvancingFront.h"
+
+namespace avg {
+
+SweepContext::SweepContext(std::vector<Point*> polyline)
+{
+ m_Basin = Basin();
+ m_EdgeEvent = EdgeEvent();
+
+ m_Points = polyline;
+
+ initEdges(m_Points);
+}
+
+void SweepContext::addHole(std::vector<Point*> polyline)
+{
+ initEdges(polyline);
+ for (unsigned int i = 0; i < polyline.size(); i++) {
+ m_Points.push_back(polyline[i]);
+ }
+}
+
+void SweepContext::addPoint(Point* point)
+{
+ m_Points.push_back(point);
+}
+
+std::vector<TriangulationTriangle*>& SweepContext::getTriangles()
+{
+ return m_Triangles;
+}
+
+void SweepContext::initTriangulation()
+{
+ double xmax(m_Points[0]->m_X), xmin(m_Points[0]->m_X);
+ double ymax(m_Points[0]->m_Y), ymin(m_Points[0]->m_Y);
+
+ // Calculate bounds.
+ for (unsigned int i = 0; i < m_Points.size(); i++) {
+ Point& p = *m_Points[i];
+ if (p.m_X > xmax) {
+ xmax = p.m_X;
+ }
+ if (p.m_X < xmin) {
+ xmin = p.m_X;
+ }
+ if (p.m_Y > ymax) {
+ ymax = p.m_Y;
+ }
+ if (p.m_Y < ymin) {
+ ymin = p.m_Y;
+ }
+ }
+
+ double dx = kAlpha * (xmax - xmin);
+ double dy = kAlpha * (ymax - ymin);
+ m_Head = new Point(xmax + dx, ymin - dy, 0);
+ m_Tail = new Point(xmin - dx, ymin - dy, 0);
+
+ // Sort along y-axis
+ std::sort(m_Points.begin(), m_Points.end(), cmp);
+
+}
+
+void SweepContext::initEdges(std::vector<Point*> polyline)
+{
+ int numPoints = polyline.size();
+ for (int i = 0; i < numPoints; i++) {
+ int j = i < numPoints - 1 ? i + 1 : 0;
+
+ m_EdgeList.push_back(new Edge(*polyline[i], *polyline[j]));
+ }
+}
+
+Point* SweepContext::getPoint(const int& index)
+{
+ return m_Points[index];
+}
+
+void SweepContext::addToMap(TriangulationTriangle* triangle)
+{
+ m_Map.push_back(triangle);
+}
+
+Node& SweepContext::locateNode(Point& point)
+{
+ // TO DO implement search tree
+ return *m_Front->locateNode(point.m_X);
+}
+
+void SweepContext::createAdvancingFront()
+{
+ // Initial triangle
+ TriangulationTriangle* triangle = new TriangulationTriangle(*m_Points[0], *m_Tail,
+ *m_Head);
+
+ m_Map.push_back(triangle);
+
+ m_AfHead = new Node(*triangle->getPoint(1), *triangle);
+ m_AfMiddle = new Node(*triangle->getPoint(0), *triangle);
+ m_AfTail = new Node(*triangle->getPoint(2));
+ m_Front = new AdvancingFront(*m_AfHead, *m_AfTail);
+
+ m_AfHead->m_Next = m_AfMiddle;
+ m_AfMiddle->m_Next = m_AfTail;
+ m_AfMiddle->m_Prev = m_AfHead;
+ m_AfTail->m_Prev = m_AfMiddle;
+}
+
+void SweepContext::removeNode(Node* node)
+{
+ delete node;
+}
+
+void SweepContext::mapTriangleToNodes(TriangulationTriangle& t)
+{
+ for (int i = 0; i < 3; i++) {
+ if (!t.getNeighbor(i)) {
+ Node* n = m_Front->locatePoint(t.pointCW(*t.getPoint(i)));
+ if (n) {
+ n->m_Triangle = &t;
+ }
+ }
+ }
+}
+
+void SweepContext::removeFromMap(TriangulationTriangle* triangle)
+{
+ m_Map.remove(triangle);
+}
+
+void SweepContext::meshClean(TriangulationTriangle& triangle)
+{
+ if (&triangle != NULL && !triangle.isInterior()) {
+ triangle.isInterior(true);
+ m_Triangles.push_back(&triangle);
+ for (int i = 0; i < 3; i++) {
+ if (!triangle.m_ConstrainedEdge[i])
+ meshClean(*triangle.getNeighbor(i));
+ }
+ }
+}
+
+SweepContext::~SweepContext()
+{
+
+ delete m_Head;
+ delete m_Tail;
+ delete m_Front;
+ delete m_AfHead;
+ delete m_AfMiddle;
+ delete m_AfTail;
+
+ typedef std::list<TriangulationTriangle*> type_list;
+
+ for (type_list::iterator iter = m_Map.begin(); iter != m_Map.end(); ++iter) {
+ TriangulationTriangle* ptr = *iter;
+ delete ptr;
+ }
+
+ for (unsigned int i = 0; i < m_EdgeList.size(); i++) {
+ delete m_EdgeList[i];
+ }
+
+}
+
+}
diff --git a/src/base/triangulate/SweepContext.h b/src/base/triangulate/SweepContext.h
new file mode 100644
index 0000000..0b9e51d
--- /dev/null
+++ b/src/base/triangulate/SweepContext.h
@@ -0,0 +1,181 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+//
+// Based on Poly2Tri algorithm.
+// Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors
+// http://code.google.com/p/poly2tri/
+//
+
+#ifndef SWEEP_CONTEXT_H
+#define SWEEP_CONTEXT_H
+
+#include <list>
+#include <vector>
+#include <cstddef>
+
+namespace avg {
+
+// Inital triangle factor, seed triangle will extend 30% of
+// PointSet width to both left and right.
+const double kAlpha = 0.3;
+
+struct Point;
+class TriangulationTriangle;
+struct Node;
+struct Edge;
+class AdvancingFront;
+
+class SweepContext
+{
+
+public:
+
+ SweepContext(std::vector<Point*> polyline);
+
+ ~SweepContext();
+
+ void setHead(Point* p1);
+
+ Point* head();
+
+ void setTail(Point* p1);
+
+ Point* tail();
+
+ int pointCount();
+
+ Node& locateNode(Point& point);
+
+ void removeNode(Node* node);
+
+ void createAdvancingFront();
+
+/// Try to map a node to all sides of this triangle that don't have a neighbor
+ void mapTriangleToNodes(TriangulationTriangle& t);
+
+ void addToMap(TriangulationTriangle* triangle);
+
+ Point* getPoint(const int& index);
+
+ Point* GetPoints();
+
+ void removeFromMap(TriangulationTriangle* triangle);
+
+ void addHole(std::vector<Point*> polyline);
+
+ void addPoint(Point* point);
+
+ AdvancingFront* front();
+
+ void meshClean(TriangulationTriangle& triangle);
+
+ std::vector<TriangulationTriangle*>& getTriangles();
+
+ std::vector<Edge*> m_EdgeList;
+
+ struct Basin
+ {
+ Node* m_LeftNode;
+ Node* m_BottomNode;
+ Node* m_RightNode;
+ double m_Width;
+ bool m_LeftHighest;
+
+ Basin()
+ {
+ clear();
+ }
+
+ void clear() {
+ m_LeftNode = NULL;
+ m_BottomNode = NULL;
+ m_RightNode = NULL;
+ m_Width = 0.0;
+ m_LeftHighest = false;
+ }
+ };
+
+ struct EdgeEvent
+ {
+ Edge* m_ConstrainedEdge;
+ bool m_Right;
+
+ EdgeEvent() :
+ m_ConstrainedEdge(NULL), m_Right(false) {
+ }
+ };
+
+ Basin m_Basin;
+ EdgeEvent m_EdgeEvent;
+
+private:
+
+ friend class Sweep;
+
+ std::vector<TriangulationTriangle*> m_Triangles;
+ std::list<TriangulationTriangle*> m_Map;
+ std::vector<Point*> m_Points;
+
+ AdvancingFront* m_Front;
+ Point* m_Head;
+ Point* m_Tail;
+
+ Node *m_AfHead, *m_AfMiddle, *m_AfTail;
+
+ void initTriangulation();
+ void initEdges(std::vector<Point*> polyline);
+
+};
+
+inline AdvancingFront* SweepContext::front()
+{
+ return m_Front;
+}
+
+inline int SweepContext::pointCount()
+{
+ return m_Points.size();
+}
+
+inline void SweepContext::setHead(Point* p1)
+{
+ m_Head = p1;
+}
+
+inline Point* SweepContext::head()
+{
+ return m_Head;
+}
+
+inline void SweepContext::setTail(Point* p1)
+{
+ m_Tail = p1;
+}
+
+inline Point* SweepContext::tail()
+{
+ return m_Tail;
+}
+
+}
+
+#endif
diff --git a/src/base/triangulate/Triangulate.cpp b/src/base/triangulate/Triangulate.cpp
new file mode 100644
index 0000000..9206327
--- /dev/null
+++ b/src/base/triangulate/Triangulate.cpp
@@ -0,0 +1,90 @@
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+//
+// Based on Poly2Tri algorithm.
+// Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors
+// http://code.google.com/p/poly2tri/
+//
+
+#include "Triangulate.h"
+#include "Sweep.h"
+#include "SweepContext.h"
+
+#include "Shapes.h"
+
+using namespace std;
+
+namespace avg {
+
+void triangulatePolygon(std::vector<unsigned int>& dest, const Vec2Vector& points,
+ const std::vector<unsigned int>& holeIndexes)
+{
+ std::vector<Point*> polyline;
+ std::vector<Point*> holeLine;
+ unsigned int contourEnd;
+
+ if (holeIndexes.size() > 0) {
+ contourEnd = holeIndexes[0];
+ } else {
+ contourEnd = points.size();
+ }
+
+ for (unsigned int i = 0; i < contourEnd; i++) {
+ polyline.push_back(new Point(points[i].x, points[i].y, i));
+ }
+
+ SweepContext* sweepContext = new SweepContext(polyline);
+ Sweep* sweep = new Sweep;
+
+ if (holeIndexes.size() > 0) {
+ for (unsigned int i = 0; i < holeIndexes.size(); i++) {
+ if ( i < holeIndexes.size()-1) {
+ for (unsigned int j = holeIndexes[i]; j < points.size() && j <
+ holeIndexes[i+1]; j++)
+ {
+ holeLine.push_back(new Point(points[j].x, points[j].y, j));
+ }
+ } else {
+ for (unsigned int j = holeIndexes[i]; j < points.size(); j++) {
+ holeLine.push_back(new Point(points[j].x, points[j].y, j));
+ }
+ }
+ sweepContext->addHole(holeLine);
+ holeLine.clear();
+ }
+ }
+
+ sweep->Triangulate(*sweepContext);
+
+ std::vector<avg::TriangulationTriangle*>& triangles = sweepContext->getTriangles();
+ for (unsigned int i = 0; i < triangles.size(); ++i) {
+ dest.push_back(triangles[i]->getPoint(0)->m_Index);
+ dest.push_back(triangles[i]->getPoint(1)->m_Index);
+ dest.push_back(triangles[i]->getPoint(2)->m_Index);
+ }
+
+ delete sweep;
+ delete sweepContext;
+
+ for (unsigned int i = 0; i < polyline.size(); i++) {
+ delete polyline[i];
+ }
+}
+
+}
diff --git a/src/base/triangulate/Triangulate.h b/src/base/triangulate/Triangulate.h
new file mode 100644
index 0000000..af538a6
--- /dev/null
+++ b/src/base/triangulate/Triangulate.h
@@ -0,0 +1,33 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#ifndef TRIANGULATION_H_
+#define TRIANGULATION_H_
+
+#include "../GLMHelper.h"
+namespace avg {
+
+ void triangulatePolygon(std::vector<unsigned int>& dest, const Vec2Vector& points,
+ const std::vector<unsigned int>& holeIndexes = std::vector<unsigned int>());
+
+}
+
+#endif /* TRIANGULATION_H_ */
diff --git a/src/base/triangulate/Utils.h b/src/base/triangulate/Utils.h
new file mode 100644
index 0000000..5dd6685
--- /dev/null
+++ b/src/base/triangulate/Utils.h
@@ -0,0 +1,124 @@
+/*
+ * Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors
+ * http://code.google.com/p/poly2tri/
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * * Neither the name of Poly2Tri nor the names of its contributors may be
+ * used to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef UTILS_H
+#define UTILS_H
+
+// Otherwise #defines like M_PI are undeclared under Visual Studio
+#define _USE_MATH_DEFINES
+
+#include <exception>
+#include <math.h>
+
+namespace avg {
+
+const double PI_3div4 = 3 * M_PI / 4;
+const double EPSILON = 1e-12;
+
+enum Orientation
+{
+ CW, CCW, COLLINEAR
+};
+
+/**
+ * Forumla to calculate signed area<br>
+ * Positive if CCW<br>
+ * Negative if CW<br>
+ * 0 if collinear<br>
+ * <pre>
+ * A[P1,P2,P3] = (x1*y2 - y1*x2) + (x2*y3 - y2*x3) + (x3*y1 - y3*x1)
+ * = (x1-x3)*(y2-y3) - (y1-y3)*(x2-x3)
+ * </pre>
+ */
+Orientation orient2d(Point& pa, Point& pb, Point& pc)
+{
+ double detleft = (pa.m_X - pc.m_X) * (pb.m_Y - pc.m_Y);
+ double detright = (pa.m_Y - pc.m_Y) * (pb.m_X - pc.m_X);
+ double val = detleft - detright;
+ if (val > -EPSILON && val < EPSILON) {
+ return COLLINEAR;
+ } else if (val > 0) {
+ return CCW;
+ }
+ return CW;
+}
+
+/*
+ bool InScanArea(Point& pa, Point& pb, Point& pc, Point& pd)
+ {
+ double pdx = pd.x;
+ double pdy = pd.y;
+ double adx = pa.x - pdx;
+ double ady = pa.y - pdy;
+ double bdx = pb.x - pdx;
+ double bdy = pb.y - pdy;
+
+ double adxbdy = adx * bdy;
+ double bdxady = bdx * ady;
+ double oabd = adxbdy - bdxady;
+
+ if (oabd <= EPSILON) {
+ return false;
+ }
+
+ double cdx = pc.x - pdx;
+ double cdy = pc.y - pdy;
+
+ double cdxady = cdx * ady;
+ double adxcdy = adx * cdy;
+ double ocad = cdxady - adxcdy;
+
+ if (ocad <= EPSILON) {
+ return false;
+ }
+
+ return true;
+ }
+
+ */
+
+bool inScanArea(Point& pa, Point& pb, Point& pc, Point& pd)
+{
+ double oadb = (pa.m_X - pb.m_X) * (pd.m_Y - pb.m_Y) - (pd.m_X - pb.m_X) * (pa.m_Y - pb.m_Y);
+ if (oadb >= -EPSILON) {
+ return false;
+ }
+
+ double oadc = (pa.m_X - pc.m_X) * (pd.m_Y - pc.m_Y) - (pd.m_X - pc.m_X) * (pa.m_Y - pc.m_Y);
+ if (oadc <= EPSILON) {
+ return false;
+ }
+ return true;
+}
+
+}
+
+#endif