From a93c0223a2999944b788092791df342d9131b6e3 Mon Sep 17 00:00:00 2001 From: expwnent Date: Tue, 18 Dec 2012 20:28:30 -0500 Subject: [PATCH] EventManager: unstable. Temp commit. --- library/include/modules/Buildings.h | 4 ++ library/include/modules/Constructions.h | 2 + library/modules/Buildings.cpp | 82 ++++++++++++++++++++++++- library/modules/Constructions.cpp | 5 ++ library/modules/EventManager.cpp | 22 +++++-- 5 files changed, 110 insertions(+), 5 deletions(-) diff --git a/library/include/modules/Buildings.h b/library/include/modules/Buildings.h index 266aadcb8..5f3a2b48d 100644 --- a/library/include/modules/Buildings.h +++ b/library/include/modules/Buildings.h @@ -25,7 +25,9 @@ distribution. #pragma once #include "Export.h" #include "DataDefs.h" +#include "Types.h" #include "df/building.h" +#include "df/building_type.h" #include "df/civzone_type.h" #include "df/furnace_type.h" #include "df/workshop_type.h" @@ -178,5 +180,7 @@ DFHACK_EXPORT bool constructWithFilters(df::building *bld, std::vector +#include +#include +#include #include +#include #include -#include using namespace std; +#include "ColorText.h" #include "VersionInfo.h" #include "MemAccess.h" #include "Types.h" @@ -77,6 +82,14 @@ using df::global::building_next_id; using df::global::process_jobs; using df::building_def; +struct CoordHash { + size_t operator()(const df::coord pos) const { + return pos.x*65537 + pos.y*17 + pos.z; + } +}; + +static unordered_map locationToBuilding; + static uint8_t *getExtentTile(df::building_extents &extent, df::coord2d tile) { if (!extent.extents) @@ -222,6 +235,30 @@ df::building *Buildings::findAtTile(df::coord pos) if (!occ || !occ->bits.building) return NULL; + auto a = locationToBuilding.find(pos); + if ( a == locationToBuilding.end() ) { + cerr << __FILE__ << ", " << __LINE__ << ": can't find building at " << pos.x << ", " << pos.y << ", " <buildings.all, id); + if ( index == -1 ) { + cerr << __FILE__ << ", " << __LINE__ << ": can't find building at " << pos.x << ", " << pos.y << ", " <buildings.all[index]; + if (!building->isSettingOccupancy()) + return NULL; + + if (building->room.extents && building->isExtentShaped()) + { + auto etile = getExtentTile(building->room, pos); + if (!etile || !*etile) + return NULL; + } + return building; + + /* auto &vec = df::building::get_vector(); for (size_t i = 0; i < vec.size(); i++) { @@ -246,6 +283,7 @@ df::building *Buildings::findAtTile(df::coord pos) } return NULL; + */ } bool Buildings::findCivzonesAt(std::vector *pvec, df::coord pos) @@ -1063,3 +1101,45 @@ bool Buildings::deconstruct(df::building *bld) return true; } +void Buildings::updateBuildings(color_ostream& out, void* ptr) { + static unordered_map corner1; + static unordered_map corner2; + out.print("Updating buildings, %s %d\n", __FILE__, __LINE__); + int32_t id = (int32_t)ptr; + + if ( corner1.find(id) == corner1.end() ) { + //new building: mark stuff + int32_t index = df::building::binsearch_index(df::global::world->buildings.all, id); + if ( index == -1 ) { + out.print("%s, line %d: Couldn't find new building id=%d.\n", __FILE__, __LINE__, id); + exit(1); + } + df::building* building = df::global::world->buildings.all[index]; + df::coord p1(min(building->x1, building->x2), min(building->y1,building->y2), building->z); + df::coord p2(max(building->x1, building->x2), max(building->y1,building->y2), building->z); + + corner1[id] = p1; + corner2[id] = p2; + + for ( int32_t x = p1.x; x <= p2.x; x++ ) { + for ( int32_t y = p1.y; y <= p2.y; y++ ) { + df::coord pt(x,y,building->z); + locationToBuilding[pt] = id; + } + } + } else { + //existing building: destroy it + df::coord p1 = corner1[id]; + df::coord p2 = corner2[id]; + + for ( int32_t x = p1.x; x <= p2.x; x++ ) { + for ( int32_t y = p1.y; y <= p2.y; y++ ) { + df::coord pt(x,y,p1.z); + locationToBuilding.erase(pt); + } + } + + corner1.erase(id); + corner2.erase(id); + } +} diff --git a/library/modules/Constructions.cpp b/library/modules/Constructions.cpp index 16c1f1b89..2153ce6a2 100644 --- a/library/modules/Constructions.cpp +++ b/library/modules/Constructions.cpp @@ -169,3 +169,8 @@ bool Constructions::designateRemove(df::coord pos, bool *immediate) return false; } + + +void Constructions::updateConstructions(color_ostream& out, void* ptr) { + //do stuff +} diff --git a/library/modules/EventManager.cpp b/library/modules/EventManager.cpp index f2d7e0261..b057adb01 100644 --- a/library/modules/EventManager.cpp +++ b/library/modules/EventManager.cpp @@ -1,5 +1,7 @@ #include "Core.h" #include "Console.h" +#include "modules/Buildings.h" +#include "modules/Constructions.h" #include "modules/EventManager.h" #include "modules/Job.h" #include "modules/World.h" @@ -127,6 +129,16 @@ static unordered_set buildings; static unordered_set constructions; void DFHack::EventManager::onStateChange(color_ostream& out, state_change_event event) { + static bool doOnce = false; + if ( !doOnce ) { + //TODO: put this somewhere else + doOnce = true; + EventHandler buildingHandler(Buildings::updateBuildings); + EventHandler constructionHandler(Constructions::updateConstructions); + DFHack::EventManager::registerListener(EventType::BUILDING, buildingHandler, NULL); + DFHack::EventManager::registerListener(EventType::CONSTRUCTION, constructionHandler, NULL); + out.print("Registered listeners.\n %d", __LINE__); + } if ( event == DFHack::SC_MAP_UNLOADED ) { lastTick = 0; lastJobId = -1; @@ -151,9 +163,9 @@ void DFHack::EventManager::onStateChange(color_ostream& out, state_change_event tickQueue.insert(newTickQueue.begin(), newTickQueue.end()); - nextItem = *df::global::item_next_id; - nextBuilding = *df::global::building_next_id; - constructions.insert(df::global::world->constructions.begin(), df::global::world->constructions.end()); + nextItem = 0; + nextBuilding = 0; + lastTick = 0; } } @@ -324,7 +336,7 @@ static void manageBuildingEvent(color_ostream& out) { * TODO: could be faster * consider looking at jobs: building creation / destruction **/ - if ( handlers[EventType::ITEM_CREATED].empty() ) + if ( handlers[EventType::BUILDING].empty() ) return; multimap copy(handlers[EventType::BUILDING].begin(), handlers[EventType::BUILDING].end()); @@ -361,6 +373,8 @@ static void manageBuildingEvent(color_ostream& out) { int32_t id = *a; buildings.erase(id); } + + out.print("Sent building event.\n %d", __LINE__); } static void manageConstructionEvent(color_ostream& out) {