z_mirror/TaskList

git clone https://git.raiguard.me/z_mirror/TaskList

Caleb HeuerCheck owner validity before updating their GUIf0b1802

fix/blueprint-sandboxes-force
4.4 KiB182 linesraw
1local table = require("__flib__/table")
2
3local util = require("__TaskList__/scripts/util")
4
5--- @alias TaskID integer
6
7--- @class Task: LuaObject
8--- @field assignee LuaPlayer?
9--- @field completed boolean
10--- @field completed_tasks TaskID[]
11--- @field description string
12--- @field id TaskID
13--- @field object_name "Task"
14--- @field owner LuaForce|LuaPlayer|Task
15--- @field owner_table ForceTable|PlayerTable|Task
16--- @field status string
17--- @field tasks TaskID[]
18--- @field title string
19local Task = {}
20
21--- Update the task info and refresh all GUIs
22--- @param title string
23--- @param description string
24--- @param assignee LuaPlayer|nil
25--- @param status string
26function Task:update(title, description, assignee, status)
27  self.title = title
28  self.description = description
29  self.assignee = assignee
30  self.status = status
31
32  self:update_guis(function(Gui)
33    Gui:update_task(self)
34  end)
35end
36
37--- Delete the task and remove it from all GUIs.
38function Task:delete()
39  for _, subtasks in pairs({ self.completed_tasks, self.tasks }) do
40    for _, task_id in pairs(subtasks) do
41      local subtask = global.tasks[task_id]
42      if subtask then
43        subtask:delete()
44      end
45    end
46  end
47
48  global.tasks[self.id] = nil
49
50  local owner_table = self.owner_table
51  local tasks_table = owner_table[self.completed and "completed_tasks" or "tasks"]
52  table.remove(tasks_table, table.find(tasks_table, self.id))
53
54  self:update_guis(function(Gui)
55    Gui:delete_task(self)
56  end)
57end
58
59function Task:toggle_completed()
60  local owner_table = self.owner_table
61
62  self.completed = not self.completed
63
64  if self.completed then
65    util.remove_task(owner_table.tasks, self.id)
66    table.insert(owner_table.completed_tasks, 1, self.id)
67  else
68    util.remove_task(owner_table.completed_tasks, self.id)
69    table.insert(owner_table.tasks, self.id)
70  end
71
72  self:update_guis(function(Gui)
73    Gui:delete_task(self, not self.completed)
74    Gui:add_task(self, self.completed and 1 or nil)
75  end)
76end
77
78--- @param delta number
79function Task:move(delta)
80  local tasks_table = self.owner_table[self.completed and "completed_tasks" or "tasks"]
81  local index = table.find(tasks_table, self.id)
82  if index then
83    if index + delta > 0 and index + delta <= #tasks_table then
84      tasks_table[index] = tasks_table[index + delta]
85      tasks_table[index + delta] = self.id
86
87      self:update_guis(function(Gui)
88        Gui:move_task(self, delta)
89      end)
90    end
91  end
92end
93
94--- @param callback fun(Gui: EditTaskGui|TasksGui)
95function Task:update_guis(callback)
96  local players = {}
97
98  -- Get ultimate owner
99  local owner = self.owner
100  while owner.object_name == "Task" do
101    owner = owner.owner
102  end
103
104  if owner.object_name == "LuaForce" then
105    for player_index, player in pairs(game.players) do
106      if util.get_force(player).index == owner.index then
107        table.insert(players, player_index)
108      end
109    end
110  elseif owner.valid then
111    players = { owner.index }
112  end
113
114  for _, player_index in pairs(players) do
115    local Gui = util.get_gui(player_index, "tasks")
116    if Gui then
117      callback(Gui)
118    end
119  end
120end
121
122local task = {}
123
124--- @param title string
125--- @param description string
126--- @param owner LuaForce|LuaPlayer|Task
127--- @param assignee LuaPlayer|nil
128--- @param status string
129--- @param add_to_top boolean
130function task.new(title, description, owner, assignee, status, add_to_top)
131  local id = global.next_task_id
132  global.next_task_id = id + 1
133
134  local owner_table
135
136  if owner.object_name == "Task" then
137    owner_table = owner
138  elseif owner.object_name == "LuaForce" then
139    owner_table = global.forces[owner.index]
140  else
141    owner_table = global.players[owner.index]
142  end
143
144  --- If `owner` is a `LuaPlayer`, then `assignee` will always be the same `LuaPlayer`.
145  --- @type Task
146  local self = {
147    assignee = assignee,
148    completed = false,
149    completed_tasks = {},
150    description = description,
151    id = id,
152    object_name = "Task",
153    owner = owner,
154    owner_table = owner_table,
155    status = status,
156    tasks = {},
157    title = title,
158  }
159
160  if add_to_top then
161    table.insert(owner_table.tasks, 1, self.id)
162  else
163    table.insert(owner_table.tasks, self.id)
164  end
165
166  task.load(self)
167
168  global.tasks[id] = self
169
170  self:update_guis(function(Gui)
171    Gui:add_task(self, add_to_top and 1 or nil)
172  end)
173
174  return self
175end
176
177--- @param self Task
178function task.load(self)
179  setmetatable(self, { __index = Task })
180end
181
182return task