uniques.h 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. #ifndef __UNIQUES_H
  2. #define __UNIQUES_H
  3. #include <time.h>
  4. #include <sstream>
  5. #include <mutex>
  6. #include <unordered_map>
  7. #include "items.h"
  8. #include "worldkey.h"
  9. namespace uniques {
  10. using key_t = worldkey::key_t;
  11. struct Uniques {
  12. std::unordered_map< key_t, std::vector<items::Item> > data;
  13. std::string filename;
  14. Uniques(const std::string& fn) : filename(fn) {}
  15. size_t series;
  16. time_t placetime;
  17. std::mutex mutex;
  18. void load() {
  19. std::unique_lock<std::mutex> l(mutex);
  20. try {
  21. serialize::Source source(filename);
  22. serialize::read(source, data);
  23. serialize::read(source, series);
  24. serialize::read(source, placetime);
  25. } catch (...) {
  26. data.clear();
  27. series = 1;
  28. placetime = 0;
  29. }
  30. }
  31. private:
  32. void write() {
  33. serialize::Sink sink(filename);
  34. serialize::write(sink, data);
  35. serialize::write(sink, series);
  36. serialize::write(sink, placetime);
  37. }
  38. public:
  39. std::vector<items::Item> get(int wx, int wy, int wz, size_t& out_series) {
  40. std::unique_lock<std::mutex> l(mutex);
  41. auto i = data.find(key_t(wx, wy, wz));
  42. if (i == data.end())
  43. return std::vector<items::Item>();
  44. auto ret = i->second;
  45. out_series = series;
  46. data.erase(i);
  47. write();
  48. return ret;
  49. }
  50. void put(int wx, int wy, int wz, const std::vector<items::Item>& i, size_t in_series) {
  51. std::unique_lock<std::mutex> l(mutex);
  52. if (series != in_series) {
  53. return;
  54. }
  55. auto& v = data[key_t(wx, wy, wz)];
  56. v.insert(v.end(), i.begin(), i.end());
  57. placetime = ::time(NULL);
  58. write();
  59. }
  60. bool generate(time_t timeout, size_t& out_series) {
  61. time_t now = ::time(NULL);
  62. std::unique_lock<std::mutex> l(mutex);
  63. if (data.empty() && (now - placetime) > timeout) {
  64. placetime = now;
  65. ++series;
  66. out_series = series;
  67. write();
  68. return true;
  69. }
  70. return false;
  71. }
  72. void locate(time_t& time, std::vector<key_t>& levels) {
  73. std::unique_lock<std::mutex> l(mutex);
  74. time = placetime;
  75. for (const auto& i : data) {
  76. levels.push_back(i.first);
  77. }
  78. }
  79. };
  80. Uniques& uniques() {
  81. static Uniques ret("uniques.dat");
  82. return ret;
  83. }
  84. Uniques& items() {
  85. static Uniques ret("permaitems.dat");
  86. return ret;
  87. }
  88. }
  89. #endif