Преглед изворни кода

Refactor header usage to use our core submodule instead.

legacy
Sam Hocevar пре 5 година
родитељ
комит
9d4b7ff456
25 измењених фајлова са 80 додато и 3249 уклоњено
  1. +3
    -9
      .gitmodules
  2. +4
    -4
      doc/tutorial/11_fractal.cpp
  3. +0
    -0
      legacy/features.h
  4. +1
    -1
      lol-core
  5. +1
    -4
      src/3rdparty/Makefile.am
  6. +0
    -1
      src/3rdparty/mingw-std-threads
  7. +0
    -1
      src/3rdparty/pegtl
  8. +9
    -10
      src/Makefile.am
  9. +1
    -1
      src/gpu/shader.cpp
  10. +1
    -10
      src/lol-core.vcxproj
  11. +1
    -28
      src/lol-core.vcxproj.filters
  12. +2
    -1
      src/lol/base/all.h
  13. +0
    -46
      src/lol/base/string.h
  14. +0
    -430
      src/lol/math/polynomial.h
  15. +0
    -126
      src/lol/math/rand.h
  16. +0
    -368
      src/lol/math/real.h
  17. +0
    -3
      src/lol/sys/all.h
  18. +0
    -41
      src/lol/sys/getopt.h
  19. +0
    -222
      src/lol/sys/thread.h
  20. +0
    -1698
      src/math/real.cpp
  21. +2
    -0
      src/scene.h
  22. +0
    -198
      src/sys/getopt.cpp
  23. +5
    -5
      src/t/base/string.cpp
  24. +14
    -14
      src/t/math/polynomial.cpp
  25. +36
    -28
      src/t/math/quat.cpp

+ 3
- 9
.gitmodules Прегледај датотеку

@@ -2,13 +2,15 @@
[submodule "core"]
path = lol-core
url = ../../lolengine/lol.git
branch = core/master
branch = core

# A very large repository with Windows binaries
[submodule "external"]
path = external
url = ../../lolengine/ext-binaries.git
branch = master

# Some libraries we embed in the engine
[submodule "imgui"]
path = src/3rdparty/imgui
url = ../../lolengine/ext-imgui.git
@@ -21,14 +23,6 @@
path = src/3rdparty/lua
url = ../../lolengine/ext-lua.git
branch = lol
[submodule "pegtl"]
path = src/3rdparty/pegtl
url = ../../lolengine/ext-pegtl.git
branch = lol
[submodule "mingw-std-threads"]
path = src/3rdparty/mingw-std-threads
url = ../../lolengine/ext-mingw-std-threads.git
branch = master
[submodule "cpp-httplib"]
path = src/3rdparty/cpp-httplib
url = ../../lolengine/ext-cpp-httplib.git

+ 4
- 4
doc/tutorial/11_fractal.cpp Прегледај датотеку

@@ -99,7 +99,7 @@ public:
m_aabb.aa = m_position;
m_aabb.bb = vec3((vec2)m_window_size, 0);

