Reduced server CPU usage on NodeMetadata step()s. Also furnace now cooks while no players are near it.

This commit is contained in:
Perttu Ahola 2011-05-31 20:02:55 +03:00
parent 7740425085
commit bbead93c1a
7 changed files with 163 additions and 80 deletions

@ -729,6 +729,16 @@ void ServerEnvironment::step(float dtime)
// Activate stored objects // Activate stored objects
activateObjects(block); activateObjects(block);
// Run node metadata
bool changed = block->m_node_metadata.step((float)dtime_s);
if(changed)
{
MapEditEvent event;
event.type = MEET_BLOCK_NODE_METADATA_CHANGED;
event.p = p;
m_map->dispatchEvent(&event);
}
// TODO: Do something // TODO: Do something
// TODO: Implement usage of ActiveBlockModifier // TODO: Implement usage of ActiveBlockModifier
@ -762,8 +772,41 @@ void ServerEnvironment::step(float dtime)
/* /*
Mess around in active blocks Mess around in active blocks
*/ */
if(m_active_blocks_nodemetadata_interval.step(dtime, 1.0))
{
float dtime = 1.0;
for(core::map<v3s16, bool>::Iterator
i = m_active_blocks.m_list.getIterator();
i.atEnd()==false; i++)
{
v3s16 p = i.getNode()->getKey();
/*dstream<<"Server: Block ("<<p.X<<","<<p.Y<<","<<p.Z
<<") being handled"<<std::endl;*/
MapBlock *block = m_map->getBlockNoCreateNoEx(p);
if(block==NULL)
continue;
// Set current time as timestamp
block->setTimestamp(m_game_time);
// Run node metadata
bool changed = block->m_node_metadata.step(dtime);
if(changed)
{
MapEditEvent event;
event.type = MEET_BLOCK_NODE_METADATA_CHANGED;
event.p = p;
m_map->dispatchEvent(&event);
}
}
}
if(m_active_blocks_test_interval.step(dtime, 10.0)) if(m_active_blocks_test_interval.step(dtime, 10.0))
{ {
//float dtime = 10.0;
for(core::map<v3s16, bool>::Iterator for(core::map<v3s16, bool>::Iterator
i = m_active_blocks.m_list.getIterator(); i = m_active_blocks.m_list.getIterator();
i.atEnd()==false; i++) i.atEnd()==false; i++)
@ -801,8 +844,11 @@ void ServerEnvironment::step(float dtime)
{ {
v3s16 p = p0 + block->getPosRelative(); v3s16 p = p0 + block->getPosRelative();
MapNode n = block->getNodeNoEx(p0); MapNode n = block->getNodeNoEx(p0);
// Test something:
// Convert mud under proper lighting to grass /*
Test something:
Convert mud under proper lighting to grass
*/
if(n.d == CONTENT_MUD) if(n.d == CONTENT_MUD)
{ {
if(myrand()%20 == 0) if(myrand()%20 == 0)

@ -246,6 +246,7 @@ private:
ActiveBlockList m_active_blocks; ActiveBlockList m_active_blocks;
IntervalLimiter m_active_blocks_management_interval; IntervalLimiter m_active_blocks_management_interval;
IntervalLimiter m_active_blocks_test_interval; IntervalLimiter m_active_blocks_test_interval;
IntervalLimiter m_active_blocks_nodemetadata_interval;
// Time from the beginning of the game in seconds. // Time from the beginning of the game in seconds.
// Incremented in step(). // Incremented in step().
u32 m_game_time; u32 m_game_time;

@ -312,7 +312,8 @@ Stuff to do before release:
Fixes to the current release: Fixes to the current release:
----------------------------- -----------------------------
- Make AuthManager to save only when data has changed - Fix client password crash
- Remember to release the fixes (some are already done)
Stuff to do after release: Stuff to do after release:
--------------------------- ---------------------------

@ -46,8 +46,14 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#define MAPTYPE_CLIENT 2 #define MAPTYPE_CLIENT 2
enum MapEditEventType{ enum MapEditEventType{
// Node added (changed from air or something else to something)
MEET_ADDNODE, MEET_ADDNODE,
// Node removed (changed to air)
MEET_REMOVENODE, MEET_REMOVENODE,
// Node metadata of block changed (not knowing which node exactly)
// p stores block coordinate
MEET_BLOCK_NODE_METADATA_CHANGED,
// Anything else
MEET_OTHER MEET_OTHER
}; };

@ -268,11 +268,14 @@ void FurnaceNodeMetadata::inventoryModified()
} }
bool FurnaceNodeMetadata::step(float dtime) bool FurnaceNodeMetadata::step(float dtime)
{ {
if(dtime > 60.0)
dstream<<"Furnace stepping a long time ("<<dtime<<")"<<std::endl;
// Update at a fixed frequency // Update at a fixed frequency
const float interval = 0.5; const float interval = 2.0;
m_step_accumulator += dtime; m_step_accumulator += dtime;
if(m_step_accumulator < interval) bool changed = false;
return false; while(m_step_accumulator > interval)
{
m_step_accumulator -= interval; m_step_accumulator -= interval;
dtime = interval; dtime = interval;
@ -311,16 +314,15 @@ bool FurnaceNodeMetadata::step(float dtime)
m_src_time = 0; m_src_time = 0;
m_src_totaltime = 0; m_src_totaltime = 0;
} }
return true; changed = true;
continue;
} }
if(src_item == NULL || m_src_totaltime < 0.001) if(src_item == NULL || m_src_totaltime < 0.001)
{ {
return false; continue;
} }
bool changed = false;
//dstream<<"Furnace is out of fuel"<<std::endl; //dstream<<"Furnace is out of fuel"<<std::endl;
InventoryList *fuel_list = m_inventory->getList("fuel"); InventoryList *fuel_list = m_inventory->getList("fuel");
@ -329,21 +331,28 @@ bool FurnaceNodeMetadata::step(float dtime)
if(ItemSpec(ITEM_MATERIAL, CONTENT_TREE).checkItem(fuel_item)) if(ItemSpec(ITEM_MATERIAL, CONTENT_TREE).checkItem(fuel_item))
{ {
m_fuel_totaltime = 10; m_fuel_totaltime = 30;
m_fuel_time = 0; m_fuel_time = 0;
fuel_list->decrementMaterials(1); fuel_list->decrementMaterials(1);
changed = true; changed = true;
} }
else if(ItemSpec(ITEM_MATERIAL, CONTENT_WOOD).checkItem(fuel_item)) else if(ItemSpec(ITEM_MATERIAL, CONTENT_WOOD).checkItem(fuel_item))
{ {
m_fuel_totaltime = 5; m_fuel_totaltime = 30/4;
m_fuel_time = 0;
fuel_list->decrementMaterials(1);
changed = true;
}
else if(ItemSpec(ITEM_CRAFT, "Stick").checkItem(fuel_item))
{
m_fuel_totaltime = 30/4/4;
m_fuel_time = 0; m_fuel_time = 0;
fuel_list->decrementMaterials(1); fuel_list->decrementMaterials(1);
changed = true; changed = true;
} }
else if(ItemSpec(ITEM_CRAFT, "lump_of_coal").checkItem(fuel_item)) else if(ItemSpec(ITEM_CRAFT, "lump_of_coal").checkItem(fuel_item))
{ {
m_fuel_totaltime = 10; m_fuel_totaltime = 40;
m_fuel_time = 0; m_fuel_time = 0;
fuel_list->decrementMaterials(1); fuel_list->decrementMaterials(1);
changed = true; changed = true;
@ -352,7 +361,7 @@ bool FurnaceNodeMetadata::step(float dtime)
{ {
//dstream<<"No fuel found"<<std::endl; //dstream<<"No fuel found"<<std::endl;
} }
}
return changed; return changed;
} }

@ -1637,6 +1637,11 @@ void Server::AsyncRunStep()
dstream<<"Server: MEET_REMOVENODE"<<std::endl; dstream<<"Server: MEET_REMOVENODE"<<std::endl;
sendRemoveNode(event->p, event->already_known_by_peer); sendRemoveNode(event->p, event->already_known_by_peer);
} }
else if(event->type == MEET_BLOCK_NODE_METADATA_CHANGED)
{
dstream<<"Server: MEET_BLOCK_NODE_METADATA_CHANGED"<<std::endl;
setBlockNotSent(event->p);
}
else if(event->type == MEET_OTHER) else if(event->type == MEET_OTHER)
{ {
dstream<<"WARNING: Server: MEET_OTHER not implemented" dstream<<"WARNING: Server: MEET_OTHER not implemented"
@ -1676,7 +1681,7 @@ void Server::AsyncRunStep()
Step node metadata Step node metadata
TODO: Move to ServerEnvironment and utilize active block stuff TODO: Move to ServerEnvironment and utilize active block stuff
*/ */
{ /*{
//TimeTaker timer("Step node metadata"); //TimeTaker timer("Step node metadata");
JMutexAutoLock envlock(m_env_mutex); JMutexAutoLock envlock(m_env_mutex);
@ -1687,6 +1692,8 @@ void Server::AsyncRunStep()
core::map<v3s16, MapBlock*> changed_blocks; core::map<v3s16, MapBlock*> changed_blocks;
m_env.getMap().nodeMetadataStep(dtime, changed_blocks); m_env.getMap().nodeMetadataStep(dtime, changed_blocks);
// Use setBlockNotSent
for(core::map<v3s16, MapBlock*>::Iterator for(core::map<v3s16, MapBlock*>::Iterator
i = changed_blocks.getIterator(); i = changed_blocks.getIterator();
i.atEnd() == false; i++) i.atEnd() == false; i++)
@ -1701,7 +1708,7 @@ void Server::AsyncRunStep()
client->SetBlockNotSent(block->getPos()); client->SetBlockNotSent(block->getPos());
} }
} }
} }*/
/* /*
Trigger emergethread (it somehow gets to a non-triggered but Trigger emergethread (it somehow gets to a non-triggered but
@ -3655,6 +3662,17 @@ void Server::sendAddNode(v3s16 p, MapNode n, u16 ignore_id,
} }
} }
void Server::setBlockNotSent(v3s16 p)
{
for(core::map<u16, RemoteClient*>::Iterator
i = m_clients.getIterator();
i.atEnd()==false; i++)
{
RemoteClient *client = i.getNode()->getValue();
client->SetBlockNotSent(p);
}
}
void Server::SendBlockNoLock(u16 peer_id, MapBlock *block, u8 ver) void Server::SendBlockNoLock(u16 peer_id, MapBlock *block, u8 ver)
{ {
DSTACK(__FUNCTION_NAME); DSTACK(__FUNCTION_NAME);

@ -480,15 +480,17 @@ private:
Additionally, if far_players!=NULL, players further away than Additionally, if far_players!=NULL, players further away than
far_d_nodes are ignored and their peer_ids are added to far_players far_d_nodes are ignored and their peer_ids are added to far_players
*/ */
// Envlock and conlock should be locked when calling these
void sendRemoveNode(v3s16 p, u16 ignore_id=0, void sendRemoveNode(v3s16 p, u16 ignore_id=0,
core::list<u16> *far_players=NULL, float far_d_nodes=100); core::list<u16> *far_players=NULL, float far_d_nodes=100);
void sendAddNode(v3s16 p, MapNode n, u16 ignore_id=0, void sendAddNode(v3s16 p, MapNode n, u16 ignore_id=0,
core::list<u16> *far_players=NULL, float far_d_nodes=100); core::list<u16> *far_players=NULL, float far_d_nodes=100);
void setBlockNotSent(v3s16 p);
// Environment and Connection must be locked when called // Environment and Connection must be locked when called
void SendBlockNoLock(u16 peer_id, MapBlock *block, u8 ver); void SendBlockNoLock(u16 peer_id, MapBlock *block, u8 ver);
// Sends blocks to clients // Sends blocks to clients (locks env and con on its own)
void SendBlocks(float dtime); void SendBlocks(float dtime);
/* /*