2

非常に単純なスケジューラを構築しようとしています。タスク (関数) をリストに追加し、設定した間隔で実行できます。「ScheduleTask」メンバーへの引数として静的関数を指定すると、「Scheduler」クラスは正常に動作します。

class TestController
{
private:
    Scheduler _scheduler;

public:
    TestController(void)
    {
        _scheduler.ScheduleTask(Task1, 3000);
        _scheduler.ScheduleTask(Task2, 5000);
    }
    ~TestController(void);

    void Task1(void) { }
    void Task2(void) { }
};

struct Task
{
    long interval;
    long last_run;
    void (*TaskCallback) (void);

    Task()
    {
        last_run = 0;
    }
};

class Scheduler
{
private:
    std::vector<Task> _tasks;
public:
    Scheduler(void) { }
    ~Scheduler(void) { }

    void ScheduleTask(void (*TaskCallback) (void), long interval)
    {
        Task t;
        t.TaskCallback = TaskCallback;
        t.interval = interval;
        _tasks.push_back(t);
    }

    void loop()
    {
        for(unsigned int i = 0; i < _tasks.size(); i++)
        {
            long elapsed = clock();

            if(elapsed - _tasks[i].last_run >= _tasks[i].interval)
            {
                _tasks[i].last_run = elapsed;
                _tasks[i].TaskCallback();
            }
        }
    }

};

既にインスタンス化された「TestController」オブジェクトのメンバーを受け入れるようにコールバックを変更するにはどうすればよいですか?

4

1 に答える 1

1

との組み合わせを使用しboost::functionますboost::bind。または、コンパイラがそれらをサポートしている場合は、 std::functionandを使用します。std::bind

#include <boost/bind.hpp>
#include <boost/function.hpp>

#include <vector>

typedef boost::function<void()> Callback;

struct Task
{
    long interval;
    long last_run;
    Callback TaskCallback;

    Task()
    {
        last_run = 0;
    }
};

class Scheduler
{
private:
    std::vector<Task> _tasks;
public:
    Scheduler(void) { }
    ~Scheduler(void) { }

    void ScheduleTask(const Callback& TaskCallback, long interval)
    {
        Task t;
        t.TaskCallback = TaskCallback;
        t.interval = interval;
        _tasks.push_back(t);
    }

    void loop()
    {
        for(unsigned int i = 0; i < _tasks.size(); i++)
        {
            long elapsed = clock();

            if(elapsed - _tasks[i].last_run >= _tasks[i].interval)
            {
                _tasks[i].last_run = elapsed;
                _tasks[i].TaskCallback();
            }
        }
    }
};

class TestController
{
private:
    Scheduler _scheduler;

public:
    TestController(void)
    {
        _scheduler.ScheduleTask(boost::bind(&TestController::Task1,this), 3000);
        _scheduler.ScheduleTask(boost::bind(&TestController::Task2,this), 5000);
    }
    ~TestController(void);

    void Task1(void) { }
    void Task2(void) { }
};
于 2012-12-16T21:48:22.173 に答える