if (has_threads())
if (thread::has_threads())
{
// Spawn worker threads and wait for their readiness
for (int i = 0; i < MAX_THREADS; i++)
@@ -111,7 +111,7 @@ public:

~Fractal()
{
if (has_threads())
if (thread::has_threads())
{
// Signal worker threads for completion and wait for them to quit
for (int i = 0; i < MAX_THREADS; i++)
@@ -291,7 +291,7 @@ public:

for (int i = 0; i < m_size.y; i += MAX_LINES * 2)
{
if (has_threads())
if (thread::has_threads())
m_jobqueue.push(i);
else
DoWork(i);
@@ -473,7 +473,7 @@ public:

if (m_dirty[m_frame])
{
if (has_threads())
if (thread::has_threads())
{
for (int i = 0; i < m_size.y; i += MAX_LINES * 2)
m_donequeue.pop();


src/lol/base/features.h → legacy/features.h Прегледај датотеку


+ 1
- 1
lol-core

@@ -1 +1 @@
Subproject commit 29336e3d2fcd112d6f66bc5d8569876ccb22b6ec
Subproject commit f30c17f180002170d3d25bcc133b6792175c8bb7

+ 1
- 4
src/3rdparty/Makefile.am Прегледај датотеку

@@ -13,13 +13,10 @@ liblol_lua_a_CPPFLAGS = $(AM_CPPFLAGS) -DLUA_ANSI $(disable_cflags_lua)

include lol-lua.am

EXTRA_DIST += $(imgui_sources) $(mingw_std_threads_sources) $(pegtl_sources) \
$(cpp_httplib_sources)
EXTRA_DIST += $(imgui_sources) $(cpp_httplib_sources)
EXTRA_DIST += lol-lua.vcxproj lol-lua.vcxproj.filters

include lol-cpp-httplib.am
include lol-mingw-std-threads.am
include lol-pegtl.am

# XXX: this is included by the parent Makefile instead
#include lol-imgui.am


+ 0
- 1
src/3rdparty/mingw-std-threads

@@ -1 +0,0 @@
Subproject commit 86ca7dc89659a556dcd1b6f954ed8f2799e23e2f

+ 0
- 1
src/3rdparty/pegtl

@@ -1 +0,0 @@
Subproject commit 5e9e1e8c2792293efced6998ae8e28ac46d93c03

+ 9
- 10
src/Makefile.am Прегледај датотеку

@@ -31,15 +31,15 @@ liblol_core_headers = \
lol/lua.h \
\
lol/base/all.h \
lol/base/avl_tree.h lol/base/features.h lol/base/tuple.h lol/base/types.h \
lol/base/array.h lol/base/assert.h lol/base/string.h lol/base/map.h \
lol/base/enum.h lol/base/log.h \
lol/base/avl_tree.h ../legacy/features.h lol/base/tuple.h lol/base/types.h \
lol/base/array.h lol/base/assert.h lol/base/map.h lol/base/enum.h \
lol/base/log.h \
\
lol/math/all.h \
lol/math/functions.h lol/math/vector.h lol/math/half.h lol/math/real.h \
lol/math/geometry.h lol/math/interp.h lol/math/rand.h lol/math/arraynd.h \
lol/math/functions.h lol/math/vector.h lol/math/half.h \
lol/math/geometry.h lol/math/interp.h lol/math/arraynd.h \
lol/math/constants.h lol/math/matrix.h lol/math/ops.h \
lol/math/transform.h lol/math/polynomial.h lol/math/bigint.h \
lol/math/transform.h lol/math/bigint.h \
lol/math/noise/gradient.h lol/math/noise/perlin.h \
lol/math/noise/simplex.h \
\
@@ -53,8 +53,7 @@ liblol_core_headers = \
lol/engine/tickable.h \
\
lol/sys/all.h \
lol/sys/init.h lol/sys/file.h lol/sys/getopt.h lol/sys/thread.h \
lol/sys/timer.h \
lol/sys/init.h lol/sys/file.h \
\
lol/image/all.h \
lol/image/pixel.h lol/image/color.h lol/image/image.h \
@@ -94,7 +93,7 @@ liblol_core_sources = \
base/assert.cpp base/features.cpp base/log.cpp base/string.cpp \
\
math/vector.cpp math/matrix.cpp math/transform.cpp math/half.cpp \
math/geometry.cpp math/real.cpp \
math/geometry.cpp \
\
gpu/shader.cpp gpu/indexbuffer.cpp gpu/vertexbuffer.cpp \
gpu/framebuffer.cpp gpu/texture.cpp gpu/renderer.cpp \
@@ -117,7 +116,7 @@ liblol_core_sources = \
mesh/mesh.cpp mesh/mesh.h \
mesh/primitivemesh.cpp mesh/primitivemesh.h \
\
sys/init.cpp sys/file.cpp sys/hacks.cpp sys/getopt.cpp \
sys/init.cpp sys/file.cpp sys/hacks.cpp \
\
image/resource.cpp image/resource-private.h \
image/image.cpp image/image-private.h image/kernel.cpp image/pixel.cpp \


+ 1
- 1
src/gpu/shader.cpp Прегледај датотеку

@@ -25,7 +25,7 @@
# undef WIN32_LEAN_AND_MEAN
#endif

#include "tao/pegtl.hpp"
#include <lol/base/pegtl.h>

#include "lolgl.h"



+ 1
- 10
src/lol-core.vcxproj Прегледај датотеку

@@ -178,7 +178,6 @@
<ClCompile Include="math\geometry.cpp" />
<ClCompile Include="math\half.cpp" />
<ClCompile Include="math\matrix.cpp" />
<ClCompile Include="math\real.cpp" />
<ClCompile Include="math\transform.cpp" />
<ClCompile Include="math\vector.cpp" />
<ClCompile Include="mesh\mesh.cpp" />
@@ -202,7 +201,6 @@
<ClCompile Include="scene.cpp" />
<ClCompile Include="sprite.cpp" />
<ClCompile Include="sys\file.cpp" />
<ClCompile Include="sys\getopt.cpp" />
<ClCompile Include="sys\hacks.cpp" />
<ClCompile Include="sys\init.cpp" />
<ClCompile Include="text.cpp" />
@@ -256,10 +254,9 @@
<ClInclude Include="lol\base\array.h" />
<ClInclude Include="lol\base\assert.h" />
<ClInclude Include="lol\base\enum.h" />
<ClInclude Include="lol\base\features.h" />
<ClInclude Include="..\legacy\features.h" />
<ClInclude Include="lol\base\log.h" />
<ClInclude Include="lol\base\map.h" />
<ClInclude Include="lol\base\string.h" />
<ClInclude Include="lol\base\types.h" />
<ClInclude Include="lol\base\tuple.h" />
<ClInclude Include="lol\debug\all.h" />
@@ -299,9 +296,6 @@
<ClInclude Include="lol\math\noise\perlin.h" />
<ClInclude Include="lol\math\noise\simplex.h" />
<ClInclude Include="lol\math\ops.h" />
<ClInclude Include="lol\math\polynomial.h" />
<ClInclude Include="lol\math\rand.h" />
<ClInclude Include="lol\math\real.h" />
<ClInclude Include="lol\math\transform.h" />
<ClInclude Include="lol\math\vector.h" />
<ClInclude Include="lol\net\all.h" />
@@ -309,10 +303,7 @@
<ClInclude Include="lol\public.h" />
<ClInclude Include="lol\sys\all.h" />
<ClInclude Include="lol\sys\file.h" />
<ClInclude Include="lol\sys\getopt.h" />
<ClInclude Include="lol\sys\init.h" />
<ClInclude Include="lol\sys\thread.h" />
<ClInclude Include="lol\sys\timer.h" />
<ClInclude Include="mesh\mesh.h" />
<ClInclude Include="mesh\primitivemesh.h" />
<ClInclude Include="messageservice.h" />


+ 1
- 28
src/lol-core.vcxproj.filters Прегледај датотеку

@@ -210,9 +210,6 @@
<ClCompile Include="math\matrix.cpp">
<Filter>math</Filter>
</ClCompile>
<ClCompile Include="math\real.cpp">
<Filter>math</Filter>
</ClCompile>
<ClCompile Include="math\transform.cpp">
<Filter>math</Filter>
</ClCompile>
@@ -236,9 +233,6 @@
<ClCompile Include="sys\file.cpp">
<Filter>sys</Filter>
</ClCompile>
<ClCompile Include="sys\getopt.cpp">
<Filter>sys</Filter>
</ClCompile>
<ClCompile Include="sys\hacks.cpp">
<Filter>sys</Filter>
</ClCompile>
@@ -356,7 +350,7 @@
<ClInclude Include="lol\base\enum.h">
<Filter>lol\base</Filter>
</ClInclude>
<ClInclude Include="lol\base\features.h">
<ClInclude Include="..\legacy\features.h">
<Filter>lol\base</Filter>
</ClInclude>
<ClInclude Include="lol\base\log.h">
@@ -365,9 +359,6 @@
<ClInclude Include="lol\base\map.h">
<Filter>lol\base</Filter>
</ClInclude>
<ClInclude Include="lol\base\string.h">
<Filter>lol\base</Filter>
</ClInclude>
<ClInclude Include="lol\base\types.h">
<Filter>lol\base</Filter>
</ClInclude>
@@ -482,15 +473,6 @@
<ClInclude Include="lol\math\ops.h">
<Filter>lol\math</Filter>
</ClInclude>
<ClInclude Include="lol\math\polynomial.h">
<Filter>lol\math</Filter>
</ClInclude>
<ClInclude Include="lol\math\rand.h">
<Filter>lol\math</Filter>
</ClInclude>
<ClInclude Include="lol\math\real.h">
<Filter>lol\math</Filter>
</ClInclude>
<ClInclude Include="lol\math\transform.h">
<Filter>lol\math</Filter>
</ClInclude>
@@ -512,18 +494,9 @@
<ClInclude Include="lol\sys\file.h">
<Filter>lol\sys</Filter>
</ClInclude>
<ClInclude Include="lol\sys\getopt.h">
<Filter>lol\sys</Filter>
</ClInclude>
<ClInclude Include="lol\sys\init.h">
<Filter>lol\sys</Filter>
</ClInclude>
<ClInclude Include="lol\sys\thread.h">
<Filter>lol\sys</Filter>
</ClInclude>
<ClInclude Include="lol\sys\timer.h">
<Filter>lol\sys</Filter>
</ClInclude>
<ClInclude Include="mesh\mesh.h">
<Filter>mesh</Filter>
</ClInclude>


+ 2
- 1
src/lol/base/all.h Прегледај датотеку

@@ -12,7 +12,8 @@

#pragma once

#include <lol/base/features.h>
#include <lol/../../legacy/features.h>

#include <lol/base/types.h>
#include <lol/base/log.h>
#include <lol/base/assert.h>


+ 0
- 46
src/lol/base/string.h Прегледај датотеку

@@ -1,46 +0,0 @@
//
// Lol Engine
//
// Copyright © 2010—2018 Sam Hocevar <sam@hocevar.net>
// © 2013—2015 Benjamin “Touky” Huet <huet.benjamin@gmail.com>
//
// Lol Engine is free software. It comes without any warranty, to
// the extent permitted by applicable law. You can redistribute it
// and/or modify it under the terms of the Do What the Fuck You Want
// to Public License, Version 2, as published by the WTFPL Task Force.
// See http://www.wtfpl.net/ for more details.
//

#pragma once

//
// The string tools
// ----------------
// Contains some utilities to work with std::string objects.
//

#include <string>

namespace lol
{

/* Split a string along a single separator */
array<std::string> split(std::string const &s, char sep = '\n');

/* Split a string along multiple separators */
array<std::string> split(std::string const &s, std::string const &seps);

/* Check whether a string starts or ends with a given substring */
bool starts_with(std::string const &s, std::string const &prefix);
bool ends_with(std::string const &s, std::string const &suffix);

/* Convert a string to lowercase or uppercase */
std::string tolower(std::string const &s);
std::string toupper(std::string const &s);

/* Format a string, printf-style */
std::string format(char const *format, ...) LOL_ATTR_FORMAT(1, 2);
std::string vformat(char const *format, va_list ap);

} /* namespace lol */


+ 0
- 430
src/lol/math/polynomial.h Прегледај датотеку

@@ -1,430 +0,0 @@
//
// Lol Engine
//
// Copyright: (c) 2010-2014 Sam Hocevar <sam@hocevar.net>
// This program is free software; you can redistribute it and/or
// modify it under the terms of the Do What The Fuck You Want To
// Public License, Version 2, as published by Sam Hocevar. See
// http://www.wtfpl.net/ for more details.
//

#pragma once

//
// The polynomial class
// --------------------
//
// The data structure is a simple dynamic array of scalars, with the
// added guarantee that the leading coefficient is always non-zero.
//

#include <functional>


namespace lol
{

template<typename T>
struct LOL_ATTR_NODISCARD polynomial
{
/* The zero polynomial */
explicit inline polynomial() {}

/* A constant polynomial */
explicit inline polynomial(T const &a)
{
m_coefficients.push(a);
reduce_degree();
}

/* Create a polynomial from a list of coefficients */
explicit polynomial(std::initializer_list<T> const &init)
{
for (auto a : init)
m_coefficients.push(a);

reduce_degree();
}

/* Factory for Chebyshev polynomials */
static polynomial<T> chebyshev(int n)
{
/* Use T0(x) = 1, T1(x) = x, Tn(x) = 2 x Tn-1(x) - Tn-2(x) */
std::function<int64_t (int, int)> coeff = [&](int i, int j)
{
if (i > j || i < 0 || ((j ^ i) & 1))
return (int64_t)0;
if (j < 2)
return (int64_t)1;
return 2 * coeff(i - 1, j - 1) - coeff(i, j - 2);
};

polynomial<T> ret;
for (int k = 0; k <= n; ++k)
ret.m_coefficients.push(T(coeff(k, n)));
return ret;
}

/* We define the zero polynomial (with no coefficients) as having
* degree -1 on purpose. */
inline int degree() const
{
return (int)m_coefficients.count() - 1;
}

/* Set one of the polynomial’s coefficients */
void set(int n, T const &a)
{
ASSERT(n >= 0);

if (n > degree() && !a)
return;

while (n > degree())
m_coefficients.push(T(0));

m_coefficients[n] = a;
reduce_degree();
}

/* Evaluate polynomial at a given value. This method can also
* be used to compose polynomials, i.e. using another polynomial
* as the value instead of a scalar. */
template<typename U> LOL_ATTR_NODISCARD U eval(U x) const
{
U ret(leading());
for (int i = degree() - 1; i >= 0; --i)
ret = ret * x + U(m_coefficients[i]);
return ret;
}

polynomial<T> derive() const
{
/* No need to reduce the degree after deriving. */
polynomial<T> ret;
for (int i = 1; i <= degree(); ++i)
ret.m_coefficients.push(m_coefficients[i] * T(i));
return ret;
}

array<T> roots() const
{
/* For now we can only solve polynomials of degrees 0, 1, 2 or 3. */
ASSERT(degree() >= 0 && degree() <= 3,
"roots() called on polynomial of degree %d", degree());

if (degree() == 0)
{
/* p(x) = a > 0 */
return array<T> {};
}
else if (degree() == 1)
{
/* p(x) = ax + b */
T const &a = m_coefficients[1];
T const &b = m_coefficients[0];
return array<T> { -b / a };
}
else if (degree() == 2)
{
/* p(x) = ax² + bx + c */
T const &a = m_coefficients[2];
T const &b = m_coefficients[1];
T const &c = m_coefficients[0];

T const k = b / (a + a);
T const delta = k * k - c / a;

if (delta < T(0))
{
return array<T> {};
}
else if (delta > T(0))
{
T const sqrt_delta = sqrt(delta);
return array<T> { -k - sqrt_delta, -k + sqrt_delta };
}
else
{
return array<T> { -k };
}
}
else if (degree() == 3)
{
static T const pi = acos(T(-1));

/* p(x) = ax³ + bx² + cx + d */
T const &a = m_coefficients[3];
T const &b = m_coefficients[2];
T const &c = m_coefficients[1];
T const &d = m_coefficients[0];

/* Find k, m, and n such that p(x - k) / a = x³ + mx + n
* q(x) = p(x - k) / a
* = x³ + (b/a-3k) x² + ((c-2bk)/a+3k²) x + (d-ck+bk²)/a-k³
*
* So we want k = b/3a and thus:
* q(x) = x³ + (c-bk)/a x + (d-ck+2bk²/3)/a
*
* k = b / 3a
* m = (c - bk) / a
* n = (d - ck + 2bk²/3) / a */
T const k = b / (T(3) * a);
T const m = (c - b * k) / a;
T const n = ((T(2) / T(3) * b * k - c) * k + d) / a;

/* Let x = u + v, such that 3uv = -m, then:
* q(u + v) = u³ + v³ + n
*
* We then need to solve the following system:
* u³v³ = -m³/27
* u³ + v³ = -n
*
* which gives :
* Δ = n² + 4m³/27
* u³ - v³ = √Δ
* u³ + v³ = -n
*
* u³,v³ = (-n ± √Δ) / 2
*/
T const delta = n * n + T(4) / T(27) * m * m * m;

/* Because 3uv = -m and m is not complex
* angle(u³) + angle(v³) must equal 0.
*
* This is why we compute u³ and v³ by norm and angle separately
* instead of using a std::complex class */
T u_norm, u3_angle;
T v_norm, v3_angle;

if (delta < 0)
{
v_norm = u_norm = sqrt(m / T(-3));

u3_angle = atan2(sqrt(-delta), -n);
v3_angle = -u3_angle;
}
else
{
T const sqrt_delta = sqrt(delta);

u_norm = cbrt(abs(n - sqrt_delta) / T(2));
v_norm = cbrt(abs(n + sqrt_delta) / T(2));

u3_angle = (n >= sqrt_delta) ? pi : 0;
v3_angle = (n <= -sqrt_delta) ? 0 : -pi;
}

T solutions[3];

for (int i : { 0, 1, 2 })
{
T u_angle = (u3_angle + T(2 * i) * pi) / T(3);
T v_angle = (v3_angle - T(2 * i) * pi) / T(3);

solutions[i] = u_norm * cos(u_angle) + v_norm * cos(v_angle);
}

if (a == d && b == c && b == T(3)*a) // triple solution
{
return array<T> { solutions[0] - k };
}

// if root of the derivative is also root of the current polynomial, we have a double root.
for (auto root : (polynomial<T>{ c, T(2) * b, T(3) * a }).roots())
{
if (eval(root) == T(0))
return array<T> { (solutions[0] + solutions[2]) / T(2) - k,
solutions[1] - k };
}

// we have 3 or 1 root depending on delta sign
if (delta > 0)
{
return array<T> { solutions[0] - k };
}
else // if (delta < 0) 3 real solutions
{
return array<T> { solutions[0] - k,
solutions[1] - k,
solutions[2] - k };
}
}

/* It is an error to reach this point. */
ASSERT(false);
return array<T> {};
}

/* Access individual coefficients. This is read-only and returns a
* copy because we cannot let the user mess with the integrity of
* the structure (i.e. the guarantee that the leading coefficient
* remains non-zero). */
LOL_ATTR_NODISCARD inline T operator[](ptrdiff_t n) const
{
if (n < 0 || n > degree())
return T(0);

return m_coefficients[n];
}

/* Return the leading coefficient */
LOL_ATTR_NODISCARD inline T leading() const
{
return (*this)[degree()];
}

/* Boolean operations */
bool operator !() const
{
return degree() < 0;
}

operator bool() const
{
return !!*this;
}

/* Unary plus */
polynomial<T> operator +() const
{
return *this;
}

/* Unary minus */
polynomial<T> operator -() const
{
polynomial<T> ret;
for (auto a : m_coefficients)
ret.m_coefficients.push(-a);
return ret;
}

/* Add two polynomials */
polynomial<T> &operator +=(polynomial<T> const &p)
{
int min_degree = lol::min(p.degree(), degree());

for (int i = 0; i <= min_degree; ++i)
m_coefficients[i] += p[i];

for (int i = min_degree + 1; i <= p.degree(); ++i)
m_coefficients.push(p[i]);

reduce_degree();
return *this;
}

polynomial<T> operator +(polynomial<T> const &p) const
{
return polynomial<T>(*this) += p;
}

/* Subtract two polynomials */
polynomial<T> &operator -=(polynomial<T> const &p)
{
return *this += -p;
}

polynomial<T> operator -(polynomial<T> const &p) const
{
return polynomial<T>(*this) += -p;
}

/* Multiply polynomial by a scalar */
polynomial<T> &operator *=(T const &k)
{
for (auto &a : m_coefficients)
a *= k;
reduce_degree();
return *this;
}

polynomial<T> operator *(T const &k) const
{
return polynomial<T>(*this) *= k;
}

/* Divide polynomial by a scalar */
polynomial<T> &operator /=(T const &k)
{
return *this *= (T(1) / k);
}

polynomial<T> operator /(T const &k) const
{
return *this * (T(1) / k);
}

/* Multiply polynomial by another polynomial */
polynomial<T> &operator *=(polynomial<T> const &p)
{
return *this = *this * p;
}

polynomial<T> operator *(polynomial<T> const &p) const
{
polynomial<T> ret;
polynomial<T> const &q = *this;

if (p.degree() >= 0 && q.degree() >= 0)
{
int n = p.degree() + q.degree();
for (int i = 0; i <= n; ++i)
ret.m_coefficients.push(T(0));

for (int i = 0; i <= p.degree(); ++i)
for (int j = 0; j <= q.degree(); ++j)
ret.m_coefficients[i + j] += p[i] * q[j];

ret.reduce_degree();
}

return ret;
}

/* Divide a polynomial by another one. There is no /= variant because
* the return value contains both the quotient and the remainder. */
tuple<polynomial<T>, polynomial<T>> operator /(polynomial<T> p) const
{
ASSERT(p.degree() >= 0);

tuple<polynomial<T>, polynomial<T>> ret;
polynomial<T> &quotient = ret.m1;
polynomial<T> &remainder = ret.m2;

remainder = *this / p.leading();
p /= p.leading();

for (int n = remainder.degree() - p.degree(); n >= 0; --n)
{
quotient.set(n, remainder.leading());
for (int i = 0; i < p.degree(); ++i)
remainder.m_coefficients[n + i] -= remainder.leading() * p[i];
(void)remainder.m_coefficients.pop();
}

return ret;
}

private:
/* Enforce the non-zero leading coefficient rule. */
void reduce_degree()
{
while (m_coefficients.count() && !m_coefficients.last())
(void)m_coefficients.pop();
}

/* The polynomial coefficients */
array<T> m_coefficients;
};

template<typename T>
polynomial<T> operator *(T const &k, polynomial<T> const &p)
{
/* We assume k * p is the same as p * k */
return p * k;
}

} /* namespace lol */


+ 0
- 126
src/lol/math/rand.h Прегледај датотеку

@@ -1,126 +0,0 @@
//
// Lol Engine
//
// Copyright: (c) 2010-2013 Sam Hocevar <sam@hocevar.net>
// This program is free software; you can redistribute it and/or
// modify it under the terms of the Do What The Fuck You Want To
// Public License, Version 2, as published by Sam Hocevar. See
// http://www.wtfpl.net/ for more details.
//

#pragma once

//
// The Random number generators
// ----------------------------
//

#include <cstdlib>
#include <stdint.h>

namespace lol
{

/* Random number generators */
template<typename T> LOL_ATTR_NODISCARD static inline T rand();
template<typename T> LOL_ATTR_NODISCARD static inline T rand(T a);
template<typename T> LOL_ATTR_NODISCARD static inline T rand(T a, T b);

/* One-value random number generators */
template<typename T> LOL_ATTR_NODISCARD static inline T rand(T a)
{
return a ? rand<T>() % a : T(0);
}

template<> LOL_ATTR_NODISCARD inline half rand<half>(half a)
{
float f = (float)std::rand() / (float)RAND_MAX;
return (half)(a * f);
}

template<> LOL_ATTR_NODISCARD inline float rand<float>(float a)
{
float f = (float)std::rand() / (float)RAND_MAX;
return a * f;
}

template<> LOL_ATTR_NODISCARD inline double rand<double>(double a)
{
double f = (double)std::rand() / (double)RAND_MAX;
return a * f;
}

template<> LOL_ATTR_NODISCARD inline ldouble rand<ldouble>(ldouble a)
{
ldouble f = (ldouble)std::rand() / (ldouble)RAND_MAX;
return a * f;
}

/* Two-value random number generator -- no need for specialisation */
template<typename T> LOL_ATTR_NODISCARD static inline T rand(T a, T b)
{
return a + rand<T>(b - a);
}

/* Default random number generator */
template<typename T> LOL_ATTR_NODISCARD static inline T rand()
{
switch (sizeof(T))
{
case 1:
return static_cast<T>(std::rand() & 0x7f);
case 2:
{
uint16_t ret = std::rand();
if (RAND_MAX < 0x7fff)
ret = (ret << 7) ^ std::rand();
return static_cast<T>(ret & 0x7fffu);
}
case 4:
{
uint32_t ret = std::rand();
if (RAND_MAX >= 0xffff)
ret = (ret << 16) ^ std::rand();
else
{
ret = (ret << 8) ^ std::rand();
ret = (ret << 8) ^ std::rand();
ret = (ret << 8) ^ std::rand();
}
return static_cast<T>(ret & 0x7fffffffu);
}
case 8:
{
uint64_t ret = std::rand();
if (RAND_MAX >= 0xffff)
{
ret = (ret << 16) ^ std::rand();
ret = (ret << 16) ^ std::rand();
ret = (ret << 16) ^ std::rand();
}
else
{
ret = (ret << 8) ^ std::rand();
ret = (ret << 8) ^ std::rand();
ret = (ret << 8) ^ std::rand();
ret = (ret << 8) ^ std::rand();
ret = (ret << 8) ^ std::rand();
ret = (ret << 8) ^ std::rand();
ret = (ret << 8) ^ std::rand();
}
return static_cast<T>(ret & (~(uint64_t)0 >> 1));
}
default:
ASSERT(false, "rand() doesn’t support types of size %d\n",
(int)sizeof(T));
return 0;
}
}

template<> LOL_ATTR_NODISCARD inline half rand<half>() { return rand<half>(1.f); }
template<> LOL_ATTR_NODISCARD inline float rand<float>() { return rand<float>(1.f); }
template<> LOL_ATTR_NODISCARD inline double rand<double>() { return rand<double>(1.0); }
template<> LOL_ATTR_NODISCARD inline ldouble rand<ldouble>() { return rand<ldouble>(1.0); }

} /* namespace lol */


+ 0
- 368
src/lol/math/real.h Прегледај датотеку

@@ -1,368 +0,0 @@
//
// Lol Engine
//
// Copyright © 2010—2019 Sam Hocevar <sam@hocevar.net>
//
// Lol Engine is free software. It comes without any warranty, to
// the extent permitted by applicable law. You can redistribute it
// and/or modify it under the terms of the Do What the Fuck You Want
// to Public License, Version 2, as published by the WTFPL Task Force.
// See http://www.wtfpl.net/ for more details.
//

#pragma once

//
// The Real class
// --------------
//

#include <lol/base/types.h>

#include <vector>
#include <string>
#include <cstdint>

namespace lol
{

/* This is OUR namespace. Don't let Windows headers mess with it. */
#undef min
#undef max

/*
* The base class for reals. The only real reason for making this a template
* class is so we can have implicit constructors ("real x = 1" works) but
* avoid accidental implicit conversions ("int x = 1; sqrt(x)" will never
* call real::sqrt).
*/
template<typename T>
class LOL_ATTR_NODISCARD Real
{
public:
typedef T bigit_t;
typedef int64_t exponent_t;

Real() = default;

Real(float f);
Real(double f);
Real(long double f);
Real(int32_t i);
Real(uint32_t i);
Real(int64_t i);
Real(uint64_t i);

Real(char const *str);

LOL_ATTR_NODISCARD bool is_zero() const { return m_mantissa.size() == 0; }
LOL_ATTR_NODISCARD bool is_negative() const { return m_sign; }
LOL_ATTR_NODISCARD bool is_nan() const { return m_nan; }
LOL_ATTR_NODISCARD bool is_inf() const { return m_inf; }

LOL_ATTR_NODISCARD operator float() const;
LOL_ATTR_NODISCARD operator double() const;
LOL_ATTR_NODISCARD operator long double() const;
LOL_ATTR_NODISCARD operator int32_t() const;
LOL_ATTR_NODISCARD operator uint32_t() const;
LOL_ATTR_NODISCARD operator int64_t() const;
LOL_ATTR_NODISCARD operator uint64_t() const;

Real<T> operator +() const;
Real<T> operator -() const;
Real<T> operator +(Real<T> const &x) const;
Real<T> operator -(Real<T> const &x) const;
Real<T> operator *(Real<T> const &x) const;
Real<T> operator /(Real<T> const &x) const;
Real<T> const &operator +=(Real<T> const &x);
Real<T> const &operator -=(Real<T> const &x);
Real<T> const &operator *=(Real<T> const &x);
Real<T> const &operator /=(Real<T> const &x);

LOL_ATTR_NODISCARD bool operator ==(Real<T> const &x) const;
LOL_ATTR_NODISCARD bool operator !=(Real<T> const &x) const;
LOL_ATTR_NODISCARD bool operator <(Real<T> const &x) const;
LOL_ATTR_NODISCARD bool operator >(Real<T> const &x) const;
LOL_ATTR_NODISCARD bool operator <=(Real<T> const &x) const;
LOL_ATTR_NODISCARD bool operator >=(Real<T> const &x) const;

LOL_ATTR_NODISCARD bool operator !() const;
LOL_ATTR_NODISCARD operator bool() const;

/* Comparison functions */
template<typename U> friend Real<U> min(Real<U> const &a, Real<U> const &b);
template<typename U> friend Real<U> max(Real<U> const &a, Real<U> const &b);
template<typename U> friend Real<U> clamp(Real<U> const &x,
Real<U> const &a, Real<U> const &b);

/* Trigonometric functions */
template<typename U> friend Real<U> sin(Real<U> const &x);
template<typename U> friend Real<U> cos(Real<U> const &x);
template<typename U> friend Real<U> tan(Real<U> const &x);
template<typename U> friend Real<U> asin(Real<U> const &x);
template<typename U> friend Real<U> acos(Real<U> const &x);
template<typename U> friend Real<U> atan(Real<U> const &x);
template<typename U> friend Real<U> atan2(Real<U> const &y, Real<U> const &x);

/* Hyperbolic functions */
template<typename U> friend Real<U> sinh(Real<U> const &x);
template<typename U> friend Real<U> cosh(Real<U> const &x);
template<typename U> friend Real<U> tanh(Real<U> const &x);

/* Exponential and logarithmic functions */
template<typename U> friend Real<U> exp(Real<U> const &x);
template<typename U> friend Real<U> exp2(Real<U> const &x);
template<typename U> friend Real<U> erf(Real<U> const &x);
template<typename U> friend Real<U> log(Real<U> const &x);
template<typename U> friend Real<U> log2(Real<U> const &x);
template<typename U> friend Real<U> log10(Real<U> const &x);

/* Floating-point functions */
template<typename U> friend Real<U> frexp(Real<U> const &x, typename Real<U>::exponent_t *exp);
template<typename U> friend Real<U> ldexp(Real<U> const &x, typename Real<U>::exponent_t exp);
template<typename U> friend Real<U> modf(Real<U> const &x, Real<U> *iptr);
template<typename U> friend Real<U> nextafter(Real<U> const &x, Real<U> const &y);

/* Power functions */
template<typename U> friend Real<U> inverse(Real<U> const &x);
template<typename U> friend Real<U> sqrt(Real<U> const &x);
template<typename U> friend Real<U> cbrt(Real<U> const &x);
template<typename U> friend Real<U> pow(Real<U> const &x, Real<U> const &y);
template<typename U> friend Real<U> gamma(Real<U> const &x);

/* Rounding, absolute value, remainder etc. */
template<typename U> friend Real<U> ceil(Real<U> const &x);
template<typename U> friend Real<U> copysign(Real<U> const &x, Real<U> const &y);
template<typename U> friend Real<U> floor(Real<U> const &x);
template<typename U> friend Real<U> fabs(Real<U> const &x);
template<typename U> friend Real<U> round(Real<U> const &x);
template<typename U> friend Real<U> fmod(Real<U> const &x, Real<U> const &y);

/* Functions inherited from GLSL */
template<typename U> friend Real<U> abs(Real<U> const &x);
template<typename U> friend Real<U> fract(Real<U> const &x);
template<typename U> friend Real<U> degrees(Real<U> const &x);
template<typename U> friend Real<U> radians(Real<U> const &x);

/* Additional functions */
template<typename U> friend Real<U> franke(Real<U> const &x, Real<U> const &y);
template<typename U> friend Real<U> peaks(Real<U> const &x, Real<U> const &y);

std::string str(int ndigits = 150) const;
std::string xstr() const;

/* Additional operators using base C++ types */
#define __LOL_REAL_OP_HELPER_GENERIC(op, type) \
inline Real<T> operator op(type x) const { return *this op (Real<T>)x; } \
inline Real<T> const &operator op##=(type x) { return *this = (*this op x); }
#define __LOL_REAL_OP_HELPER_FASTMULDIV(op, type) \
inline Real<T> operator op(type x) const \
{ \
Real<T> tmp = *this; return tmp op##= x; \
} \
inline Real<T> const &operator op##=(type x) \
{ \
/* If multiplying or dividing by a power of two, take a shortcut */ \
if (!is_zero() && x && !(x & (x - 1))) \
{ \
while (x >>= 1) \
m_exponent += 1 op 2 - 1; /* 1 if op is *, -1 if op is / */ \
} \
else \
*this = *this op (Real<T>)x; \
return *this; \
}
#define __LOL_REAL_OP_HELPER_INT(type) \
__LOL_REAL_OP_HELPER_GENERIC(+, type) \
__LOL_REAL_OP_HELPER_GENERIC(-, type) \
__LOL_REAL_OP_HELPER_FASTMULDIV(*, type) \
__LOL_REAL_OP_HELPER_FASTMULDIV(/, type)
#define __LOL_REAL_OP_HELPER_FLOAT(type) \
__LOL_REAL_OP_HELPER_GENERIC(+, type) \
__LOL_REAL_OP_HELPER_GENERIC(-, type) \
__LOL_REAL_OP_HELPER_GENERIC(*, type) \
__LOL_REAL_OP_HELPER_GENERIC(/, type)

__LOL_REAL_OP_HELPER_INT(int)
__LOL_REAL_OP_HELPER_INT(unsigned int)
__LOL_REAL_OP_HELPER_INT(int64_t)
__LOL_REAL_OP_HELPER_INT(uint64_t)
__LOL_REAL_OP_HELPER_FLOAT(float)
__LOL_REAL_OP_HELPER_FLOAT(double)
__LOL_REAL_OP_HELPER_FLOAT(long double)

/* Constants */
static Real<T> const R_0();
static Real<T> const& R_1();
static Real<T> const& R_2();
static Real<T> const& R_3();
static Real<T> const& R_4();
static Real<T> const& R_10();

static Real<T> const& R_E();
static Real<T> const& R_LOG2E();
static Real<T> const& R_LOG10E();
static Real<T> const& R_LN2();
static Real<T> const& R_LN10();
static Real<T> const& R_PI();
static Real<T> const& R_PI_2();
static Real<T> const& R_PI_3();
static Real<T> const& R_PI_4();
static Real<T> const& R_TAU();
static Real<T> const& R_1_PI();
static Real<T> const& R_2_PI();
static Real<T> const& R_2_SQRTPI();
static Real<T> const& R_SQRT2();
static Real<T> const& R_SQRT3();
static Real<T> const& R_SQRT1_2();

static Real<T> const R_INF();
static Real<T> const R_NAN();

static Real<T> const& R_MIN();
static Real<T> const& R_MAX();

private:
std::vector<T> m_mantissa;
exponent_t m_exponent = 0;
bool m_sign = false, m_nan = false, m_inf = false;

public:
static int DEFAULT_BIGIT_COUNT;

static inline int bigit_bits() { return 8 * (int)sizeof(bigit_t); }
inline int bigit_count() const { return (int)m_mantissa.size(); }
inline int total_bits() const { return bigit_count() * bigit_bits(); }
};

template<typename U>
std::ostream& operator <<(std::ostream &s, Real<U> const &x);

/*
* Mandatory forward declarations of template specialisations
*/
template<> real::Real(float f);
template<> real::Real(double f);
template<> real::Real(long double f);
template<> real::Real(int32_t i);
template<> real::Real(uint32_t i);
template<> real::Real(int64_t i);
template<> real::Real(uint64_t i);
template<> real::Real(char const *str);

template<> LOL_ATTR_NODISCARD real::operator float() const;
template<> LOL_ATTR_NODISCARD real::operator double() const;
template<> LOL_ATTR_NODISCARD real::operator long double() const;
template<> LOL_ATTR_NODISCARD real::operator int32_t() const;
template<> LOL_ATTR_NODISCARD real::operator uint32_t() const;
template<> LOL_ATTR_NODISCARD real::operator int64_t() const;
template<> LOL_ATTR_NODISCARD real::operator uint64_t() const;
template<> real real::operator +() const;
template<> real real::operator -() const;
template<> real real::operator +(real const &x) const;
template<> real real::operator -(real const &x) const;
template<> real real::operator *(real const &x) const;
template<> real real::operator /(real const &x) const;
template<> real const &real::operator +=(real const &x);
template<> real const &real::operator -=(real const &x);
template<> real const &real::operator *=(real const &x);
template<> real const &real::operator /=(real const &x);
template<> LOL_ATTR_NODISCARD bool real::operator ==(real const &x) const;
template<> LOL_ATTR_NODISCARD bool real::operator !=(real const &x) const;
template<> LOL_ATTR_NODISCARD bool real::operator <(real const &x) const;
template<> LOL_ATTR_NODISCARD bool real::operator >(real const &x) const;
template<> LOL_ATTR_NODISCARD bool real::operator <=(real const &x) const;
template<> LOL_ATTR_NODISCARD bool real::operator >=(real const &x) const;
template<> LOL_ATTR_NODISCARD bool real::operator !() const;
template<> LOL_ATTR_NODISCARD real::operator bool() const;

template<typename U> Real<U> min(Real<U> const &a, Real<U> const &b);
template<typename U> Real<U> max(Real<U> const &a, Real<U> const &b);
template<typename U> Real<U> clamp(Real<U> const &x,
Real<U> const &a, Real<U> const &b);

template<typename U> Real<U> sin(Real<U> const &x);
template<typename U> Real<U> cos(Real<U> const &x);
template<typename U> Real<U> tan(Real<U> const &x);
template<typename U> Real<U> asin(Real<U> const &x);
template<typename U> Real<U> acos(Real<U> const &x);
template<typename U> Real<U> atan(Real<U> const &x);
template<typename U> Real<U> atan2(Real<U> const &y, Real<U> const &x);
template<typename U> Real<U> sinh(Real<U> const &x);
template<typename U> Real<U> cosh(Real<U> const &x);
template<typename U> Real<U> tanh(Real<U> const &x);
template<typename U> Real<U> exp(Real<U> const &x);
template<typename U> Real<U> exp2(Real<U> const &x);
template<typename U> Real<U> erf(Real<U> const &x);
template<typename U> Real<U> log(Real<U> const &x);
template<typename U> Real<U> log2(Real<U> const &x);
template<typename U> Real<U> log10(Real<U> const &x);
template<typename U> Real<U> frexp(Real<U> const &x, typename Real<U>::exponent_t *exp);
template<typename U> Real<U> ldexp(Real<U> const &x, typename Real<U>::exponent_t exp);
template<typename U> Real<U> modf(Real<U> const &x, Real<U> *iptr);
template<typename U> Real<U> nextafter(Real<U> const &x, Real<U> const &y);
template<typename U> Real<U> inverse(Real<U> const &x);
template<typename U> Real<U> sqrt(Real<U> const &x);
template<typename U> Real<U> cbrt(Real<U> const &x);
template<typename U> Real<U> pow(Real<U> const &x, Real<U> const &y);
template<typename U> Real<U> gamma(Real<U> const &x);
template<typename U> Real<U> ceil(Real<U> const &x);
template<typename U> Real<U> copysign(Real<U> const &x, Real<U> const &y);
template<typename U> Real<U> floor(Real<U> const &x);
template<typename U> Real<U> fabs(Real<U> const &x);
template<typename U> Real<U> round(Real<U> const &x);
template<typename U> Real<U> fmod(Real<U> const &x, Real<U> const &y);
template<typename U> Real<U> abs(Real<U> const &x);
template<typename U> Real<U> fract(Real<U> const &x);
template<typename U> Real<U> degrees(Real<U> const &x);
template<typename U> Real<U> radians(Real<U> const &x);
template<typename U> Real<U> franke(Real<U> const &x, Real<U> const &y);
template<typename U> Real<U> peaks(Real<U> const &x, Real<U> const &y);

template<> real min(real const &a, real const &b);
template<> real max(real const &a, real const &b);
template<> real clamp(real const &x, real const &a, real const &b);

template<> real sin(real const &x);
template<> real cos(real const &x);
template<> real tan(real const &x);
template<> real asin(real const &x);
template<> real acos(real const &x);
template<> real atan(real const &x);
template<> real atan2(real const &y, real const &x);
template<> real sinh(real const &x);
template<> real cosh(real const &x);
template<> real tanh(real const &x);
template<> real exp(real const &x);
template<> real exp2(real const &x);
template<> real erf(real const &x);
template<> real log(real const &x);
template<> real log2(real const &x);
template<> real log10(real const &x);
template<> real frexp(real const &x, real::exponent_t *exp);
template<> real ldexp(real const &x, real::exponent_t exp);
template<> real modf(real const &x, real *iptr);
template<> real nextafter(real const &x, real const &y);
template<> real inverse(real const &x);
template<> real sqrt(real const &x);
template<> real cbrt(real const &x);
template<> real pow(real const &x, real const &y);
template<> real gamma(real const &x);
template<> real ceil(real const &x);
template<> real copysign(real const &x, real const &y);
template<> real floor(real const &x);
template<> real fabs(real const &x);
template<> real round(real const &x);
template<> real fmod(real const &x, real const &y);
template<> real abs(real const &x);
template<> real fract(real const &x);
template<> real degrees(real const &x);
template<> real radians(real const &x);
template<> real franke(real const &x, real const &y);
template<> real peaks(real const &x, real const &y);

template<> std::string real::str(int ndigits) const;
template<> std::string real::xstr() const;

} /* namespace lol */


+ 0
- 3
src/lol/sys/all.h Прегледај датотеку

@@ -12,9 +12,6 @@

#pragma once

#include <lol/sys/thread.h>
#include <lol/sys/timer.h> /* requires thread.h */
#include <lol/sys/getopt.h>
#include <lol/sys/init.h>
#include <lol/sys/file.h>


+ 0
- 41
src/lol/sys/getopt.h Прегледај датотеку

@@ -1,41 +0,0 @@
//
// Lol Engine
//
// Copyright © 2002—2016 Sam Hocevar <sam@hocevar.net>
//
// Lol Engine is free software. It comes without any warranty, to
// the extent permitted by applicable law. You can redistribute it
// and/or modify it under the terms of the Do What the Fuck You Want
// to Public License, Version 2, as published by the WTFPL Task Force.
// See http://www.wtfpl.net/ for more details.
//

#pragma once

//
// The getopt functions
// --------------------
//

namespace lol
{

class getopt
{
public:
getopt(int argc, char ** _argv);
getopt(int argc, char * const * _argv);
~getopt();

void add_opt(int short_opt, char const *long_opt, bool has_arg);
int parse();

int index;
char *arg;

private:
std::unique_ptr<struct getopt_private> m_private;
};

}


+ 0
- 222
src/lol/sys/thread.h Прегледај датотеку

@@ -1,222 +0,0 @@
//
// Lol Engine
//
// Copyright © 2010—2019 Sam Hocevar <sam@hocevar.net>
//
// Lol Engine is free software. It comes without any warranty, to
// the extent permitted by applicable law. You can redistribute it
// and/or modify it under the terms of the Do What the Fuck You Want
// to Public License, Version 2, as published by the WTFPL Task Force.
// See http://www.wtfpl.net/ for more details.
//

#pragma once

//
// The Threading classes
// ---------------------
//

#include <functional>

#include <thread>
#include <mutex>
#include <condition_variable>

/* XXX: workaround for a bug in Visual Studio 2012 and 2013!
* https://connect.microsoft.com/VisualStudio/feedback/details/747145 */
#if defined(_MSC_VER) && (_MSC_VER < 1900)
# define LOL_VISUAL_STUDIO_BUG_747145_WORKAROUND 1
# ifdef WIN32_LEAN_AND_MEAN
# include <windows.h>
# else
# define WIN32_LEAN_AND_MEAN 1
# include <windows.h>
# undef WIN32_LEAN_AND_MEAN
# endif
#endif

/* XXX: workaround for missing std::thread in mingw */
#if _GLIBCXX_MUTEX && !_GLIBCXX_HAS_GTHREADS && _WIN32
# include "mingw.thread.h"
# include "mingw.mutex.h"
# include "mingw.condition_variable.h"
# undef near /* Fuck Microsoft */
# undef far /* Fuck Microsoft again */
#endif

namespace lol
{

// This is like std::mutex but we can add debug information to it
class mutex
{
public:
inline void lock() { m_mutex.lock(); }

inline bool try_lock() { return m_mutex.try_lock(); }

inline void unlock() { m_mutex.unlock(); }

private:
std::mutex m_mutex;
};

// A FIFO queue for threads
template<typename T, int N = 128>
class queue
{
public:
int size() const { return m_count; }

// Will block the thread if another has already locked
void push(T value)
{
std::unique_lock<std::mutex> uni_lock(m_mutex);

if (has_threads())
{
// Wait for the mutex availability or non-fullness
m_full_cond.wait(uni_lock, [&]{ return m_count < CAPACITY; });
}

do_push(value); /* Push value */

if (has_threads())
{
// Release lock and notify empty condition var (in that order)
uni_lock.unlock();
m_empty_cond.notify_one();
}
}

// Will not block if another has already locked
bool try_push(T value)
{
std::unique_lock<std::mutex> uni_lock(m_mutex, std::defer_lock);

if (has_threads())
{
// Try to lock, bail out if we fail
if (!uni_lock.try_lock())
return false;
}

if (m_count == CAPACITY)
return false; // unlocks uni_lock

do_push(value);

if (has_threads())
{
// Release lock and notify empty condition var (in that order)
uni_lock.unlock();
m_empty_cond.notify_one();
}

return true;
}

// Will block the thread if another has already locked
T pop()
{
ASSERT(has_threads(), "Pop should only be used with threads. Use try_pop instead.");

// Wait for the mutex availability or non-emptiness
std::unique_lock<std::mutex> uni_lock(m_mutex);
m_empty_cond.wait(uni_lock, [&]{return m_count > 0; });

T ret = do_pop();

// Release lock and notify full condition var (in that order)
uni_lock.unlock();
m_full_cond.notify_one();

return ret;
}

// Will not block if another has already locked
bool try_pop(T &ret)
{
std::unique_lock<std::mutex> uni_lock(m_mutex, std::defer_lock);

if (has_threads())
{
if (!uni_lock.try_lock())
return false;
}

if (m_count == 0)
return false;

ret = do_pop(); /* Pop value */

if (has_threads())
{
// Release lock and notify full condition var (in that order)
uni_lock.unlock();
m_full_cond.notify_one();
}

return true;
}

// Inner methods for actual update
private:
void do_push(T &value)
{
m_values[(m_start + m_count) % CAPACITY] = value;
m_count++;
}

T& do_pop()
{
int idx = m_start;
m_start = (m_start + 1) % CAPACITY;
m_count--;
return m_values[idx];
}

private:
static int const CAPACITY = N;
T m_values[CAPACITY];
int m_start = 0, m_count = 0;

std::mutex m_mutex;
std::condition_variable m_empty_cond, m_full_cond;
};

// Base class for threads
class thread
{
public:
thread(std::function<void(thread*)> fn)
: m_function(fn)
{
m_thread = std::thread(trampoline, this);
}

~thread()
{
#if LOL_VISUAL_STUDIO_BUG_747145_WORKAROUND
m_thread.detach();
#else
m_thread.join();
#endif
}

private:
static void trampoline(thread *that)
{
that->m_function(that);
#if LOL_VISUAL_STUDIO_BUG_747145_WORKAROUND
ExitThread(0);
#endif
}

std::thread m_thread;
std::function<void(thread*)> m_function;
};

} /* namespace lol */


+ 0
- 1698
src/math/real.cpp
Разлика између датотеке није приказан због своје велике величине
Прегледај датотеку


+ 2
- 0
src/scene.h Прегледај датотеку

@@ -25,7 +25,9 @@
#include "light.h"
#include "camera.h"
#include "mesh/mesh.h"

#include <lol/gpu/renderer.h>
#include <lol/base/thread.h>

#define LOL_MAX_LIGHT_COUNT 8



+ 0
- 198
src/sys/getopt.cpp Прегледај датотеку

@@ -1,198 +0,0 @@
//
// Lol Engine
//
// Copyright © 2002—2018 Sam Hocevar <sam@hocevar.net>
//
// Lol Engine is free software. It comes without any warranty, to
// the extent permitted by applicable law. You can redistribute it
// and/or modify it under the terms of the Do What the Fuck You Want
// to Public License, Version 2, as published by the WTFPL Task Force.
// See http://www.wtfpl.net/ for more details.
//

#include <lol/engine-internal.h>

#if HAVE_GETOPT_H
# include <getopt.h>
#endif
#if HAVE_UNISTD_H
# include <unistd.h>
#endif

namespace lol
{

struct getopt_private
{
getopt_private(int argc, char * const * _argv)
: m_argc(argc),
m_argv(_argv)
{}

#if HAVE_GETOPT_LONG
typedef option optdesc;
#else
struct optdesc
{
char const *name;
int has_arg;
int *flag;
int val;
};
#endif

int m_argc;
char * const *m_argv;

std::string m_optstring;
array<optdesc> m_opts;
};

getopt::getopt(int argc, char ** _argv)
: index(1),
arg(nullptr),
m_private(new getopt_private(argc, _argv))
{
}

getopt::getopt(int argc, char * const * _argv)
: index(1),
arg(nullptr),
m_private(new getopt_private(argc, _argv))
{
}

getopt::~getopt()
{
}

void getopt::add_opt(int short_opt, char const *long_opt, bool has_arg)
{
getopt_private::optdesc o { long_opt, has_arg, nullptr, short_opt };
m_private->m_opts.push(o);

/* “The standards require that the argument [to isalnum()] is either
* EOF or a value that is representable in the type unsigned char.” */
if ((int)(unsigned char)short_opt == short_opt && isalnum(short_opt))
{
m_private->m_optstring += (char)short_opt;
if (has_arg)
m_private->m_optstring += ':';
}
}

int getopt::parse()
{
int longindex = 0; // FIXME: what is this?

#if HAVE_GETOPT_LONG
int ret;
optind = this->index;
optarg = this->arg;
m_private->m_opts.push(getopt_private::optdesc { nullptr, 0, nullptr, 0 });
ret = getopt_long(m_private->m_argc, m_private->m_argv, m_private->m_optstring.c_str(),
(option const *)m_private->m_opts.data(), &longindex);
this->index = optind;
this->arg = optarg;
return ret;

#else
/* XXX: this getopt_long implementation should not be trusted for other
* applications without any serious peer reviewing. It “just works” with
* zzuf and a few libcaca programs but may fail miserably in other
* programs. */
char **argv = (char **)(uintptr_t)m_private->m_argv;
char *flag;

if (this->index >= m_private->m_argc)
return -1;

flag = argv[this->index];

if (flag[0] == '-' && flag[1] != '-')
{
char const *tmp;
int ret = flag[1];

if (ret == '\0')
return -1;

tmp = strchr(m_private->m_optstring.c_str(), ret);
if (!tmp || ret == ':')
return '?';

++this->index;
if (tmp[1] == ':')
{
if (flag[2] != '\0')
this->arg = flag + 2;
else
{
if (this->index >= m_private->m_argc)
goto too_few;
this->arg = argv[this->index++];
}
return ret;
}

if (flag[2] != '\0')
{
flag[1] = '-';
--this->index;
++argv[this->index];
}

return ret;
}

if (flag[0] == '-' && flag[1] == '-')
{
if (flag[2] == '\0')
return -1;

for (int i = 0; m_private->m_opts[i].name; ++i)
{
size_t l = strlen(m_private->m_opts[i].name);

if (strncmp(flag + 2, m_private->m_opts[i].name, l))
continue;

switch (flag[2 + l])
{
case '=':
if (!m_private->m_opts[i].has_arg)
goto bad_opt;
longindex = i;
++this->index;
this->arg = flag + 2 + l + 1;
return m_private->m_opts[i].val;
case '\0':
longindex = i;
++this->index;
if (m_private->m_opts[i].has_arg)
{
if (this->index >= m_private->m_argc)
goto too_few;
this->arg = argv[this->index++];
}
return m_private->m_opts[i].val;
default:
break;
}
}
bad_opt:
fprintf(stderr, "%s: unrecognized option `%s'\n", argv[0], flag);
return '?';

too_few:
fprintf(stderr, "%s: option `%s' requires an argument\n",
argv[0], flag);
return '?';
}

return -1;
#endif
}

} // namespace lol


+ 5
- 5
src/t/base/string.cpp Прегледај датотеку

@@ -51,27 +51,27 @@ lolunit_declare_fixture(string_test)
lolunit_declare_test(string_split)
{
auto l1 = split(std::string("abc"));
lolunit_assert(l1.count() == 1);
lolunit_assert(l1.size() == 1);
lolunit_assert(l1[0] == "abc");

auto l2 = split(std::string("\nabc"));
lolunit_assert(l2.count() == 2);
lolunit_assert(l2.size() == 2);
lolunit_assert(l2[0] == "");
lolunit_assert(l2[1] == "abc");

auto l3 = split(std::string("abc\n"));
lolunit_assert(l3.count() == 2);
lolunit_assert(l3.size() == 2);
lolunit_assert(l3[0] == "abc");
lolunit_assert(l3[1] == "");

auto l4 = split(std::string("\n\n"));
lolunit_assert(l4.count() == 3);
lolunit_assert(l4.size() == 3);
lolunit_assert(l4[0] == "");
lolunit_assert(l4[1] == "");
lolunit_assert(l4[2] == "");

auto l5 = split(std::string("abc\nde\n\nf\n"));
lolunit_assert(l5.count() == 5);
lolunit_assert(l5.size() == 5);
lolunit_assert(l5[0] == "abc");
lolunit_assert(l5[1] == "de");
lolunit_assert(l5[2] == "");


+ 14
- 14
src/t/math/polynomial.cpp Прегледај датотеку

@@ -196,12 +196,12 @@ lolunit_declare_fixture(polynomial_test)
* r(x) = 3 + x + x²
* s(x) = 5 */
auto r = p / q;
lolunit_assert_equal(r.m1.degree(), 2);
lolunit_assert_doubles_equal(r.m1[0], 3.f, 1e-5f);
lolunit_assert_doubles_equal(r.m1[1], 1.f, 1e-5f);
lolunit_assert_doubles_equal(r.m1[2], 1.f, 1e-5f);
lolunit_assert_equal(r.m2.degree(), 0);
lolunit_assert_doubles_equal(r.m2[0], 5.f, 1e-5f);
lolunit_assert_equal(std::get<0>(r).degree(), 2);
lolunit_assert_doubles_equal(std::get<0>(r)[0], 3.f, 1e-5f);
lolunit_assert_doubles_equal(std::get<0>(r)[1], 1.f, 1e-5f);
lolunit_assert_doubles_equal(std::get<0>(r)[2], 1.f, 1e-5f);
lolunit_assert_equal(std::get<1>(r).degree(), 0);
lolunit_assert_doubles_equal(std::get<1>(r)[0], 5.f, 1e-5f);
}

lolunit_declare_test(composition_degree_2_2)
@@ -241,7 +241,7 @@ lolunit_declare_fixture(polynomial_test)
polynomial<float> p { 42.f };
auto roots = p.roots();

lolunit_assert_equal(roots.count(), 0);
lolunit_assert_equal(roots.size(), 0);
}

lolunit_declare_test(degree_1_root)
@@ -250,7 +250,7 @@ lolunit_declare_fixture(polynomial_test)
polynomial<float> p { -6.f, 2.f };
auto roots = p.roots();

lolunit_assert_equal(roots.count(), 1);
lolunit_assert_equal(roots.size(), 1);
lolunit_assert_equal(roots[0], 3.f);
}

@@ -260,14 +260,14 @@ lolunit_declare_fixture(polynomial_test)
polynomial<float> p { 81.f, -18.f, 1.f };
auto roots1 = p.roots();

lolunit_assert_equal(roots1.count(), 1);
lolunit_assert_equal(roots1.size(), 1);
lolunit_assert_equal(roots1[0], 9.f);

/* p(x) = 42 - 20x + 2x² */
polynomial<float> q { 42.f, -20.f, 2.f };
auto roots2 = q.roots();

lolunit_assert_equal(roots2.count(), 2);
lolunit_assert_equal(roots2.size(), 2);
lolunit_assert_equal(roots2[0], 3.f);
lolunit_assert_equal(roots2[1], 7.f);
}
@@ -277,7 +277,7 @@ lolunit_declare_fixture(polynomial_test)
polynomial<float> p { 1.f, 3.f, 3.f, 1.f };
auto roots1 = p.roots();

lolunit_assert_equal(roots1.count(), 1);
lolunit_assert_equal(roots1.size(), 1);
lolunit_assert_doubles_equal(roots1[0], -1, 0);
}

@@ -287,7 +287,7 @@ lolunit_declare_fixture(polynomial_test)
auto roots1 = p.roots();

// Should have 2 solutions only, but precision leads to 3 solutions
lolunit_assert_equal(roots1.count(), 2);
lolunit_assert_equal(roots1.size(), 2);
lolunit_assert_doubles_equal(roots1[0], -1, 1e-6);
lolunit_assert_doubles_equal(roots1[1], -2, 1e-6);
}
@@ -297,7 +297,7 @@ lolunit_declare_fixture(polynomial_test)
polynomial<float> p { 6.f, 11.f, 6.f, 1.f };
auto roots1 = p.roots();

lolunit_assert_equal(roots1.count(), 3);
lolunit_assert_equal(roots1.size(), 3);
lolunit_assert_doubles_equal(roots1[0], -1, 1e-8);
lolunit_assert_doubles_equal(roots1[1], -3, 1e-8);
lolunit_assert_doubles_equal(roots1[2], -2, 1e-8);
@@ -308,7 +308,7 @@ lolunit_declare_fixture(polynomial_test)
polynomial<float> p { -12000.f, 1000.f - 1200.f - 120.f, 100.f + 10.0f - 12.f, 1.f };
auto roots1 = p.roots();

lolunit_assert_equal(roots1.count(), 3);
lolunit_assert_equal(roots1.size(), 3);

lolunit_assert_doubles_equal(roots1[0], 12, 1e-5);
lolunit_assert_doubles_equal(roots1[1], -100, 1e-5);


+ 36
- 28
src/t/math/quat.cpp Прегледај датотеку

@@ -22,16 +22,16 @@ lolunit_declare_fixture(quaternion_test)
void setup()
{
/* Generate identity quaternions */
m_vectorpairs.push(vec3::axis_x, vec3::axis_x);
m_vectorpairs.push(2.f * vec3::axis_x, 3.f * vec3::axis_x);
push_vector_pair(vec3::axis_x, vec3::axis_x);
push_vector_pair(2.f * vec3::axis_x, 3.f * vec3::axis_x);

/* Generate 90-degree rotations */
m_vectorpairs.push(vec3::axis_x, vec3::axis_y);
m_vectorpairs.push(2.f * vec3::axis_x, 3.f * vec3::axis_y);
push_vector_pair(vec3::axis_x, vec3::axis_y);
push_vector_pair(2.f * vec3::axis_x, 3.f * vec3::axis_y);

/* Generate 180-degree rotations */
m_vectorpairs.push(vec3::axis_x, -vec3::axis_x);
m_vectorpairs.push(2.f * vec3::axis_x, -3.f * vec3::axis_x);
push_vector_pair(vec3::axis_x, -vec3::axis_x);
push_vector_pair(2.f * vec3::axis_x, -3.f * vec3::axis_x);

/* Fill array with random test values */
for (int i = 0; i < 10000; ++i)
@@ -40,7 +40,7 @@ lolunit_declare_fixture(quaternion_test)
* vec3(rand(-1.f, 1.f), rand(-1.f, 1.f), rand(-1.f, 1.f));
vec3 v2 = lol::pow(10.f, rand(-5.f, 5.f))
* vec3(rand(-1.f, 1.f), rand(-1.f, 1.f), rand(-1.f, 1.f));
m_vectorpairs.push(v1, v2);
push_vector_pair(v1, v2);
}
}

