overhaul serialization; persist item filters
parent
60de4619a2
commit
4cc262c796
@ -0,0 +1,59 @@
|
||||
#include "buildingplan.h"
|
||||
#include "buildingtypekey.h"
|
||||
|
||||
#include "Debug.h"
|
||||
#include "MiscUtils.h"
|
||||
|
||||
using std::string;
|
||||
using std::vector;
|
||||
|
||||
namespace DFHack {
|
||||
DBG_EXTERN(buildingplan, status);
|
||||
}
|
||||
|
||||
using namespace DFHack;
|
||||
|
||||
// building type, subtype, custom
|
||||
BuildingTypeKey::BuildingTypeKey(df::building_type type, int16_t subtype, int32_t custom)
|
||||
: tuple(type, subtype, custom) { }
|
||||
|
||||
static BuildingTypeKey deserialize(color_ostream &out, const std::string &serialized) {
|
||||
vector<string> key_parts;
|
||||
split_string(&key_parts, serialized, ",");
|
||||
if (key_parts.size() != 3) {
|
||||
WARN(status,out).print("invalid key_str: '%s'\n", serialized.c_str());
|
||||
return BuildingTypeKey(df::building_type::NONE, -1, -1);
|
||||
}
|
||||
return BuildingTypeKey((df::building_type)string_to_int(key_parts[0]),
|
||||
string_to_int(key_parts[1]), string_to_int(key_parts[2]));
|
||||
}
|
||||
|
||||
BuildingTypeKey::BuildingTypeKey(color_ostream &out, const std::string &serialized)
|
||||
:tuple(deserialize(out, serialized)) { }
|
||||
|
||||
string BuildingTypeKey::serialize() const {
|
||||
std::ostringstream ser;
|
||||
ser << std::get<0>(*this) << ",";
|
||||
ser << std::get<1>(*this) << ",";
|
||||
ser << std::get<2>(*this);
|
||||
return ser.str();
|
||||
}
|
||||
|
||||
// rotates a size_t value left by count bits
|
||||
// assumes count is not 0 or >= size_t_bits
|
||||
// replace this with std::rotl when we move to C++20
|
||||
static std::size_t rotl_size_t(size_t val, uint32_t count)
|
||||
{
|
||||
static const int size_t_bits = CHAR_BIT * sizeof(std::size_t);
|
||||
return val << count | val >> (size_t_bits - count);
|
||||
}
|
||||
|
||||
std::size_t BuildingTypeKeyHash::operator() (const BuildingTypeKey & key) const {
|
||||
// cast first param to appease gcc-4.8, which is missing the enum
|
||||
// specializations for std::hash
|
||||
std::size_t h1 = std::hash<int32_t>()(static_cast<int32_t>(std::get<0>(key)));
|
||||
std::size_t h2 = std::hash<int16_t>()(std::get<1>(key));
|
||||
std::size_t h3 = std::hash<int32_t>()(std::get<2>(key));
|
||||
|
||||
return h1 ^ rotl_size_t(h2, 8) ^ rotl_size_t(h3, 16);
|
||||
}
|
@ -0,0 +1,22 @@
|
||||
#pragma once
|
||||
|
||||
#include "df/building_type.h"
|
||||
|
||||
#include <tuple>
|
||||
#include <string>
|
||||
|
||||
namespace DFHack {
|
||||
class color_ostream;
|
||||
}
|
||||
|
||||
// building type, subtype, custom
|
||||
struct BuildingTypeKey : public std::tuple<df::building_type, int16_t, int32_t> {
|
||||
BuildingTypeKey(df::building_type type, int16_t subtype, int32_t custom);
|
||||
BuildingTypeKey(DFHack::color_ostream &out, const std::string & serialized);
|
||||
|
||||
std::string serialize() const;
|
||||
};
|
||||
|
||||
struct BuildingTypeKeyHash {
|
||||
std::size_t operator() (const BuildingTypeKey & key) const;
|
||||
};
|
@ -0,0 +1,60 @@
|
||||
#include "defaultitemfilters.h"
|
||||
|
||||
#include "Debug.h"
|
||||
#include "MiscUtils.h"
|
||||
|
||||
#include "modules/World.h"
|
||||
|
||||
namespace DFHack {
|
||||
DBG_EXTERN(buildingplan, status);
|
||||
}
|
||||
|
||||
using std::string;
|
||||
using std::vector;
|
||||
using namespace DFHack;
|
||||
|
||||
BuildingTypeKey DefaultItemFilters::getKey(PersistentDataItem &filter_config) {
|
||||
return BuildingTypeKey(
|
||||
(df::building_type)get_config_val(filter_config, FILTER_CONFIG_TYPE),
|
||||
get_config_val(filter_config, FILTER_CONFIG_SUBTYPE),
|
||||
get_config_val(filter_config, FILTER_CONFIG_CUSTOM));
|
||||
}
|
||||
|
||||
DefaultItemFilters::DefaultItemFilters(color_ostream &out, BuildingTypeKey key, const std::vector<const df::job_item *> &jitems)
|
||||
: key(key) {
|
||||
DEBUG(status,out).print("creating persistent data for filter key %d,%d,%d\n",
|
||||
std::get<0>(key), std::get<1>(key), std::get<2>(key));
|
||||
filter_config = World::AddPersistentData(FILTER_CONFIG_KEY);
|
||||
set_config_val(filter_config, FILTER_CONFIG_TYPE, std::get<0>(key));
|
||||
set_config_val(filter_config, FILTER_CONFIG_SUBTYPE, std::get<1>(key));
|
||||
set_config_val(filter_config, FILTER_CONFIG_CUSTOM, std::get<2>(key));
|
||||
item_filters.resize(jitems.size());
|
||||
filter_config.val() = serialize_item_filters(item_filters);
|
||||
}
|
||||
|
||||
DefaultItemFilters::DefaultItemFilters(color_ostream &out, PersistentDataItem &filter_config, const std::vector<const df::job_item *> &jitems)
|
||||
: key(getKey(filter_config)), filter_config(filter_config) {
|
||||
auto &serialized = filter_config.val();
|
||||
DEBUG(status,out).print("deserializing item filters for key %d,%d,%d: %s\n",
|
||||
std::get<0>(key), std::get<1>(key), std::get<2>(key), serialized.c_str());
|
||||
std::vector<ItemFilter> filters = deserialize_item_filters(out, serialized);
|
||||
if (filters.size() != jitems.size()) {
|
||||
WARN(status,out).print("ignoring invalid filters_str for key %d,%d,%d: '%s'\n",
|
||||
std::get<0>(key), std::get<1>(key), std::get<2>(key), serialized.c_str());
|
||||
item_filters.resize(jitems.size());
|
||||
} else
|
||||
item_filters = filters;
|
||||
}
|
||||
|
||||
void DefaultItemFilters::setItemFilter(DFHack::color_ostream &out, const ItemFilter &filter, int index) {
|
||||
if (item_filters.size() <= index) {
|
||||
WARN(status,out).print("invalid index for filter key %d,%d,%d: %d\n",
|
||||
std::get<0>(key), std::get<1>(key), std::get<2>(key), index);
|
||||
return;
|
||||
}
|
||||
|
||||
item_filters[index] = filter;
|
||||
filter_config.val() = serialize_item_filters(item_filters);
|
||||
DEBUG(status,out).print("updated item filter and persisted for key %d,%d,%d: %s\n",
|
||||
std::get<0>(key), std::get<1>(key), std::get<2>(key), filter_config.val().c_str());
|
||||
}
|
@ -0,0 +1,24 @@
|
||||
#pragma once
|
||||
|
||||
#include "buildingplan.h"
|
||||
#include "buildingtypekey.h"
|
||||
|
||||
#include "modules/Persistence.h"
|
||||
|
||||
class DefaultItemFilters {
|
||||
public:
|
||||
static BuildingTypeKey getKey(DFHack::PersistentDataItem &filter_config);
|
||||
|
||||
const BuildingTypeKey key;
|
||||
|
||||
DefaultItemFilters(DFHack::color_ostream &out, BuildingTypeKey key, const std::vector<const df::job_item *> &jitems);
|
||||
DefaultItemFilters(DFHack::color_ostream &out, DFHack::PersistentDataItem &filter_config, const std::vector<const df::job_item *> &jitems);
|
||||
|
||||
void setItemFilter(DFHack::color_ostream &out, const ItemFilter &filter, int index);
|
||||
|
||||
const std::vector<ItemFilter> & getItemFilters() const { return item_filters; }
|
||||
|
||||
private:
|
||||
DFHack::PersistentDataItem filter_config;
|
||||
std::vector<ItemFilter> item_filters;
|
||||
};
|
Loading…
Reference in New Issue