Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Defined Yocto utility libraries #1021

Merged
merged 4 commits into from
Aug 19, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 1 addition & 2 deletions apps/yimageview/yimageview.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,12 @@

#include <yocto/yocto_commonio.h>
#include <yocto/yocto_image.h>
#include <yocto/yocto_parallel.h>
#include <yocto_gui/yocto_imgui.h>
#include <yocto_gui/yocto_opengl.h>
using namespace yocto;

#include <atomic>
#include <deque>
#include <future>

struct image_stats {
vec4f min = zero4f;
Expand Down
3 changes: 1 addition & 2 deletions apps/ysceneitrace/ysceneitrace.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,16 +28,15 @@

#include <yocto/yocto_color.h>
#include <yocto/yocto_commonio.h>
#include <yocto/yocto_parallel.h>
#include <yocto/yocto_sceneio.h>
#include <yocto/yocto_shape.h>
#include <yocto/yocto_trace.h>
#include <yocto_gui/yocto_imgui.h>
#include <yocto_gui/yocto_opengl.h>
using namespace yocto;

#include <atomic>
#include <deque>
#include <future>

namespace yocto {
void print_obj_camera(scene_camera* camera);
Expand Down
3 changes: 1 addition & 2 deletions apps/ysceneview/ysceneview.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,15 +29,14 @@
#include <yocto/yocto_commonio.h>
#include <yocto/yocto_geometry.h>
#include <yocto/yocto_image.h>
#include <yocto/yocto_parallel.h>
#include <yocto/yocto_sceneio.h>
#include <yocto/yocto_shape.h>
#include <yocto_gui/yocto_imgui.h>
#include <yocto_gui/yocto_opengl.h>
using namespace yocto;

#include <atomic>
#include <deque>
#include <future>

#ifdef _WIN32
#undef near
Expand Down
3 changes: 1 addition & 2 deletions apps/ysceneviews/ysceneviews.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,15 +29,14 @@
#include <yocto/yocto_commonio.h>
#include <yocto/yocto_geometry.h>
#include <yocto/yocto_image.h>
#include <yocto/yocto_parallel.h>
#include <yocto/yocto_sceneio.h>
#include <yocto/yocto_shape.h>
#include <yocto_gui/yocto_imgui.h>
#include <yocto_gui/yocto_opengl.h>
using namespace yocto;

#include <atomic>
#include <deque>
#include <future>
using namespace std::string_literals;

#ifdef _WIN32
Expand Down
3 changes: 1 addition & 2 deletions apps/yshapeview/yshapeview.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,15 +29,14 @@
#include <yocto/yocto_commonio.h>
#include <yocto/yocto_geometry.h>
#include <yocto/yocto_image.h>
#include <yocto/yocto_parallel.h>
#include <yocto/yocto_sceneio.h>
#include <yocto/yocto_shape.h>
#include <yocto_gui/yocto_imgui.h>
#include <yocto_gui/yocto_opengl.h>
using namespace yocto;

#include <atomic>
#include <deque>
#include <future>

#ifdef _WIN32
#undef near
Expand Down
204 changes: 35 additions & 169 deletions libs/yocto/yocto_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,15 +37,9 @@
// INCLUDES
// -----------------------------------------------------------------------------

#include <algorithm>
#include <atomic>
#include <chrono>
#include <deque>
#include <future>
#include <mutex>
#include <cstdint>
#include <string>
#include <thread>
#include <unordered_map>
#include <utility>
#include <vector>

Expand All @@ -55,9 +49,6 @@
namespace yocto {

// using directives
using std::atomic;
using std::deque;
using std::future;
using std::pair;
using std::string;
using std::vector;
Expand All @@ -79,12 +70,14 @@ inline int64_t get_time();
// -----------------------------------------------------------------------------
namespace yocto {

// Python `range()` equivalent. Construct an instance to iterate over a
// sequence.
inline auto range(int min, int max);
inline auto range(int max);
// Python `range()` equivalent. Construct an object that c over an
// integer sequence.
template <typename T>
inline auto range(T min, T max);
template <typename T>
inline auto range(T max);

// Python `enumerate()` equivalent. Construct an object that iteraterates over a
// Python `enumerate()` equivalent. Construct an object that iterates over a
// sequence of elements and numbers them.
template <typename T>
inline auto enumerate(const vector<T>& vals);
Expand All @@ -93,60 +86,13 @@ inline auto enumerate(vector<T>& vals);

// Vector append and concatenation
template <typename T>
inline vector<T>& operator+=(vector<T>& a, const vector<T>& b);
inline vector<T>& append(vector<T>& a, const vector<T>& b);
template <typename T>
inline vector<T>& operator+=(vector<T>& a, const T& b);
inline vector<T>& append(vector<T>& a, const T& b);
template <typename T>
inline vector<T> operator+(const vector<T>& a, const vector<T>& b);
inline vector<T> join(const vector<T>& a, const vector<T>& b);
template <typename T>
inline vector<T> operator+(const vector<T>& a, const T& b);

} // namespace yocto

// -----------------------------------------------------------------------------
// CONCURRENCY UTILITIES
// -----------------------------------------------------------------------------
namespace yocto {

// a simple concurrent queue that locks at every call
template <typename T>
struct concurrent_queue {
concurrent_queue() {}
concurrent_queue(const concurrent_queue& other) = delete;
concurrent_queue& operator=(const concurrent_queue& other) = delete;

bool empty();
void clear();
void push(const T& value);
bool try_pop(T& value);

private:
std::mutex mutex;
deque<T> queue;
};

// Run a task asynchronously
template <typename Func, typename... Args>
inline auto run_async(Func&& func, Args&&... args);

// Check if an async task is ready
inline bool is_valid(const future<void>& result);
inline bool is_running(const future<void>& result);
inline bool is_ready(const future<void>& result);

// Simple parallel for used since our target platforms do not yet support
// parallel algorithms. `Func` takes the integer index.
template <typename Func>
inline void parallel_for(int begin, int end, Func&& func);
template <typename Func>
inline void parallel_for(int num, Func&& func);

// Simple parallel for used since our target platforms do not yet support
// parallel algorithms. `Func` takes a reference to a `T`.
template <typename T, typename Func>
inline void parallel_foreach(vector<T>& values, Func&& func);
template <typename T, typename Func>
inline void parallel_foreach(const vector<T>& values, Func&& func);
inline vector<T> join(const vector<T>& a, const T& b);

} // namespace yocto

Expand Down Expand Up @@ -176,40 +122,47 @@ inline int64_t get_time() {
namespace yocto {

// Range object to support Python-like iteration. Use with `range()`.
template <typename T>
struct range_helper {
struct iterator {
int pos = 0;
T pos = 0;
iterator& operator++() {
pos++;
return *this;
}
bool operator!=(const iterator& other) const { return pos != other.pos; }
int operator*() const { return pos; }
T operator*() const { return pos; }
};
int begin_ = 0, end_ = 0;
T begin_ = 0, end_ = 0;
iterator begin() const { return {begin_}; }
iterator end() const { return {end_}; }
};

// Python `range()` equivalent. Construct an object to iterate over a sequence.
inline auto range(int min, int max) { return range_helper{min, max}; }
inline auto range(int max) { return range(0, max); }
template <typename T>
inline auto range(T min, T max) {
return range_helper{min, max};
}
template <typename T>
inline auto range(T max) {
return range((T)0, max);
}

// Enumerate object to support Python-like enumeration. Use with `enumerate()`.
template <typename T>
struct enumerate_helper {
struct iterator {
T* data = nullptr;
int pos = 0;
int64_t pos = 0;
iterator& operator++() {
pos++;
return *this;
}
bool operator!=(const iterator& other) const { return pos != other.pos; }
pair<int&, T&> operator*() const { return {pos, *(data + pos)}; }
pair<int64_t&, T&> operator*() const { return {pos, *(data + pos)}; }
};
T* data = nullptr;
int size = 0;
int64_t size = 0;
iterator begin() const { return {data, 0}; }
iterator end() const { return {data, size}; }
};
Expand All @@ -218,120 +171,33 @@ struct enumerate_helper {
// sequence of elements and numbers them.
template <typename T>
inline auto enumerate(const vector<T>& vals) {
return enumerate_helper<const T>{vals.data(), vals.size()};
return enumerate_helper<const T>{vals.data(), (int64_t)vals.size()};
}
template <typename T>
inline auto enumerate(vector<T>& vals) {
return enumerate_helper<T>{vals.data(), vals.size()};
return enumerate_helper<T>{vals.data(), (int64_t)vals.size()};
}

// Vector append and concatenation
template <typename T>
inline vector<T>& operator+=(vector<T>& a, const vector<T>& b) {
inline vector<T>& append(vector<T>& a, const vector<T>& b) {
a.insert(a.end(), b.begin(), b.end());
return a;
}
template <typename T>
inline vector<T>& operator+=(vector<T>& a, const T& b) {
inline vector<T>& append(vector<T>& a, const T& b) {
a.push_back(b);
return a;
}
template <typename T>
inline vector<T> operator+(const vector<T>& a, const vector<T>& b) {
inline vector<T> join(const vector<T>& a, const vector<T>& b) {
auto c = a;
return c += b;
return append(b);
}
template <typename T>
inline vector<T> operator+(const vector<T>& a, const T& b) {
inline vector<T> join(const vector<T>& a, const T& b) {
auto c = a;
return c += b;
}

} // namespace yocto

// -----------------------------------------------------------------------------
// CONCURRENCY UTILITIES
// -----------------------------------------------------------------------------
namespace yocto {

// a simple concurrent queue that locks at every call
template <typename T>
bool concurrent_queue<T>::empty() {
std::lock_guard<std::mutex> lock(mutex);
return queue.empty();
}
template <typename T>
void concurrent_queue<T>::clear() {
std::lock_guard<std::mutex> lock(mutex);
queue.clear();
}
template <typename T>
void concurrent_queue<T>::push(const T& value) {
std::lock_guard<std::mutex> lock(mutex);
queue.push_back(value);
}
template <typename T>
bool concurrent_queue<T>::try_pop(T& value) {
std::lock_guard<std::mutex> lock(mutex);
if (queue.empty()) return false;
value = queue.front();
queue.pop_front();
return true;
}

// Run a task asynchronously
template <typename Func, typename... Args>
inline auto run_async(Func&& func, Args&&... args) {
return std::async(std::launch::async, std::forward<Func>(func),
std::forward<Args>(args)...);
}
// Check if an async task is ready
inline bool is_valid(const future<void>& result) { return result.valid(); }
inline bool is_running(const future<void>& result) {
return result.valid() && result.wait_for(std::chrono::microseconds(0)) !=
std::future_status::ready;
}
inline bool is_ready(const future<void>& result) {
return result.valid() && result.wait_for(std::chrono::microseconds(0)) ==
std::future_status::ready;
}

// Simple parallel for used since our target platforms do not yet support
// parallel algorithms. `Func` takes the integer index.
template <typename Func>
inline void parallel_for(int begin, int end, Func&& func) {
auto futures = vector<future<void>>{};
auto nthreads = std::thread::hardware_concurrency();
atomic<int> next_idx(begin);
for (auto thread_id = 0; thread_id < nthreads; thread_id++) {
futures.emplace_back(
std::async(std::launch::async, [&func, &next_idx, end]() {
while (true) {
auto idx = next_idx.fetch_add(1);
if (idx >= end) break;
func(idx);
}
}));
}
for (auto& f : futures) f.get();
}

template <typename Func>
inline void parallel_for(int num, Func&& func) {
parallel_for(0, num, std::forward<Func>(func));
}

// Simple parallel for used since our target platforms do not yet support
// parallel algorithms. `Func` takes a reference to a `T`.
template <typename T, typename Func>
inline void parallel_foreach(vector<T>& values, Func&& func) {
parallel_for(
0, (int)values.size(), [&func, &values](int idx) { func(values[idx]); });
}
template <typename T, typename Func>
inline void parallel_foreach(const vector<T>& values, Func&& func) {
parallel_for(
0, (int)values.size(), [&func, &values](int idx) { func(values[idx]); });
return append(b);
}

} // namespace yocto
Expand Down