我需要写下以下几行:
缓冲区中的foreach缓冲区:
- 在thread0中映射OpenGL缓冲区,然后复制到thread1中的缓冲区,然后在thread1中取消映射缓冲区。
- 中渲染
当所有缓冲区都未映射时,然后在thread1
这并不像我希望的那样微不足道,future.then
和when_all
这将非常简单。但是,目前我在下面的内容中找到了一些相当难看的内容,请参阅底部的upload_to_buffers
。它有点工作,但它很快变得相当难以管理和不可读(一切都需要以相反的顺序编写),我不确定这个解决方案的安全性。关于如何以更好的方式实现这一目标的任何想法?
template<typename T>
class async_result
{
public:
async_result(T value)
: value_(std::move(value))
{
}
async_result(std::exception_ptr exception)
: exception_(exception)
{
}
T& get()
{
if(exception_)
std::rethrow_exception(exception_);
return *value_;
}
const T& get() const
{
if(exception_)
std::rethrow_exception(exception_);
return *value_;
}
private:
boost::optional<T> value_;
std::exception_ptr exception_;
};
template<typename C>
void map(buffer buf, C callback)
{
thread0.execute([=]
{
try
{
// Do map.
callback(async_result<buffer>(std::move(buf)));
}
catch(...)
{
callback(async_result<buffer>(std::current_exception()));
}
});
}
template<typename C>
void copy(buffer buf, C callback)
{
thread1.execute([=]
{
try
{
// Do copy.
callback(async_result<buffer>(std::move(buf)));
}
catch(...)
{
callback(async_result<buffer>(std::current_exception()));
}
});
}
template<typename C>
void unmap(buffer buf, C callback)
{
thread0.execute([=]
{
try
{
// Do unmap.
callback(async_result<buffer>(std::move(buf)));
}
catch(...)
{
callback(async_result<buffer>(std::current_exception()));
}
});
}
template<typename C>
void upload_to_buffers(std::vector<buffer> buffers, C callback)
{
auto unmap_buffer_results = std::make_shared<std::vector<async_result<buffer>>();
auto unmap_buffer_results_count = buffers.size();
auto on_unmap_buffer = [=](async_result<buffer> result)
{
unmap_buffer_results->push_back(std::move(result));
if(unmap_buffer_results->size() != unmap_buffer_results_count )
return;
std::vector<buffer> buffers;
for(auto& result : *unmap_buffer_results)
buffers.push_back(std::move(result.get()));
callback(std::move(buffers);
};
auto copy_buffer_results = std::make_shared<std::vector<async_result<buffer>>();
auto copy_buffer_results_count = buffers.size();
auto on_copy_buffer = [=](async_result<buffer> result)
{
copy_buffer_results->push_back(std::move(result));
if(copy_buffer_results->size() != copy_buffer_results_count)
return;
std::vector<buffer> buffers;
for(auto& result : *copy_buffer_results)
buffers.push_back(std::move(result.get()));
for(auto& buf: buffers)
unmap(std::move(buf), on_unmap_buffer);
};
auto map_buffer_results = std::make_shared<std::vector<async_result<buffer>>();
auto map_buffer_results_count = buffers.size();
auto on_mapped_buffer = [=](async_result<buffer> result)
{
map_buffer_results->push_back(std::move(result));
if(map_buffer_results->size() != map_buffer_results_count)
return;
std::vector<buffer> buffers;
for(auto& result : *map_buffer_results)
buffers.push_back(std::move(result.get()));
for(auto& buf: buffers)
copy(std::move(buf), on_copy_buffer);
};
for(auto& buf : buffers)
map(std::move(buf), on_mapped_buffer);
}