@@ -203,41 +203,44 @@ lolunit_declare_fixture(quaternion_test)
{
for (auto pair : m_vectorpairs)
{
vec3 a = pair.m1;
vec3 b = pair.m2;
vec3 da = normalize(a);
vec3 db = normalize(b);
vec3 a0 = std::get<0>(pair);
vec3 b0 = std::get<1>(pair);
vec3 a = normalize(a0);
vec3 b = normalize(b0);

quat q = quat::rotate(a, b);
quat q = quat::rotate(a0, b0);

auto ctx = a0.tostring() + " " + b0.tostring();
lolunit_set_context(ctx);

/* Check that q is a unit quaternion */
lolunit_assert_doubles_equal(1.0, (double)norm(q), 1e-5);

/* Check that q transforms da into db */
vec3 c = q.transform(da);
/* Check that q transforms a into b */
vec3 c = q.transform(a);

lolunit_assert_doubles_equal(c.x, db.x, 1e-5);
lolunit_assert_doubles_equal(c.y, db.y, 1e-5);
lolunit_assert_doubles_equal(c.z, db.z, 1e-5);
lolunit_assert_doubles_equal(c.x, b.x, 2e-5);
lolunit_assert_doubles_equal(c.y, b.y, 2e-5);
lolunit_assert_doubles_equal(c.z, b.z, 2e-5);

/* Check that ~q transforms db into da */
vec3 d = (~q).transform(db);
/* Check that ~q transforms b into a */
vec3 d = (~q).transform(b);

lolunit_assert_doubles_equal(d.x, da.x, 1e-5);
lolunit_assert_doubles_equal(d.y, da.y, 1e-5);
lolunit_assert_doubles_equal(d.z, da.z, 1e-5);
lolunit_assert_doubles_equal(d.x, a.x, 2e-5);
lolunit_assert_doubles_equal(d.y, a.y, 2e-5);
lolunit_assert_doubles_equal(d.z, a.z, 2e-5);

if (distance(da, db) > 1e-6f)
if (distance(a, b) > 1e-6f)
{
/* If da and db differ, check that the rotation axis is normal to both
/* If a and b differ, check that the rotation axis is normal to both
* vectors, which is only true if the rotation uses the shortest path. */
vec3 axis = q.axis();
lolunit_assert_doubles_equal(0.0, (double)dot(axis, da), 1e-5);
lolunit_assert_doubles_equal(0.0, (double)dot(axis, db), 1e-5);
lolunit_assert_doubles_equal(0.0, (double)dot(axis, a), 1e-5);
lolunit_assert_doubles_equal(0.0, (double)dot(axis, b), 1e-5);
}
else
{
/* If da and db are roughly the same, check that the rotation angle
/* If a and b are roughly the same, check that the rotation angle
* is zero. */
lolunit_assert_doubles_equal(0.0, (double)q.angle(), 1e-5);
}
@@ -533,7 +536,12 @@ lolunit_declare_fixture(quaternion_test)
}

private:
array<vec3, vec3> m_vectorpairs;
void push_vector_pair(vec3 p, vec3 q)
{
m_vectorpairs.push_back(std::make_tuple(p, q));
}

std::vector<std::tuple<vec3, vec3>> m_vectorpairs;
};

} /* namespace lol */


Loading…
Откажи
Сачувај