AI 24/25 Project Software
Documentation for the AI 24/25 course programming project software
Loading...
Searching...
No Matches
per_task_information.h
1#ifndef PER_TASK_INFORMATION_H
2#define PER_TASK_INFORMATION_H
3
4#include "downward/task_proxy.h"
5
6#include "downward/algorithms/subscriber.h"
7
8#include "downward/utils/hash.h"
9
10#include <functional>
11#include <memory>
12
13/*
14 A PerTaskInformation<T> acts like a HashMap<TaskID, T>
15 with two main differences:
16 (1) If an entry is accessed that does not exist yet, it is created using a
17 factory function that is passed to the PerTaskInformation in its
18 constructor.
19 (2) If a task is destroyed, its associated data in all PerTaskInformation
20 objects is automatically destroyed as well.
21
22*/
23template <class Entry>
24class PerTaskInformation : public subscriber::Subscriber<PlanningTask> {
25 /*
26 EntryConstructor is the type of a function that can create objects for
27 a given task if the PerTaskInformation is accessed for a task that has no
28 associated entry yet. It receives a TaskProxy instead of the AbstractTask
29 because AbstractTask is an internal implementation detail as far as other
30 classes are concerned. It should return a unique_ptr to the newly created
31 object.
32 */
33 using EntryConstructor =
34 std::function<std::unique_ptr<Entry>(const PlanningTaskProxy&)>;
35 EntryConstructor entry_constructor;
36 utils::HashMap<TaskID, std::unique_ptr<Entry>> entries;
37
38public:
39 /*
40 If no entry_constructor is passed to the PerTaskInformation explicitly,
41 we assume the class Entry has a constructor that takes a single
42 PlanningTaskProxy parameter.
43 */
44 PerTaskInformation()
45 : entry_constructor([](const PlanningTaskProxy& task_proxy) {
46 return std::make_unique<Entry>(task_proxy);
47 })
48 {
49 }
50
51 explicit PerTaskInformation(EntryConstructor entry_constructor)
52 : entry_constructor(entry_constructor)
53 {
54 }
55
56 Entry& operator[](const PlanningTaskProxy& task_proxy)
57 {
58 TaskID id = task_proxy.get_id();
59 const auto& it = entries.find(id);
60 if (it == entries.end()) {
61 entries[id] = entry_constructor(task_proxy);
62 task_proxy.subscribe_to_task_destruction(this);
63 }
64 return *entries[id];
65 }
66
67 virtual void notify_service_destroyed(const PlanningTask* task) override
68 {
69 TaskID id = PlanningTaskProxy(*task).get_id();
70 entries.erase(id);
71 }
72};
73
74#endif