| 402 | } |
| 403 | |
| 404 | bool DFHack::Job::removeJob(df::job* job) { |
| 405 | using df::global::world; |
| 406 | CHECK_NULL_POINTER(job); |
| 407 | |
| 408 | // cancel_job below does not clean up all refs, so we have to do some work |
| 409 | for (auto &item_ref : job->items) { |
| 410 | disconnectJobItem(job, item_ref); |
| 411 | if (item_ref) delete item_ref; |
| 412 | } |
| 413 | job->items.resize(0); |
| 414 | |
| 415 | // call the job cancel vmethod graciously provided by The Toady One. |
| 416 | // job_handler::cancel_job calls job::~job, and then deletes job (this has |
| 417 | // been confirmed by disassembly). |
| 418 | |
| 419 | // HACK: GCC (starting around GCC 10 targeting C++20 as of v50.09) optimizes |
| 420 | // out the vmethod call here regardless of optimization level, so we need to |
| 421 | // invoke the vmethod manually through a pointer, as the Lua wrapper does. |
| 422 | // `volatile` does not seem to be necessary but is included for good |
| 423 | // measure. |
| 424 | volatile auto cancel_job_method = &df::job_handler::cancel_job; |
| 425 | (world->jobs.*cancel_job_method)(job); |
| 426 | |
| 427 | return true; |
| 428 | } |
| 429 | |
| 430 | bool DFHack::Job::addWorker(df::job *job, df::unit *unit){ |
| 431 | CHECK_NULL_POINTER(job); |