Commit c2535f0f authored by TheNumbat's avatar TheNumbat
Browse files

upstream changes

parent 8b8ee1f1
#include "debug.h"
#include "../util/rand.h"
#include "../rays/samplers.h"
#include "../util/rand.h"
#include "debug.h"
namespace Samplers {
Vec2 Rect::Uniform::sample(float& pdf) const {
Vec2 Rect::Uniform::sample(float &pdf) const {
// TODO (PathTracer): Task 1
// Generate a uniformly random point on a rectangle of size size.x * size.y
......@@ -15,14 +15,14 @@ Vec2 Rect::Uniform::sample(float& pdf) const {
return Vec2();
}
Vec3 Hemisphere::Cosine::sample(float& pdf) const {
Vec3 Hemisphere::Cosine::sample(float &pdf) const {
// TODO (PathTracer): Task 6
// You may implement this, but don't have to.
return Vec3();
}
Vec3 Sphere::Uniform::sample(float& pdf) const {
Vec3 Sphere::Uniform::sample(float &pdf) const {
// TODO (PathTracer): Task 7
// Generate a uniformly random point on the unit sphere (or equivalently, direction)
......@@ -32,7 +32,7 @@ Vec3 Sphere::Uniform::sample(float& pdf) const {
return Vec3();
}
Sphere::Image::Image(const HDR_Image& image) {
Sphere::Image::Image(const HDR_Image &image) {
// TODO (PathTracer): Task 7
// Set up importance sampling for a spherical environment map image.
......@@ -40,11 +40,12 @@ Sphere::Image::Image(const HDR_Image& image) {
// You may make use of the pdf, cdf, and total members, or create your own
// representation.
const auto [_w,_h] = image.dimension();
w = _w; h = _h;
const auto [_w, _h] = image.dimension();
w = _w;
h = _h;
}
Vec3 Sphere::Image::sample(float& out_pdf) const {
Vec3 Sphere::Image::sample(float &out_pdf) const {
// TODO (PathTracer): Task 7
// Use your importance sampling data structure to generate a sample direction.
......@@ -54,14 +55,14 @@ Vec3 Sphere::Image::sample(float& out_pdf) const {
return Vec3();
}
Vec3 Point::sample(float& pmf) const {
Vec3 Point::sample(float &pmf) const {
pmf = 1.0f;
return point;
}
Vec3 Two_Points::sample(float& pmf) const {
if(RNG::unit() < prob) {
Vec3 Two_Points::sample(float &pmf) const {
if (RNG::unit() < prob) {
pmf = prob;
return p1;
}
......@@ -69,7 +70,7 @@ Vec3 Two_Points::sample(float& pmf) const {
return p2;
}
Vec3 Hemisphere::Uniform::sample(float& pdf) const {
Vec3 Hemisphere::Uniform::sample(float &pdf) const {
float Xi1 = RNG::unit();
float Xi2 = RNG::unit();
......@@ -85,4 +86,4 @@ Vec3 Hemisphere::Uniform::sample(float& pdf) const {
return Vec3(xs, ys, zs);
}
}
} // namespace Samplers
#include "debug.h"
#include "../rays/shapes.h"
#include "debug.h"
namespace PT {
const char* Shape_Type_Names[(int)Shape_Type::count] = {
"None",
"Sphere"
};
const char *Shape_Type_Names[(int)Shape_Type::count] = {"None", "Sphere"};
BBox Sphere::bbox() const {
......@@ -17,7 +14,7 @@ BBox Sphere::bbox() const {
return box;
}
Trace Sphere::hit(const Ray& ray) const {
Trace Sphere::hit(const Ray &ray) const {
// TODO (PathTracer): Task 2
// Intersect this ray with a sphere of radius Sphere::radius centered at the origin.
......@@ -36,4 +33,4 @@ Trace Sphere::hit(const Ray& ray) const {
return ret;
}
}
} // namespace PT
......@@ -35,7 +35,7 @@ Mat4 Joint::joint_to_posed() const {
return Mat4::I;
}
Vec3 Skeleton::end_of(Joint* j) {
Vec3 Skeleton::end_of(Joint *j) {
// TODO(Animation): Task 2
......@@ -44,7 +44,7 @@ Vec3 Skeleton::end_of(Joint* j) {
return Vec3{};
}
Vec3 Skeleton::posed_end_of(Joint* j) {
Vec3 Skeleton::posed_end_of(Joint *j) {
// TODO(Animation): Task 2
......@@ -53,7 +53,7 @@ Vec3 Skeleton::posed_end_of(Joint* j) {
return Vec3{};
}
Mat4 Skeleton::joint_to_bind(const Joint* j) const {
Mat4 Skeleton::joint_to_bind(const Joint *j) const {
// TODO(Animation): Task 2
......@@ -62,7 +62,7 @@ Mat4 Skeleton::joint_to_bind(const Joint* j) const {
return Mat4::I;
}
Mat4 Skeleton::joint_to_posed(const Joint* j) const {
Mat4 Skeleton::joint_to_posed(const Joint *j) const {
// TODO(Animation): Task 2
......@@ -71,7 +71,8 @@ Mat4 Skeleton::joint_to_posed(const Joint* j) const {
return Mat4::I;
}
void Skeleton::find_joints(const GL::Mesh& mesh, std::unordered_map<unsigned int, std::vector<Joint*>>& map) {
void Skeleton::find_joints(const GL::Mesh &mesh,
std::unordered_map<unsigned int, std::vector<Joint *>> &map) {
// TODO(Animation): Task 3
......@@ -79,10 +80,9 @@ void Skeleton::find_joints(const GL::Mesh& mesh, std::unordered_map<unsigned int
// that should effect the vertex. A joint should effect a vertex if it is within Joint::radius
// distance of the bone segment in bind position.
const std::vector<GL::Mesh::Vert>& verts = mesh.verts();
for_joints([&](Joint* j) {
const std::vector<GL::Mesh::Vert> &verts = mesh.verts();
for_joints([&](Joint *j) {
// What vertices does joint j effect?
});
......@@ -90,8 +90,8 @@ void Skeleton::find_joints(const GL::Mesh& mesh, std::unordered_map<unsigned int
(void)verts;
}
void Skeleton::skin(const GL::Mesh& input, GL::Mesh& output,
const std::unordered_map<unsigned int, std::vector<Joint*>>& map) {
void Skeleton::skin(const GL::Mesh &input, GL::Mesh &output,
const std::unordered_map<unsigned int, std::vector<Joint *>> &map) {
// TODO(Animation): Task 3
......@@ -103,7 +103,7 @@ void Skeleton::skin(const GL::Mesh& input, GL::Mesh& output,
// Currently, this just copies the input to the output without modification.
std::vector<GL::Mesh::Vert> verts = input.verts();
for(size_t i = 0; i < verts.size(); i++) {
for (size_t i = 0; i < verts.size(); i++) {
// Skin vertex i.
}
......
#include "debug.h"
#include "../geometry/spline.h"
#include "debug.h"
template<typename T>
T Spline<T>::cubic_unit_spline(float time, const T& position0, const T& position1, const T& tangent0, const T& tangent1) {
template <typename T>
T Spline<T>::cubic_unit_spline(float time, const T &position0, const T &position1,
const T &tangent0, const T &tangent1) {
// TODO (Animation): Task 1a
// Given time in [0,1] compute the cubic spline coefficients and use them to compute
......@@ -15,8 +16,7 @@ T Spline<T>::cubic_unit_spline(float time, const T& position0, const T& position
return T();
}
template<typename T>
T Spline<T>::at(float time) const {
template <typename T> T Spline<T>::at(float time) const {
// TODO (Animation): Task 1b
......
#include "debug.h"
#include "../rays/tri_mesh.h"
#include "debug.h"
namespace PT {
......@@ -13,13 +13,15 @@ BBox Triangle::bbox() const {
return box;
}
Trace Triangle::hit(const Ray& ray) const {
Trace Triangle::hit(const Ray &ray) const {
// Vertices of triangle - has postion and surface normal
Tri_Mesh_Vert v_0 = vertex_list[v0];
Tri_Mesh_Vert v_1 = vertex_list[v1];
Tri_Mesh_Vert v_2 = vertex_list[v2];
(void)v_0; (void)v_1; (void)v_2;
(void)v_0;
(void)v_1;
(void)v_2;
// TODO (PathTracer): Task 2
// Intersect this ray with a triangle defined by the three above points.
......@@ -33,42 +35,37 @@ Trace Triangle::hit(const Ray& ray) const {
return ret;
}
Triangle::Triangle(Tri_Mesh_Vert* verts, unsigned int v0, unsigned int v1, unsigned int v2)
Triangle::Triangle(Tri_Mesh_Vert *verts, unsigned int v0, unsigned int v1, unsigned int v2)
: vertex_list(verts), v0(v0), v1(v1), v2(v2) {}
void Tri_Mesh::build(const GL::Mesh& mesh) {
void Tri_Mesh::build(const GL::Mesh &mesh) {
verts.clear();
triangles.clear();
for(const auto& v : mesh.verts()) {
for (const auto &v : mesh.verts()) {
verts.push_back({v.pos, v.norm});
}
const auto& idxs = mesh.indices();
const auto &idxs = mesh.indices();
std::vector<Triangle> tris;
for(size_t i = 0; i < idxs.size(); i += 3) {
tris.push_back(Triangle(verts.data(), idxs[i], idxs[i+1], idxs[i+2]));
for (size_t i = 0; i < idxs.size(); i += 3) {
tris.push_back(Triangle(verts.data(), idxs[i], idxs[i + 1], idxs[i + 2]));
}
triangles.build(std::move(tris), 4);
}
Tri_Mesh::Tri_Mesh(const GL::Mesh& mesh) {
build(mesh);
}
Tri_Mesh::Tri_Mesh(const GL::Mesh &mesh) { build(mesh); }
BBox Tri_Mesh::bbox() const {
return triangles.bbox();
}
BBox Tri_Mesh::bbox() const { return triangles.bbox(); }
Trace Tri_Mesh::hit(const Ray& ray) const {
return triangles.hit(ray);
}
Trace Tri_Mesh::hit(const Ray &ray) const { return triangles.hit(ray); }
size_t Tri_Mesh::visualize(GL::Lines& lines, GL::Lines& active, size_t level, const Mat4& trans) const {
size_t Tri_Mesh::visualize(GL::Lines &lines, GL::Lines &active, size_t level,
const Mat4 &trans) const {
return triangles.visualize(lines, active, level, trans);
}
}
} // namespace PT
#include "camera.h"
const Vec3 UP = Vec3{0.0f, 1.0f, 0.0f};
Camera::Camera(Vec2 dim) {
reset();
set_ar(dim);
}
Mat4 Camera::get_view() const {
return view;
}
Mat4 Camera::get_view() const { return view; }
Mat4 Camera::get_proj() const {
return Mat4::project(vert_fov, aspect_ratio, near_plane);
}
Mat4 Camera::get_proj() const { return Mat4::project(vert_fov, aspect_ratio, near_plane); }
Vec3 Camera::pos() const {
return position;
}
Vec3 Camera::pos() const { return position; }
Vec3 Camera::front() const {
return (looking_at - position).unit();
}
Vec3 Camera::front() const { return (looking_at - position).unit(); }
float Camera::dist() const {
return (position - looking_at).norm();
}
float Camera::dist() const { return (position - looking_at).norm(); }
void Camera::look_at(Vec3 cent, Vec3 pos) {
position = pos;
looking_at = cent;
radius = (pos - cent).norm();
update_dirs();
rot = Quat::euler(Mat4::rotate_z_to(front()).to_euler());
update_pos();
}
void Camera::reset() {
vert_fov = 90.0f;
aspect_ratio = 1.7778f;
pitch = -45.0f;
yaw = 45.0f;
rot = Quat::euler(Vec3(-45.0f, 45.0f, 0.0f));
near_plane = 0.01f;
radius = 5.0f;
radius_sens = 0.25f;
move_sens = 0.015f;
orbit_sens = 0.2f;
looking_at = Vec3();
global_up = Vec3(0, 1, 0);
update_pos();
}
void Camera::mouse_orbit(Vec2 off) {
yaw += off.x * orbit_sens;
pitch += off.y * orbit_sens;
if (yaw > 360.0f) yaw = 0.0f;
else if (yaw < 0.0f) yaw = 360.0f;
pitch = clamp(pitch, -89.5f, 89.5f);
float up_rot = -off.x * orbit_sens;
float right_rot = off.y * orbit_sens;
Vec3 up = rot.rotate(UP);
Vec3 f = front();
Vec3 right = cross(f, up).unit();
rot = Quat::axis_angle(UP, up_rot) * Quat::axis_angle(right, right_rot) * rot;
update_pos();
}
void Camera::mouse_move(Vec2 off) {
Vec3 front = (position - looking_at).unit();
Vec3 right = cross(front, global_up).unit();
Vec3 up = cross(front, right).unit();
looking_at += right * off.x * move_sens - up * off.y * move_sens;
Vec3 up = rot.rotate(UP);
Vec3 f = front();
Vec3 right = cross(f, up).unit();
looking_at += -right * off.x * move_sens + up * off.y * move_sens;
update_pos();
}
......@@ -71,9 +66,7 @@ void Camera::mouse_radius(float off) {
update_pos();
}
void Camera::set_fov(float f) {
vert_fov = f;
}
void Camera::set_fov(float f) { vert_fov = f; }
float Camera::get_h_fov() const {
float vfov = Radians(vert_fov);
......@@ -81,46 +74,21 @@ float Camera::get_h_fov() const {
return Degrees(hfov);
}
float Camera::get_fov() const {
return vert_fov;
}
float Camera::get_fov() const { return vert_fov; }
float Camera::get_ar() const {
return aspect_ratio;
}
float Camera::get_ar() const { return aspect_ratio; }
float Camera::get_near() const {
return near_plane;
}
Vec3 Camera::center() const {
return looking_at;
}
float Camera::get_near() const { return near_plane; }
void Camera::set_ar(float a) {
aspect_ratio = a;
}
Vec3 Camera::center() const { return looking_at; }
void Camera::set_ar(Vec2 dim) {
aspect_ratio = dim.x / dim.y;
}
void Camera::set_ar(float a) { aspect_ratio = a; }
void Camera::update_dirs() {
Vec3 dir = front();
yaw = Degrees(std::atan2(dir.z, dir.x));
pitch = Degrees(std::atan2(dir.y, Vec2(dir.x, dir.z).norm()));
while (yaw > 360.0f) yaw -= 360.0f;
while (yaw < 0.0f) yaw += 360.0f;
pitch = clamp(pitch, -89.5f, 89.5f);
update_pos();
}
void Camera::set_ar(Vec2 dim) { aspect_ratio = dim.x / dim.y; }
void Camera::update_pos() {
position.x = std::cos(Radians(pitch)) * std::cos(Radians(yaw));
position.y = std::sin(Radians(pitch));
position.z = std::sin(Radians(yaw)) * std::cos(Radians(pitch));
position = looking_at - radius * position.unit();
view = Mat4::look_at(position, looking_at, global_up);
iview = view.inverse();
position = rot.rotate(Vec3{0.0f, 0.0f, 1.0f});
position = looking_at + radius * position.unit();
iview = Mat4::translate(position) * rot.to_mat();
view = iview.inverse();
}
......@@ -54,15 +54,15 @@ public:
float get_near() const;
private:
void update_dirs();
void update_pos();
/// Camera parameters
Vec3 position, looking_at, global_up;
Vec3 position, looking_at;
float vert_fov, aspect_ratio;
Quat rot;
/// For updating position & looking_at
float pitch, yaw, radius, near_plane;
float radius, near_plane;
/// For mouse control
float orbit_sens, move_sens, radius_sens;
......
......@@ -22,9 +22,7 @@ HDR_Image HDR_Image::copy() const {
return ret;
}
std::pair<size_t,size_t> HDR_Image::dimension() const {
return {w,h};
}
std::pair<size_t, size_t> HDR_Image::dimension() const { return {w, h}; }
void HDR_Image::resize(size_t _w, size_t _h) {
w = _w;
......@@ -35,11 +33,12 @@ void HDR_Image::resize(size_t _w, size_t _h) {
}
void HDR_Image::clear(Spectrum color) {
for(auto& s : pixels) s = color;
for (auto &s : pixels)
s = color;
dirty = true;
}
Spectrum& HDR_Image::at(size_t i) {
Spectrum &HDR_Image::at(size_t i) {
assert(i < w * h);
dirty = true;
return pixels[i];
......@@ -50,7 +49,7 @@ Spectrum HDR_Image::at(size_t i) const {
return pixels[i];
}
Spectrum& HDR_Image::at(size_t x, size_t y) {
Spectrum &HDR_Image::at(size_t x, size_t y) {
assert(x < w && y < h);
size_t idx = y * w + x;
dirty = true;
......@@ -65,11 +64,11 @@ Spectrum HDR_Image::at(size_t x, size_t y) const {
std::string HDR_Image::load_from(std::string file) {
if(IsEXR(file.c_str()) == TINYEXR_SUCCESS) {
if (IsEXR(file.c_str()) == TINYEXR_SUCCESS) {
int n_w, n_h;
float* data;
const char* err = nullptr;
float *data;
const char *err = nullptr;
int ret = LoadEXR(&data, &n_w, &n_h, file.c_str(), &err);
......@@ -79,17 +78,18 @@ std::string HDR_Image::load_from(std::string file) {
std::string err_s(err);
FreeEXRErrorMessage(err);
return err_s;
} else return "Unknown failure.";
} else
return "Unknown failure.";
} else {
resize(n_w, n_h);
for(size_t j = 0; j < h; j++) {
for(size_t i = 0; i < w; i++) {
for (size_t j = 0; j < h; j++) {
for (size_t i = 0; i < w; i++) {
size_t didx = 4 * (j * w + i);
size_t pidx = (h - j - 1) * w + i;
pixels[pidx] = Spectrum(data[didx],data[didx+1],data[didx+2]);
pixels[pidx] = Spectrum(data[didx], data[didx + 1], data[didx + 2]);
}
}
......@@ -103,24 +103,27 @@ std::string HDR_Image::load_from(std::string file) {
int n_w, n_h, channels;
unsigned char *data = stbi_load(file.c_str(), &n_w, &n_h, &channels, 0);
if(!data) return std::string(stbi_failure_reason());
if(channels < 3) return "Image has less than 3 color channels.";
if (!data)
return std::string(stbi_failure_reason());
if (channels < 3)
return "Image has less than 3 color channels.";
resize(n_w, n_h);
for(size_t i = 0; i < w * h * channels; i += channels) {
for (size_t i = 0; i < w * h * channels; i += channels) {
float r = data[i] / 255.0f;
float g = data[i+1] / 255.0f;
float b = data[i+2] / 255.0f;
pixels[i / channels] = Spectrum(r,g,b);
float g = data[i + 1] / 255.0f;
float b = data[i + 2] / 255.0f;
pixels[i / channels] = Spectrum(r, g, b);
}
stbi_image_free(data);
}
for(size_t i = 0; i < pixels.size(); i++) {
for (size_t i = 0; i < pixels.size(); i++) {
pixels[i].make_linear();
if(!pixels[i].valid()) pixels[i] = {};
if (!pixels[i].valid())
pixels[i] = {};
}
last_path = file;
......@@ -128,20 +131,19 @@ std::string HDR_Image::load_from(std::string file) {
return {};
}
std::string HDR_Image::loaded_from() const {
return last_path;
}
std::string HDR_Image::loaded_from() const { return last_path; }
void HDR_Image::tonemap(float e) const {
if(e <= 0.0f) {
if (e <= 0.0f) {
e = exposure;
} else if(e != exposure) {
} else if (e != exposure) {
exposure = e;
dirty = true;
}
if(!dirty) return;
if (!dirty)
return;
std::vector<unsigned char> data;
tonemap_to(data, e);
......@@ -150,38 +152,38 @@ void HDR_Image::tonemap(float e) const {
dirty = false;
}
const GL::Tex2D& HDR_Image::get_texture(float e) const {
const GL::Tex2D &HDR_Image::get_texture(float e) const {
tonemap(e);
return render_tex;
}
void HDR_Image::tonemap_to(std::vector<unsigned char>& data, float e) const {
void HDR_Image::tonemap_to(std::vector<unsigned char> &data, float e) const {
if(e <= 0.0f) {
if (e <= 0.0f) {
e = exposure;
}
if(data.size() != w * h * 4)
if (data.size() != w * h * 4)
data.resize(w * h * 4);
for(size_t j = 0; j < h; j++) {
for(size_t i = 0; i < w; i++) {
for (size_t j = 0; j < h; j++) {
for (size_t i = 0; i < w; i++) {
size_t pidx = (h - j - 1) * w + i;
const Spectrum& sample = pixels[pidx];
const Spectrum &sample = pixels[pidx];
float r = 1.0f - std::exp(-sample.r * exposure);
float g = 1.0f - std::exp(-sample.g * exposure);
float b = 1.0f - std::exp(-sample.b * exposure);
Spectrum out(r,g,b);
Spectrum out(r, g, b);
out.make_srgb();
size_t didx = 4 * (j * w + i);
data[didx] = (unsigned char)std::round(out.r * 255.0f);
data[didx+1] = (unsigned char)std::round(out.g * 255.0f);
data[didx+2] = (unsigned char)std::round(out.b * 255.0f);
data[didx+3] = 255;
data[didx + 1] = (unsigned char)std::round(out.g * 255.0f);
data[didx + 2] = (unsigned char)std::round(out.b * 255.0f);
data[didx + 3] = 255;
}
}
}
......@@ -3,36 +3,36 @@
#include <vector>
#include "../platform/gl.h"
#include "../lib/spectrum.h"
#include "../platform/gl.h"
class HDR_Image {
public:
HDR_Image();
HDR_Image(size_t w, size_t h);
HDR_Image(const HDR_Image& src) = delete;
HDR_Image(HDR_Image&& src) = default;
HDR_Image(const HDR_Image &src) = delete;
HDR_Image(HDR_Image &&src) = default;
~HDR_Image() = default;
HDR_Image copy() const;
HDR_Image& operator=(const HDR_Image& src) = delete;
HDR_Image& operator=(HDR_Image&& src) = default;
HDR_Image &operator=(const HDR_Image &src) = delete;
HDR_Image &operator=(HDR_Image &&src) = default;
Spectrum& at(size_t x, size_t y);
Spectrum &at(size_t x, size_t y);
Spectrum at(size_t x, size_t y) const;
Spectrum& at(size_t i);
Spectrum &at(size_t i);
Spectrum at(size_t i) const;
void clear(Spectrum color);
void resize(size_t w, size_t h);
std::pair<size_t,size_t> dimension() const;
std::pair<size_t, size_t> dimension() const;
std::string load_from(std::string file);
std::string loaded_from() const;
void tonemap_to(std::vector<unsigned char>& data, float exposure = 0.0f) const;
const GL::Tex2D& get_texture(float exposure = 0.0f) const;
void tonemap_to(std::vector<unsigned char> &data, float exposure = 0.0f) const;
const GL::Tex2D &get_texture(float exposure = 0.0f) const;
private:
void tonemap(float exposure = 0.0f) const;
......
......@@ -15,20 +15,17 @@ float unit() {
return d(rng);
}
int integer(int min, int max) {
return (int)lerp((float)min, (float)max, unit());
}
int integer(int min, int max) { return (int)lerp((float)min, (float)max, unit()); }
bool coin_flip(float p) {
return unit() < p;
}
bool coin_flip(float p) { return unit() < p; }
void seed() {
std::random_device r;
std::random_device::result_type seed = r() ^
std::random_device::result_type seed =
r() ^
(std::random_device::result_type)std::hash<std::thread::id>()(std::this_thread::get_id()) ^
(std::random_device::result_type)std::hash<time_t>()(std::time(nullptr));
rng.seed(seed);
}
}
} // namespace RNG
......@@ -3,16 +3,15 @@
namespace RNG {
// Generate random float in the range [0,1]
float unit();
// Generate random float in the range [0,1]
float unit();
// Generate random integer in the range [min,max)
int integer(int min, int max);
// Generate random integer in the range [min,max)
int integer(int min, int max);
// Return true with probability p and false with probability 1-p
bool coin_flip(float p = 0.5f);
// Seed the current thread's PRNG
void seed();
}
// Return true with probability p and false with probability 1-p
bool coin_flip(float p = 0.5f);
// Seed the current thread's PRNG
void seed();
} // namespace RNG
......@@ -2,28 +2,25 @@
#include "thread_pool.h"
#include "../util/rand.h"
Thread_Pool::Thread_Pool(size_t threads) {
start(threads);
}
Thread_Pool::Thread_Pool(size_t threads) { start(threads); }
Thread_Pool::~Thread_Pool() {
stop();
}
Thread_Pool::~Thread_Pool() { stop(); }
void Thread_Pool::start(size_t threads) {
n_threads = threads;
stop_now = false;
stop_when_done = false;
for(size_t i = 0; i < threads; i++)
workers.emplace_back([this]{
for (size_t i = 0; i < threads; i++)
workers.emplace_back([this] {
RNG::seed();
for(;;) {
for (;;) {
std::function<void()> task;
{
std::unique_lock<std::mutex> lock(this->queue_mutex);
this->condition.wait(lock,
[this]{ return this->stop_now || this->stop_when_done || !this->tasks.empty(); });
if(this->stop_now || (this->stop_when_done && this->tasks.empty()))
this->condition.wait(lock, [this] {
return this->stop_now || this->stop_when_done || !this->tasks.empty();
});
if (this->stop_now || (this->stop_when_done && this->tasks.empty()))
return;
task = std::move(this->tasks.front());
this->tasks.pop();
......@@ -46,7 +43,7 @@ void Thread_Pool::wait() {
}
condition.notify_all();
for(std::thread &worker: workers) {
for (std::thread &worker : workers) {
worker.join();
}
workers.clear();
......@@ -62,7 +59,7 @@ void Thread_Pool::stop() {
}
condition.notify_all();
for(std::thread &worker: workers) {
for (std::thread &worker : workers) {
worker.join();
}
workers.clear();
......
#pragma once
#include <queue>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <future>
#include <functional>
#include <future>
#include <mutex>
#include <queue>
#include <thread>
#include "../lib/log.h"
......@@ -19,8 +19,9 @@ public:
void wait();
void clear();
template<class F, class... Args>
auto enqueue(F&& f, Args&&... args) -> std::future<typename std::invoke_result<F, Args...>::type> {
template <class F, class... Args>
auto enqueue(F &&f, Args &&...args)
-> std::future<typename std::invoke_result<F, Args...>::type> {
using return_type = typename std::invoke_result<F, Args...>::type;
assert(!stop_now && !stop_when_done);
......@@ -31,7 +32,7 @@ public:
std::future<return_type> res = task->get_future();
{
std::unique_lock<std::mutex> lock(queue_mutex);
tasks.emplace([task](){ (*task)(); });
tasks.emplace([task]() { (*task)(); });
}
condition.notify_one();
return res;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment