没有未来的编程。然后

时间:2012-12-10 10:22:07

标签: c++ visual-studio-2010 asynchronous concurrency future

我需要写下以下几行:

  
      
  • 缓冲区中的foreach缓冲区:

         
        
    • 在thread0中映射OpenGL缓冲区,然后复制到thread1中的缓冲区,然后在thread1中取消映射缓冲区。
    •   
  •   
  • 当所有缓冲区都未映射时,然后在thread1

  • 中渲染   

这并不像我希望的那样微不足道,future.thenwhen_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);
}

0 个答案:

没有答案