What I am trying to do now is to store stored function calls with arguments into a list or vector, retrieve them later, and call them.
What I've got now:
a task class:
struct basic_task
{
virtual ~basic_task()
{
}
virtual void run()
{
std::cout<<"will run basic"<<std::endl;
}
};
template<typename OBJ, typename FUNC, typename ...ARGS>
struct task: basic_task
{
OBJ obj_;
FUNC OBJ::*func_;
std::tuple<ARGS...> args_;
task(OBJ& obj, FUNC OBJ::*func, ARGS ... args) :
obj_(obj), func_(func)
{
args_ = std::make_tuple(std::forward<ARGS>(args)...);
}
virtual ~task()
{
//delete args_;
}
virtual void run()
{
std::cout<<"will run real"<<std::endl;
caller::call(obj_, func_, args_);
}
};
a task binder:
struct task_binder
{
template<typename OBJ, typename FUNC, typename ...ARGS>
static auto bind(OBJ& obj, FUNC OBJ::*func,
ARGS ... args)->task<OBJ,FUNC,ARGS...>
{
task<OBJ, FUNC, ARGS...> result
{ obj, func, args... };
return result;
}
};
And what I am trying to do now is a task_queue class, which stores instances by calling produce, and consume the task by calling consume.
class task_queue: public task_queue_if
{
public:
task_queue() :
flag_(true), cond_(mutex_)
{
}
virtual ~task_queue()
{
}
virtual void close()
{
lock_guard lock(mutex_);
flag_ = false;
cond_.broadcast();
}
virtual void produce(const basic_task& t)
{
lock_guard lock(mutex_);
bool was_empty = task_list_.empty();
task_list_.push_back(t);
if (was_empty)
{
cond_.signal();
}
}
virtual int consume()
{
lock_guard lock(mutex_);
while (task_list_.empty())
{
if (flag_ == false)
return -1;
cond_.wait();
}
basic_task tt = task_list_.front();
task_list_.pop_front();
tt.run() // won't call the stored function call
return 1;
}
private:
volatile bool flag_;
mutex_lock mutex_;
std::list<basic_task> task_list_;
condition_var cond_;
}
So my problem is the consume call will call the basic_task's run() function rather than the one in task. However, if I did not store them as type basic_task but as task, it won't compile. And if I store them as basic_task, when I want to call it, I won't know which type of task should I cast the task to, so it won't compile either. Is there a way to do it?
Thanks.
Aucun commentaire:
Enregistrer un commentaire