11#include < active-job-manager.h>
22#include < inlines.h>
3+ #include < on-tick.h>
34#include < ranges>
45
56#include < tile-cache.h>
1112#include < df/report.h>
1213
1314namespace CSP {
15+ extern OnTick tick_it_master;;
1416 extern std::unordered_set<df::coord> dignow_queue;
1517}
1618
@@ -141,23 +143,17 @@ void ActiveJobManager::cleanup() {
141143}
142144
143145void ActiveJobManager::on_update (color_ostream &out) {
146+ INFO (jobs).print (" onUpdate()" );
144147 int32_t tick = df::global::world->frame_counter ;
145148 // clean up stale df::job*
146149 if ((config.monitoring || config.resurrect ) && tick - last_tick >= 1 ) {
147150 last_tick = tick;
148151 cleanup ();
149152 }
150- // cancel jobs in the cancel queue
151- for (auto pos : cancel_queue) {
152- cancel_job (pos);
153- if (!ChannelManager::Get ().manage_one (pos, true , true )) {
154- DEBUG (jobs).print (" <- JobStartedEvent(): failed to cancel a job and marker the designation." );
155- }
156- }
157- cancel_queue.clear ();
153+
158154
159155 // monitoring activity
160- if (config.monitoring && tick - last_monitor_tick >= config.monitor_freq ) {
156+ if (config.monitoring && tick - last_monitor_tick >= 666 ){ // config.monitor_freq) {
161157 last_monitor_tick = tick;
162158 TRACE (monitor).print (" OnUpdate() monitoring now\n " );
163159
@@ -166,70 +162,39 @@ void ActiveJobManager::on_update(color_ostream &out) {
166162 if unlikely (!ajob.worker ) continue ;
167163 if unlikely (!Units::isAlive (ajob.worker )) continue ;
168164 if unlikely (!Maps::isValidTilePos (ajob.pos )) continue ;
165+ if likely (ajob.worker ->pos != ajob.pos ) continue ;
166+ if likely (is_safe_fall (ajob.pos )) continue ;
169167
170- // check for fall safety
171- if (ajob.worker ->pos == ajob.pos && !is_safe_fall (ajob.pos )) {
172- // unsafe
173- WARN (monitor).print (" -> unsafe job\n " );
174- Job::removeWorker (ajob.job );
175-
176- // decide to insta-dig, marker mode, or break a few eggs to get it done before unbreaking them
177- if (config.insta_dig ) {
178- // delete the job
179- Job::removeJob (ajob.job );
180- // queue digging the job instantly
181- CSP::dignow_queue.emplace (ajob.pos );
182- DEBUG (monitor).print (" -> insta-dig\n " );
183- } else if (!config.resurrect ) {
184- // set marker mode
185- Maps::getTileOccupancy (ajob.pos )->bits .dig_marked = true ;
186-
187- using df_bsedp = df::block_square_event_designation_priorityst;
188- // prevent algorithm from re-enabling designation
189- for (auto &blk_evt: Maps::getBlock (ajob.pos )->block_events ) {
190- if (auto bsedp = virtual_cast<df_bsedp>(blk_evt)) {
191- df::coord local (ajob.pos );
192- local.x = local.x % 16 ;
193- local.y = local.y % 16 ;
194- bsedp->priority [Coord (local)] = config.ignore_threshold * 1000 + 1 ;
195- break ;
196- }
168+ // unsafe
169+ WARN (monitor).print (" -> unsafe job\n " );
170+ Job::removeWorker (ajob.job );
171+
172+ if (!config.resurrect ) {
173+ // set marker mode
174+ Maps::getTileOccupancy (ajob.pos )->bits .dig_marked = true ;
175+
176+ using df_bsedp = df::block_square_event_designation_priorityst;
177+ // prevent algorithm from re-enabling designation
178+ for (auto &blk_evt: Maps::getBlock (ajob.pos )->block_events ) {
179+ if (auto bsedp = virtual_cast<df_bsedp>(blk_evt)) {
180+ df::coord local (ajob.pos );
181+ local.x = local.x % 16 ;
182+ local.y = local.y % 16 ;
183+ bsedp->priority [Coord (local)] = config.ignore_threshold * 1000 + 1 ;
184+ break ;
197185 }
198- DEBUG (monitor).print (" -> set marker mode\n " );
199186 }
187+ DEBUG (monitor).print (" -> set marker mode\n " );
200188 }
201189 }
202190 TRACE (monitor).print (" OnUpdate() monitoring done\n " );
203191 }
204-
205- // Resurrect Dead Workers
206- if (config.resurrect && tick - last_resurrect_tick >= 1 ) {
207- last_resurrect_tick = tick;
208- for (auto [id, aworker] : active_workers) {
209- if (Units::isAlive (aworker.worker )) {
210- continue ;
211- }
212- resurrect (out, aworker.id );
213- df::coord lowest = simulate_fall (aworker.last_safe_pos );
214- Units::teleport (aworker.worker , lowest);
215- }
216- // resurrect any dead endangered units
217- for (auto unit : df::global::world->units .all ) {
218- if (!endangered_units.contains (unit->id ) || !safe_locations.contains (unit->id )) {
219- continue ;
220- }
221- if (Units::isAlive (unit)) {
222- continue ;
223- }
224- resurrect (out, unit->id );
225- df::coord lowest = simulate_fall (safe_locations[unit->id ]);
226- Units::teleport (unit, lowest);
227- }
228- }
229192}
230193
194+ extern DFHack::EventManager::EventHandler resurrectHandler;
195+
231196void ActiveJobManager::on_job_start (df::job* job) {
232- if (!ChannelManager::Get ().exists (job->pos )) {
197+ if (!ChannelManager::Get ().contains (job->pos )) {
233198 ChannelManager::Get ().build_groups (false );
234199 }
235200 df::unit* worker = Job::getWorker (job);
@@ -246,6 +211,11 @@ void ActiveJobManager::on_job_start(df::job* job) {
246211 active_jobs.emplace (ajob.id ,ajob);
247212 active_workers.emplace (ajob.id , aworker);
248213 safe_locations[aworker.id ] = aworker.last_safe_pos ;
214+ if (config.resurrect && !CSP::tick_it_master.resurrect_queued ) {
215+ CSP::tick_it_master.resurrect_queued = true ;
216+ // todo: verify this means NEXT tick.. or just use 0
217+ EventManager::registerTick (resurrectHandler,1 );
218+ }
249219 }
250220 // cavein prevention is the rest of the function
251221 if (!config.riskaverse ) {
@@ -352,13 +322,76 @@ void ActiveJobManager::on_report_event(df::report* report) {
352322 DEBUG (plugin).print (" [id %d] is/was an endangereed worker, we'll extend tracking them too.\n " , aworker.id );
353323 }
354324 }
325+ if (!CSP::tick_it_master.resurrect_queued ) {
326+ CSP::tick_it_master.resurrect_queued = true ;
327+ // todo: verify this means NEXT tick.. or just use 0
328+ EventManager::registerTick (resurrectHandler,1 );
329+ }
355330 }
356331 break ;
357332 default :
358333 break ;
359334 }
360335}
361336
337+ extern DFHack::EventManager::EventHandler cancelHandler;
338+
339+ void ActiveJobManager::cancel (df::coord site) {
340+ if (!CSP::tick_it_master.cancel_queued ) {
341+ CSP::tick_it_master.cancel_queued = true ;
342+ // todo: verify this means NEXT tick.. or just use 0
343+ EventManager::registerTick (cancelHandler,1 );
344+ }
345+ cancel_queue.emplace (site);
346+ }
347+
348+ void ActiveJobManager::handle_cancellation () {
349+ // cancel jobs in the cancel queue
350+ ChannelJobs jobs;
351+ jobs.load_channel_jobs ();
352+ for (auto pos : cancel_queue) {
353+ INFO (jobs).print (" Canceling job: " COORD, COORDARGS (pos));
354+ if (auto job_ptr = jobs.find_job (pos); job_ptr) {
355+ if unlikely (job_ptr->id < 0 ) {
356+ Job::removePostings (job_ptr, true );
357+ revert_designation (pos, job_ptr->job_type );
358+ continue ;
359+ }
360+ Job::removeWorker (job_ptr);
361+ Job::removePostings (job_ptr, true );
362+ Job::removeJob (job_ptr);
363+ revert_designation (pos, job_ptr->job_type );
364+ }
365+ }
366+ cancel_queue.clear ();
367+ }
368+
369+ void ActiveJobManager::handle_resurrect (color_ostream &out) {
370+ if (!config.resurrect ) {
371+ return ;
372+ }
373+ for (auto [id, aworker] : active_workers) {
374+ if (Units::isAlive (aworker.worker )) {
375+ continue ;
376+ }
377+ resurrect (out, aworker.id );
378+ df::coord lowest = simulate_fall (aworker.last_safe_pos );
379+ Units::teleport (aworker.worker , lowest);
380+ }
381+ // resurrect any dead endangered units
382+ for (auto unit : df::global::world->units .all ) {
383+ if (!endangered_units.contains (unit->id ) || !safe_locations.contains (unit->id )) {
384+ continue ;
385+ }
386+ if (Units::isAlive (unit)) {
387+ continue ;
388+ }
389+ resurrect (out, unit->id );
390+ df::coord lowest = simulate_fall (safe_locations[unit->id ]);
391+ Units::teleport (unit, lowest);
392+ }
393+ }
394+
362395void ActiveJobManager::clear () {
363396 safe_locations.clear ();
364397 endangered_units.clear ();
@@ -368,3 +401,7 @@ void ActiveJobManager::clear() {
368401 cancel_queue.clear ();
369402}
370403
404+ bool ActiveJobManager::needs_resurrect_queued () {
405+ return !active_workers.empty () || !endangered_units.empty ();
406+ }
407+
0 commit comments