dfhack/plugins/channel-safely/include/channel-groups.h

58 lines
2.1 KiB
C

2022-11-06 01:12:35 -06:00
#pragma once
#include "plugin.h"
#include "channel-jobs.h"
#include <df/map_block.h>
#include <df/coord.h>
#include <modules/EventManager.h> //hash functions (they should probably get moved at this point, the ones that aren't specifically for EM anyway)
2022-11-06 01:12:35 -06:00
#include <vector>
#include <unordered_map>
#include <unordered_set>
2022-11-06 01:12:35 -06:00
using namespace DFHack;
using Group = std::set<df::coord>;
2022-11-06 01:12:35 -06:00
using Groups = std::vector<Group>;
/* Used to build groups of adjacent channel designations/jobs
* groups_map: maps coordinates to a group index in `groups`
* groups: list of Groups
* Group: used to track designations which are connected through adjacency to one another (a group cannot span Z)
* Note: a designation plan may become unsafe if the jobs aren't completed in a specific order;
* the easiest way to programmatically ensure safety is to..
* lock overlapping groups directly adjacent across Z until the above groups are complete, or no longer overlap
* groups may no longer overlap if the adjacent designations are completed, but requires a rebuild of groups
* jobs: list of coordinates with channel jobs associated to them
*/
class ChannelGroups {
private:
using GroupBlocks = std::unordered_set<df::map_block*>;
using GroupsMap = std::unordered_map<df::coord, int>;
2022-11-06 12:53:46 -07:00
GroupBlocks group_blocks;
2022-11-06 01:12:35 -06:00
GroupsMap groups_map;
Groups groups;
ChannelJobs &jobs;
std::set<int> free_spots;
protected:
void add(const df::coord &map_pos);
public:
int debugGIndex(const df::coord &map_pos) const {
if (groups_map.count(map_pos)) {
return groups_map.find(map_pos)->second;
}
return -1;
}
2022-11-06 01:12:35 -06:00
explicit ChannelGroups(ChannelJobs &jobs) : jobs(jobs) { groups.reserve(200); }
void scan_one(const df::coord &map_pos);
void scan(bool full_scan = false);
2022-11-06 01:12:35 -06:00
void clear();
void remove(const df::coord &map_pos);
Groups::const_iterator find(const df::coord &map_pos) const;
Groups::const_iterator begin() const;
Groups::const_iterator end() const;
size_t count(const df::coord &map_pos) const;
void debug_groups();
void debug_map();
};