RenderClass с поддержкой Multithread-поддержки, перевод функции в вектор для вызова в другом потоке - PullRequest
2 голосов
/ 19 сентября 2019

Я пытаюсь создать RenderClass, где 1 функция вызывается из потока, который вычисляет все и передает вызовы функций в вектор, в то время как другой поток вызывает функцию RenderClass, которая затем вызывает каждую функцию, которая была помещена в вектор.это вообще возможно?также мой код не дает мне ошибок intellisense в сравнении с какой-то странной ошибкой C3867, которая, на мой взгляд, не имеет смысла при попытке компиляции ..

Я уже пытался поиграться с функцией шаблона, такой как удаление RenderClass :: *работать с

template<typename Function, typename ...ARGS>
    void QueueRenderFunction(Function *function, ARGS... args)

, но не могу заставить его работать: /

здесь вся тестовая программа, которую я тестировал на этом ...

#include <Windows.h>
#include <iostream>
#include <functional>
#include <string>
#include <vector>
#include <mutex>

class Vector3 {
    float x, y, z;
};

class RenderClass
{
public:
    template<typename Function, typename ...ARGS>
    void QueueRenderFunction(Function RenderClass::*function, ARGS... args)
    {
        _RenderList.push_back(std::forward<Function>(function, args...));
    }
    void CallRenderFunctions()
    {
        std::lock_guard<std::recursive_mutex> l(renderlist_mtx);
        for (auto&& Function : RenderList)
            Function();
    }

    //just as examplecode
    void DRAWCIRCLE(Vector3 Position, float Range) {
        std::cout << Range << std::endl;
    }
    void DRAWSTRING(Vector3 Position, std::string String) {
        std::cout << String << std::endl;
    }

    void QueueDrawings() {
        //begin new Renderlist
        _RenderList.clear();
        //some drawing calcs

        //some Position
        Vector3 Position;
        QueueRenderFunction(DRAWCIRCLE, Position, 100.f);
        QueueRenderFunction(DRAWSTRING, Position,"Name");

        std::lock_guard<std::recursive_mutex> l(renderlist_mtx);
        RenderList = _RenderList;
    }

private:
    std::recursive_mutex renderlist_mtx;
    std::vector<std::function<void()>> RenderList;
    std::vector<std::function<void()>> _RenderList;
};

RenderClass* Renderer = new RenderClass();
void Render() {
    while (true)
    {
        Renderer->CallRenderFunctions();
        std::this_thread::sleep_for(std::chrono::milliseconds(1));
    }

}

int main() {
    std::thread RenderThread(Render);
    while (true)
    {
        Renderer->QueueDrawings();
        std::this_thread::sleep_for(std::chrono::milliseconds(1));
    }
    return 0;
}

как я сказал дляПример этой ошибки: Код серьезности Описание Состояние подавления строки файла проекта C3867 'RenderClass :: DRAWCIRCLE': нестандартный синтаксис;используйте '&', чтобы создать указатель на член

, и попытка & DRAWCIRCLE только что дает мне

Ошибка C2276 '&': недопустимая операция с выражением функции связанного члена *

, вот и всечто заставляет меня говорить, что это не имеет смысла, по моему мнению

1 Ответ

1 голос
/ 19 сентября 2019

Ваша проблема в том, что у вас есть std::vector<std::function<void()>>, что нормально, но вам нужно добавить несколько дополнений.std :: bind - ваш друг.

Этот код должен помочь.

template<typename Function, typename ...ARGS>
void QueueRenderFunction(Function function, ARGS... args)
{
    _RenderList.push_back(std::bind(function, args...));
}

Возможно, вы также захотите определить функцию, которую вы поместили в список визуализации, как свободную от функций и передатьчто бы это было в качестве аргумента.

В качестве примечания, вы, вероятно, захотите использовать RenderList.swap(_RenderList); для сокращения копирования.

...