Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix map locations with ref sections not being updated #94

Merged
merged 1 commit into from
Jan 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions src/core/location.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -458,6 +458,7 @@ json LocationSection::save() const
{"cleared", _itemCleared}
};
}

bool LocationSection::load(json& j)
{
if (j.type() == json::value_t::object) {
Expand All @@ -471,6 +472,13 @@ bool LocationSection::load(json& j)
return false;
}

bool LocationSection::operator<(const LocationSection& rhs) const
{
if (this->getParentID() == rhs.getParentID())
return this->getName() < rhs.getName();
return this->getParentID() < rhs.getParentID();
}


#ifndef NDEBUG
#include <stdio.h>
Expand Down
2 changes: 2 additions & 0 deletions src/core/location.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ class LocationSection final : public LuaInterface<LocationSection> {
virtual nlohmann::json save() const;
virtual bool load(nlohmann::json& j);

bool operator<(const LocationSection& rhs) const;

protected: // lua interface
static constexpr const char Lua_Name[] = "LocationSection";
static const LuaInterface::MethodMap Lua_Methods;
Expand Down
47 changes: 43 additions & 4 deletions src/core/tracker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,7 @@ bool Tracker::AddLocations(const std::string& file) {

_reachableCache.clear();
_providerCountCache.clear();
_sectionRefs.clear();
for (auto& loc : Location::FromJSON(j, _locations)) {
// find duplicate, warn and merge
#ifdef MERGE_DUPLICATE_LOCATIONS // this should be default in the future
Expand Down Expand Up @@ -329,10 +330,12 @@ bool Tracker::AddLocations(const std::string& file) {
#endif
_locations.push_back(std::move(loc)); // TODO: move constructor
for (auto& sec : _locations.back().getSections()) {
if (!sec.getRef().empty())
_sectionNameRefs[sec.getRef()].push_back(_locations.back().getID() + "/" + sec.getName());
sec.onChange += {this,[this,&sec](void*){ onLocationSectionChanged.emit(this, sec); }};
}
}

onLayoutChanged.emit(this, ""); // TODO: differentiate between structure and content
return false;
}
Expand Down Expand Up @@ -570,7 +573,7 @@ Location& Tracker::getLocation(const std::string& id, bool partialMatch)
return blankLocation;
}

LocationSection& Tracker::getLocationSection(const std::string& id)
std::pair<Location&, LocationSection&> Tracker::getLocationAndSection(const std::string& id)
{
const char *start = id.c_str();
const char *t = strrchr(start, '/');
Expand All @@ -581,11 +584,47 @@ LocationSection& Tracker::getLocationSection(const std::string& id)
auto& loc = getLocation(locid, true);
for (auto& sec: loc.getSections()) {
if (sec.getName() != secname) continue;
return sec;
return {loc, sec};
}
}
return {blankLocation, blankLocationSection};
}

LocationSection& Tracker::getLocationSection(const std::string& id)
{
return getLocationAndSection(id).second;
}

const std::vector<std::pair<std::reference_wrapper<const Location>, std::reference_wrapper<const LocationSection>>>&
Tracker::getReferencingSections(const LocationSection& sec)
{
static std::vector<std::pair<std::reference_wrapper<const Location>, std::reference_wrapper<const LocationSection>>>
blank = {};

if (_sectionRefs.empty() && !_sectionNameRefs.empty())
rebuildSectionRefs();

auto it = _sectionRefs.find(sec);
if (it != _sectionRefs.end()) {
return it->second;
}
return blank;
}

void Tracker::rebuildSectionRefs()
{
_sectionRefs.clear();
for (const auto& pair: _sectionNameRefs) {
const auto& target = getLocationSection(pair.first);
if (target.getName().empty())
continue;
for (const auto& sourceName: pair.second) {
const auto& source = getLocationAndSection(sourceName);
if (source.second.getRef().empty())
continue;
_sectionRefs[target].push_back(source);
}
}
return blankLocationSection;
}

const Pack* Tracker::getPack() const
Expand Down
11 changes: 11 additions & 0 deletions src/core/tracker.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include "signal.h"
#include <string>
#include <list>
#include <functional>
#include <cstddef> // nullptr_t
#include <nlohmann/json.hpp>

Expand Down Expand Up @@ -81,7 +82,10 @@ class Tracker final : public LuaInterface<Tracker> {
std::list<std::string> getMapNames() const;
std::list< std::pair<std::string, Location::MapLocation> > getMapLocations(const std::string& mapname) const;
Location& getLocation(const std::string& name, bool partialMatch=false);
std::pair<Location&, LocationSection&> getLocationAndSection(const std::string& id);
LocationSection& getLocationSection(const std::string& id);
const std::vector<std::pair<std::reference_wrapper<const Location>, std::reference_wrapper<const LocationSection>>>&
getReferencingSections(const LocationSection& sec);

nlohmann::json saveState() const;
bool loadState(nlohmann::json& state);
Expand Down Expand Up @@ -114,6 +118,12 @@ class Tracker final : public LuaInterface<Tracker> {
std::list<std::string> _bulkItemUpdates;
bool _bulkUpdate = false;

std::map<std::string, std::vector<std::string>> _sectionNameRefs;
std::map<std::reference_wrapper<const LocationSection>,
std::vector<std::pair<std::reference_wrapper<const Location>,
std::reference_wrapper<const LocationSection>>>,
std::less<const LocationSection&>> _sectionRefs;

std::list<std::string>* _parents = nullptr;

static int _execLimit;
Expand All @@ -124,6 +134,7 @@ class Tracker final : public LuaInterface<Tracker> {
bool isVisible(const Location& location, std::list<std::string>& parents);
AccessibilityLevel isReachable(const std::list< std::list<std::string> >& rules, bool visibilityRules, std::list<std::string>& parents);

void rebuildSectionRefs();

protected: // Lua interface implementation
static constexpr const char Lua_Name[] = "Tracker";
Expand Down
12 changes: 9 additions & 3 deletions src/ui/trackerview.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,9 @@ TrackerView::TrackerView(int x, int y, int w, int h, Tracker* tracker, const std
}};
_tracker->onLocationSectionChanged += {this, [this](void *s, const LocationSection& sec) {
updateLocation(sec.getParentID());
for (const auto& pair: _tracker->getReferencingSections(sec))
updateLocation(pair.first.get().getID());
updateMapTooltip(); // TODO: move this into updateLocation and detect if the location is hovered
}};
updateLayout(layoutRoot);
updateState("");
Expand Down Expand Up @@ -360,12 +363,12 @@ void TrackerView::updateLayout(const std::string& layout)

void TrackerView::updateLocations()
{
updateLocation("");
updateLocation("", true);
updateMapTooltip(); // TODO: move this into updateLocation and detect if the location is hovered
}

void TrackerView::updateLocation(const std::string& location)
void TrackerView::updateLocation(const std::string& location, bool all)
{
bool all = location.empty();
for (auto& mappair: _maps) {
for (auto& w: mappair.second) {
for (const auto& pair : _tracker->getMapLocations(mappair.first)) {
Expand All @@ -381,7 +384,10 @@ void TrackerView::updateLocation(const std::string& location)
}
}
}
}

void TrackerView::updateMapTooltip()
{
if (_mapTooltip && _mapTooltipOwner) {
_mapTooltip->update(_tracker, [this](Item* w, const BaseItem& item) { updateItem(w, item); });
// update size if visibility of an item changed
Expand Down
3 changes: 2 additions & 1 deletion src/ui/trackerview.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,8 @@ class TrackerView : public SimpleContainer {
void updateDisplay(const std::string& check);
void updateState(const std::string& check);
void updateLocations();
void updateLocation(const std::string& location);
void updateLocation(const std::string& location, bool all=false);
void updateMapTooltip();
void updateItem(Item* w, const BaseItem& item);

size_t addLayoutNodes(Container* container, const std::list<LayoutNode>& nodes, size_t depth=0);
Expand Down
Loading