Add option to force-fetch world blocks in RemoteFortressReader

The current behavior of GetBlockList in the RemoteFortressReader
  Protobuf RPC API is to only return blocks that have changed since
  the last fetch. This causes problems when the RPC client (i.e. a
  world renderer) wants to restart, as it can no longer fetch the
  full world state.

  This patch adds a `force_reload` option to BlockRequest, defaulting
  to `false` (the current behavior). When passed, it returns all
  requested blocks regardless of whether they have changed or not.

Signed-off-by: David Li <jiawei.davidli@gmail.com>
develop
David Li 2023-08-06 13:32:07 -07:00
parent a7129cad04
commit 8b5321fe86
3 changed files with 7 additions and 4 deletions

@ -42,6 +42,7 @@ changelog.txt uses a syntax similar to RST, with a few special sequences:
## Documentation ## Documentation
## API ## API
- `RemoteFortressReader`: add a `force_reload` option to the GetBlockList RPC API to return blocks regardless of whether they have changed since the last request
## Internals ## Internals

@ -526,6 +526,7 @@ message BlockRequest
optional int32 max_y = 5; optional int32 max_y = 5;
optional int32 min_z = 6; optional int32 min_z = 6;
optional int32 max_z = 7; optional int32 max_z = 7;
optional bool force_reload = 8;
} }
message BlockList message BlockList

@ -1393,6 +1393,7 @@ static command_result GetBlockList(color_ostream &stream, const BlockRequest *in
int max_y = in->max_y(); int max_y = in->max_y();
int min_z = in->min_z(); int min_z = in->min_z();
int max_z = in->max_z(); int max_z = in->max_z();
bool forceReload = in->force_reload();
bool firstBlock = true; //Always send all the buildings needed on the first block, and none on the rest. bool firstBlock = true; //Always send all the buildings needed on the first block, and none on the rest.
//stream.print("Got request for blocks from (%d, %d, %d) to (%d, %d, %d).\n", in->min_x(), in->min_y(), in->min_z(), in->max_x(), in->max_y(), in->max_z()); //stream.print("Got request for blocks from (%d, %d, %d) to (%d, %d, %d).\n", in->min_x(), in->min_y(), in->min_z(), in->max_x(), in->max_y(), in->max_z());
for (int zz = max_z - 1; zz >= min_z; zz--) for (int zz = max_z - 1; zz >= min_z; zz--)
@ -1440,19 +1441,19 @@ static command_result GetBlockList(color_ostream &stream, const BlockRequest *in
bool itemsChanged = block->items.size() > 0; bool itemsChanged = block->items.size() > 0;
bool flows = block->flows.size() > 0; bool flows = block->flows.size() > 0;
RemoteFortressReader::MapBlock *net_block = nullptr; RemoteFortressReader::MapBlock *net_block = nullptr;
if (tileChanged || desChanged || spatterChanged || firstBlock || itemsChanged || flows) if (tileChanged || desChanged || spatterChanged || firstBlock || itemsChanged || flows || forceReload)
{ {
net_block = out->add_map_blocks(); net_block = out->add_map_blocks();
net_block->set_map_x(block->map_pos.x); net_block->set_map_x(block->map_pos.x);
net_block->set_map_y(block->map_pos.y); net_block->set_map_y(block->map_pos.y);
net_block->set_map_z(block->map_pos.z); net_block->set_map_z(block->map_pos.z);
} }
if (tileChanged) if (tileChanged || forceReload)
{ {
CopyBlock(block, net_block, &MC, pos); CopyBlock(block, net_block, &MC, pos);
blocks_sent++; blocks_sent++;
} }
if (desChanged) if (desChanged || forceReload)
CopyDesignation(block, net_block, &MC, pos); CopyDesignation(block, net_block, &MC, pos);
if (firstBlock) if (firstBlock)
{ {
@ -1460,7 +1461,7 @@ static command_result GetBlockList(color_ostream &stream, const BlockRequest *in
CopyProjectiles(net_block); CopyProjectiles(net_block);
firstBlock = false; firstBlock = false;
} }
if (spatterChanged) if (spatterChanged || forceReload)
Copyspatters(block, net_block, &MC, pos); Copyspatters(block, net_block, &MC, pos);
if (itemsChanged) if (itemsChanged)
CopyItems(block, net_block, &MC, pos); CopyItems(block, net_block, &MC, pos);