fix selection panel contents
This commit is contained in:
@@ -1,15 +1,17 @@
|
||||
#include "BufferedBuildingContent.h"
|
||||
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <set>
|
||||
|
||||
#include <QVBoxLayout>
|
||||
|
||||
#include "Building.h"
|
||||
#include "BufferSection.h"
|
||||
#include "BuildingTarget.h"
|
||||
#include "DisplayName.h"
|
||||
#include "FactoryQueries.h"
|
||||
#include "ProductionSection.h"
|
||||
#include "RecipeSummaryRow.h"
|
||||
#include "SectionBox.h"
|
||||
#include "SelectionNames.h"
|
||||
#include "Simulation.h"
|
||||
|
||||
@@ -27,6 +29,33 @@ std::vector<RecipeSummaryRow::Amount> toAmounts(const std::map<std::string, int>
|
||||
return amounts;
|
||||
}
|
||||
|
||||
// Every item one side of the card should list: what the buffer holds, what a cycle
|
||||
// moves, and what the building handles at all. A building's buffers can carry items it
|
||||
// is not currently making anything of, and an auto-recipe building between cycles names
|
||||
// nothing at all, so the three sources are unioned rather than one being picked.
|
||||
std::set<std::string> collectItemIds(const std::map<std::string, int>& buffered,
|
||||
const std::map<std::string, int>& perCycle,
|
||||
const std::vector<std::string>& handled)
|
||||
{
|
||||
std::set<std::string> itemIds;
|
||||
for (const std::pair<const std::string, int>& entry : buffered)
|
||||
{
|
||||
itemIds.insert(entry.first);
|
||||
}
|
||||
for (const std::pair<const std::string, int>& entry : perCycle)
|
||||
{
|
||||
itemIds.insert(entry.first);
|
||||
}
|
||||
itemIds.insert(handled.begin(), handled.end());
|
||||
return itemIds;
|
||||
}
|
||||
|
||||
int lookUp(const std::map<std::string, int>& map, const std::string& key)
|
||||
{
|
||||
const std::map<std::string, int>::const_iterator it = map.find(key);
|
||||
return (it != map.end()) ? it->second : 0;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
|
||||
@@ -40,10 +69,21 @@ BufferedBuildingContent::BufferedBuildingContent(const SelectionContext& context
|
||||
m_recipeSummary = new RecipeSummaryRow(context.itemIcons, this);
|
||||
getConfigurationLayout()->addWidget(m_recipeSummary);
|
||||
|
||||
m_buffers = new BufferSection(context, this);
|
||||
m_inputSection = new SectionBox(tr("Input buffers"), this);
|
||||
m_inputChips = new ItemChipRow(context.itemIcons, m_inputSection);
|
||||
m_inputSection->getContentLayout()->addWidget(m_inputChips);
|
||||
|
||||
m_production = new ProductionSection(this);
|
||||
getRuntimeLayout()->addWidget(m_buffers);
|
||||
|
||||
m_outputSection = new SectionBox(tr("Output buffer"), this);
|
||||
m_outputChips = new ItemChipRow(context.itemIcons, m_outputSection);
|
||||
m_outputSection->getContentLayout()->addWidget(m_outputChips);
|
||||
|
||||
// In the direction the materials flow: what goes in, what is being made of it, what
|
||||
// has come out (REQ-UI-SINGLE-SELECTION, REQ-UI-PRODUCTION-PROGRESS).
|
||||
getRuntimeLayout()->addWidget(m_inputSection);
|
||||
getRuntimeLayout()->addWidget(m_production);
|
||||
getRuntimeLayout()->addWidget(m_outputSection);
|
||||
}
|
||||
|
||||
void BufferedBuildingContent::refreshConfiguration()
|
||||
@@ -77,8 +117,93 @@ void BufferedBuildingContent::refreshRuntime()
|
||||
setProductionStatusSlot(*target.building);
|
||||
|
||||
const CycleInfo cycle = getCycleInfo(target);
|
||||
m_buffers->setBuffers(*target.building, cycle.perCycleInputs, cycle.perCycleOutputs);
|
||||
|
||||
const std::vector<ItemChipRow::Entry> inputs =
|
||||
buildInputEntries(*target.building, cycle);
|
||||
const std::vector<ItemChipRow::Entry> outputs =
|
||||
buildOutputEntries(*target.building, cycle);
|
||||
|
||||
m_inputChips->setEntries(inputs);
|
||||
m_outputChips->setEntries(outputs);
|
||||
m_inputSection->setVisible(!inputs.empty());
|
||||
m_outputSection->setVisible(!outputs.empty());
|
||||
|
||||
m_production->setProduction(cycle.runsProduction, *target.building,
|
||||
cycle.durationSeconds,
|
||||
getContext().sim->getCurrentTick());
|
||||
}
|
||||
|
||||
std::vector<ItemChipRow::Entry> BufferedBuildingContent::buildInputEntries(
|
||||
const Building& building, const CycleInfo& cycle) const
|
||||
{
|
||||
std::map<std::string, int> buffered;
|
||||
for (const std::pair<const ItemType, int>& entry : building.inputBuffer.counts)
|
||||
{
|
||||
buffered[entry.first.id] = entry.second;
|
||||
}
|
||||
|
||||
std::vector<ItemChipRow::Entry> entries;
|
||||
for (const std::string& itemId :
|
||||
collectItemIds(buffered, cycle.perCycleInputs, cycle.handledInputs))
|
||||
{
|
||||
// An auto-recipe building's buffers are sized over every recipe of its type,
|
||||
// including recipes still locked, so those entries are left out here
|
||||
// (REQ-UI-SINGLE-SELECTION, REQ-LOCK-UI-RECIPE).
|
||||
if (!getContext().sim->isItemUnlocked(itemId)) { continue; }
|
||||
|
||||
ItemChipRow::Entry chip;
|
||||
chip.itemId = itemId;
|
||||
chip.countText = QString::number(lookUp(buffered, itemId));
|
||||
|
||||
const int perCycle = lookUp(cycle.perCycleInputs, itemId);
|
||||
if (perCycle > 0)
|
||||
{
|
||||
chip.subLine = tr("/ %1 per cycle").arg(perCycle);
|
||||
}
|
||||
else
|
||||
{
|
||||
chip.subLine = QString::fromStdString(toDisplayName(itemId));
|
||||
}
|
||||
entries.push_back(chip);
|
||||
}
|
||||
return entries;
|
||||
}
|
||||
|
||||
std::vector<ItemChipRow::Entry> BufferedBuildingContent::buildOutputEntries(
|
||||
const Building& building, const CycleInfo& cycle) const
|
||||
{
|
||||
// The buffered items plus those still emerging onto the output belts: an emerging
|
||||
// item still belongs to the output buffer (REQ-MAT-OUTPUT-EMERGE), so leaving it out
|
||||
// would make it vanish from the panel while it animates.
|
||||
std::map<std::string, int> buffered;
|
||||
for (const Item& item : building.outputBuffer.items)
|
||||
{
|
||||
buffered[item.type.id]++;
|
||||
}
|
||||
for (const std::vector<BeltItemSlot>& lane : building.emergingItems)
|
||||
{
|
||||
for (const BeltItemSlot& slot : lane)
|
||||
{
|
||||
buffered[slot.item.type.id]++;
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<ItemChipRow::Entry> entries;
|
||||
for (const std::string& itemId :
|
||||
collectItemIds(buffered, cycle.perCycleOutputs, cycle.handledOutputs))
|
||||
{
|
||||
if (!getContext().sim->isItemUnlocked(itemId)) { continue; }
|
||||
|
||||
ItemChipRow::Entry chip;
|
||||
chip.itemId = itemId;
|
||||
// Counted against the buffer's capacity, which is what production stops at
|
||||
// (REQ-MAT-OUTPUT-BUFFER).
|
||||
chip.countText = building.outputBuffer.capacity > 0
|
||||
? tr("%1 / %2").arg(lookUp(buffered, itemId))
|
||||
.arg(building.outputBuffer.capacity)
|
||||
: QString::number(lookUp(buffered, itemId));
|
||||
chip.subLine = QString::fromStdString(toDisplayName(itemId));
|
||||
entries.push_back(chip);
|
||||
}
|
||||
return entries;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user