Posts: 952
Threads: 16
Joined: May 2013
Thanks: 66
Given 105 thank(s) in 89 post(s)
Привет!
I am rewriting the redstone simulator because the current one doesn't work.
However, I am encountering a difficulty (namely, an assert fired by deque) trying to get blocks to be powered or changed as a result of being powered. This only happens in DEBUG and not release.
The assert fired tells me: Expression: deque iterator not incrementable
What is the cause of this?
This code, for example, breaks:
void cRedstoneSimulator::HandleTNT(const Vector3i & a_BlockPos)
{
if (AreCoordsPowered(a_BlockPos))
{
m_World.BroadcastSoundEffect("random.fuse", a_BlockPos.x * 8, a_BlockPos.y * 8, a_BlockPos.z * 8, 0.5f, 0.6f);
m_World.SpawnPrimedTNT(a_BlockPos.x + 0.5, a_BlockPos.y + 0.5, a_BlockPos.z + 0.5, 4); // 4 seconds to boom
m_World.SetBlock(a_BlockPos.x, a_BlockPos.y, a_BlockPos.z, E_BLOCK_AIR, 0);
}
return;
}
bool cRedstoneSimulator::AreCoordsPowered(const Vector3i & a_BlockPos)
{
for (PoweredBlocksList::iterator itr = m_PoweredBlocks.begin(); itr != m_PoweredBlocks.end(); ++itr)
{
sPoweredBlocks & Change = *itr;
if (Change.a_BlockPos.Equals(a_BlockPos))
{
return true;
}
}
return false;
}
Posts: 6,485
Threads: 176
Joined: Jan 2012
Thanks: 131
Given 1074 thank(s) in 852 post(s)
Здравствуй.
This means that your code is buggy. The assert means that you have an iterator that is invalid; this usually happens when iterating through a container and deleting from the container at the same time, either from two threads, or even from one thread. You cannot have a for-loop over the container, inside which you delete items from that container - this invalidates the iterators.
I don't think the code that you've posted is the only cause of this, there's nothing immediate that would indicate a problem.
Of course the asserts only fire in debug mode, that's the point of asserts - they check conditions that shouldn't happen and may be costly to check, so they are compiled in only in debug mode; in release they are left out, meaning the program will crash or otherwise misbehave instead.
Posts: 952
Threads: 16
Joined: May 2013
Thanks: 66
Given 105 thank(s) in 89 post(s)
I see
So how would I iterate through a BlockList and delete the ones I don't want?
Posts: 6,485
Threads: 176
Joined: Jan 2012
Thanks: 131
Given 1074 thank(s) in 852 post(s)
Basically you need something like this (skeleton only):
for (itr = Container.begin; itr != Container.end(); ) // Note that you need to call end() each time, and you cannot auto-advance itr
{
if (ShouldDelete)
{
itr = Container.erase(itr); // Container must support erasing
}
else
{
++itr;
}
}
Posts: 952
Threads: 16
Joined: May 2013
Thanks: 66
Given 105 thank(s) in 89 post(s)
09-22-2013, 05:12 AM
(This post was last modified: 09-22-2013, 05:13 AM by tigerw.)
Thanks!
Found two:
// Check to see if PoweredBlocks have invalid items (source is air)
for (PoweredBlocksList::iterator itr = m_PoweredBlocks.begin(); itr != m_PoweredBlocks.end(); )
{
sPoweredBlocks & Change = *itr;
if (m_World.GetBlock(Change.a_SourcePos) == E_BLOCK_AIR)
{
itr = m_PoweredBlocks.erase(itr);
}
else if (
((m_World.GetBlock(Change.a_SourcePos) == E_BLOCK_REDSTONE_WIRE) && (m_World.GetBlockMeta(Change.a_SourcePos) == 0)) ||
(m_World.GetBlock(Change.a_SourcePos) == E_BLOCK_REDSTONE_TORCH_OFF) ||
(m_World.GetBlock(Change.a_SourcePos) == E_BLOCK_REDSTONE_REPEATER_OFF) ||
(m_World.GetBlock(Change.a_SourcePos) == E_BLOCK_INACTIVE_COMPARATOR)
)
{
itr = m_PoweredBlocks.erase(itr);
}
else
{
itr++;
}
}
...and a SetBlock to FastSetBlock.
Posts: 952
Threads: 16
Joined: May 2013
Thanks: 66
Given 105 thank(s) in 89 post(s)
09-24-2013, 05:15 AM
(This post was last modified: 09-24-2013, 05:15 AM by tigerw.)
Hello, I need halp again
How do I get a Chunk (pointer? object?) to pass onto cRedStoneSimulator::WakeUp(int X Y Z, cChunk & a_Chunk)? I need to wake it up manually to provide an update to devices.
Thanks.
Posts: 6,485
Threads: 176
Joined: Jan 2012
Thanks: 131
Given 1074 thank(s) in 852 post(s)
09-24-2013, 05:37 AM
(This post was last modified: 09-24-2013, 05:40 AM by xoft.)
cWorld:DoWithChunk()
Where are you calling that WakeUp from? Doesn't that have a chunk?
To be honest, I think you've bitten off quite a bit more than you could chew here. Rewriting redstone is a really really big task, and with your history of doing things half-way through, then abandoning them, I'm not really comfortable with it all.
There are lots of other tasks, especially in the FlySpray, that I believe would be more suitable for you now.
Posts: 952
Threads: 16
Joined: May 2013
Thanks: 66
Given 105 thank(s) in 89 post(s)
09-24-2013, 06:27 AM
(This post was last modified: 09-24-2013, 07:02 AM by tigerw.)
(09-24-2013, 05:37 AM)xoft Wrote: ...and with your history of doing things half-way through...
Thank you, for summing that up
I don't know, it's going alright. Besides, the FlySpray issues seem to mainly consist of crash bugs (no idea how to debug), physics (tried, failed, lost some hair), and redstone.
I might as well try, right?
WakeUp is called by the server, I just need to call it again to update blocks that were changed as a result of simulation (FastSetBlock doesn't seem to do it automatically)
Owait, I can just do m_World.WakeUpSimulators, right?
This simplifies things!
Or not. Deque iterators are derpy.
Posts: 6,485
Threads: 176
Joined: Jan 2012
Thanks: 131
Given 1074 thank(s) in 852 post(s)
FlySpray issues that I think would be an ideal match for you:
Door/Fence Door open without permission. (#260)
Fire should activate TNT (#406)
Bucket should use the "BlockFace == -1" packet (#405)
Pickup collection range too long (#396)
Add pickup delay (#394) (don't you just LOVE pickups? )
Add rotation and mirroring support to cBlockArea (#331)
The Core won't let player interact with the block on which they're standing (#188) - This one bugs me really bad
Snow should melt in high blocklight (#264)
Why do you even need to call the wakeup again? It feels as if you're trying to do something silly, how about you share your thoughts on this? What are you trying to achieve? Why did you pick this solution?
Posts: 952
Threads: 16
Joined: May 2013
Thanks: 66
Given 105 thank(s) in 89 post(s)
I need to update each redstone wire that is connected. I have managed to (nearly) achieve this with recursing the HandleRedstoneWire function and changes to WakeUp, but the last block of wire doesn't update for some reason.
I will go on to pickup delays soon - but I don't know how to pass a bool from SpawnItemPickups to the pickup handler (it complains about default values or something).
I think I will remove the Core block interaction code, because it doesn't actually do anything - i.e. I can still place a block in ANOTHER player if the server hasn't updated their position correctly. All Core does is check if the block being placed is intersecting YOURSELF, which the client already does, so is effectively useless.
|