Skip to content

Commit b5974be

Browse files
committed
Implement owner and auto deleter for tasks in DirectObject
1 parent 6bf8bff commit b5974be

File tree

3 files changed

+57
-11
lines changed

3 files changed

+57
-11
lines changed

render_pipeline/rppanda/showbase/direct_object.hpp

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,19 @@ namespace rppanda {
5757
class RENDER_PIPELINE_DECL DirectObject : public TypedReferenceCount
5858
{
5959
public:
60+
DirectObject() = default;
61+
DirectObject(const DirectObject&) = delete;
62+
#if !defined(_MSC_VER) || _MSC_VER >= 1900
63+
DirectObject(DirectObject&&);
64+
#endif
65+
6066
virtual ~DirectObject();
6167

68+
DirectObject& operator=(const DirectObject&) = delete;
69+
#if !defined(_MSC_VER) || _MSC_VER >= 1900
70+
DirectObject& operator=(DirectObject&&);
71+
#endif
72+
6273
ALLOC_DELETED_CHAIN(DirectObject);
6374

6475
void accept(const std::string& ev_name, const Messenger::EventFunction& func);
@@ -107,9 +118,23 @@ class RENDER_PIPELINE_DECL DirectObject : public TypedReferenceCount
107118
void remove_all_tasks();
108119

109120
private:
121+
class TaskContainer : public WeakPointerCallback
122+
{
123+
public:
124+
TaskContainer(DirectObject* owner, AsyncTask* task);
125+
void wp_callback(void*) final { owner_->task_list_.erase(task_id_); }
126+
127+
WPT(AsyncTask) task_;
128+
129+
private:
130+
DirectObject* owner_;
131+
AtomicAdjust::Integer task_id_; // While destructing AsyncTask, ID already is deleted
132+
// So, we save it.
133+
};
134+
110135
void do_add_task(AsyncTask* task);
111136

112-
std::unordered_map<AtomicAdjust::Integer, PT(AsyncTask)> task_list_;
137+
std::unordered_map<AtomicAdjust::Integer, TaskContainer> task_list_;
113138

114139
public:
115140
static TypeHandle get_class_type();

render_pipeline/rppanda/task/task_manager.hpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -198,9 +198,9 @@ class RENDER_PIPELINE_DECL TaskManager : public TypedObject
198198
size_t remove_task_matching(const GlobPattern& task_pattern);
199199

200200
private:
201-
AsyncTask* setup_task(AsyncTask* task, const std::string& name = {},
202-
boost::optional<int> sort = boost::none, boost::optional<int> priority = boost::none,
203-
const boost::optional<std::string>& task_chain = boost::none);
201+
AsyncTask* setup_task(AsyncTask* task, const std::string& name,
202+
boost::optional<int> sort, boost::optional<int> priority,
203+
const boost::optional<std::string>& task_chain);
204204

205205
AsyncTaskManager* mgr_;
206206
ClockObject* global_clock_;

src/rppanda/showbase/direct_object.cpp

Lines changed: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -44,13 +44,28 @@
4444

4545
namespace rppanda {
4646

47+
DirectObject::TaskContainer::TaskContainer(DirectObject* owner, AsyncTask* task) : owner_(owner), task_(task), task_id_(task->get_task_id())
48+
{
49+
task_.set_callback(this);
50+
}
51+
52+
// ************************************************************************************************
53+
4754
TypeHandle DirectObject::type_handle_;
4855

56+
#if !defined(_MSC_VER) || _MSC_VER >= 1900
57+
DirectObject::DirectObject(DirectObject&&) = default;
58+
#endif
59+
4960
DirectObject::~DirectObject()
5061
{
5162
ignore_all();
5263
}
5364

65+
#if !defined(_MSC_VER) || _MSC_VER >= 1900
66+
DirectObject& DirectObject::operator=(DirectObject&&) = default;
67+
#endif
68+
5469
void DirectObject::accept(const std::string& ev_name, const Messenger::EventFunction& func)
5570
{
5671
Messenger::get_global_instance()->accept(ev_name, func, this, true);
@@ -113,31 +128,37 @@ FunctionalTask* DirectObject::do_method_later(float delay_time,
113128

114129
void DirectObject::remove_task(const std::string& task_name)
115130
{
116-
for (const auto& task: task_list_)
131+
for (const auto& task_container: task_list_)
117132
{
118-
if (task.second->get_name() == task_name)
119-
remove_task(task.second);
133+
auto& task = task_container.second.task_;
134+
if (task->get_name() == task_name)
135+
remove_task(task);
120136
}
121137
}
122138

123139
void DirectObject::remove_task(AsyncTask* task)
124140
{
125-
auto id = task->get_task_id();
141+
task_list_.erase(task->get_task_id());
126142
task->remove();
127-
task_list_.erase(id);
128143
}
129144

130145
void DirectObject::remove_all_tasks()
131146
{
147+
std::vector<AsyncTask*> tasks;
148+
tasks.reserve(task_list_.size());
132149
for (const auto& task : task_list_)
133-
task.second->remove();
150+
tasks.push_back(task.second.task_.p());
151+
134152
task_list_.clear();
153+
154+
for (const auto& task : tasks)
155+
task->remove();
135156
}
136157

137158
void DirectObject::do_add_task(AsyncTask* task)
138159
{
139160
#if !defined(_MSC_VER) || _MSC_VER >= 1900
140-
task_list_.insert_or_assign(task->get_task_id(), task);
161+
task_list_.insert_or_assign(task->get_task_id(), TaskContainer(this, task));
141162
#else
142163
task_list_[task->get_task_id()] = task;
143164
#endif

0 commit comments

Comments
 (0)