Quick report on the current state of things. I traced the source of the bug up to the DragBuffer.
The “thing” being actually moved is a ReportState object.
The very first move by the user puts the wrong thing into the DragBuffer, it puts the Stack there, which contains the ReportState. It looks like things work fine if the actual ReportState is in the DragBuffer, and not the Stack that contains the ReportState.
If I replace this Stack in the DragBuffer with the ReportState contained in the Stack, then everything seems to work. And this has to be done only once, afterwards all further move and undo actions work perfectly fine.
Example, the log is from the method DragBuffer.add() which fires when the user clicks and holds the counters:
- The very first move by the user, observe how the DragBuffer contains a Stack:
2020-06-01 09:52:28,048 [0-AWT-EventQueue-0] DEBUG VASSAL.counters.DragBuffer - dragBuffer.add: VASSAL.counters.Stack@6db2a5c0[Blockade Marker]
- I correct this during debugging by just replacing the Stack in the dragbuffer with the ReportState object that is inside the Stack
- Then comes the undo which works fine
- Then I can move the counter forward and undo, as many times as I want, every time the DragBuffer contains the correct object and nothing needs to be fixed anymore, observe how the DragBuffer contains the ReportState:
2020-06-01 09:55:21,425 [0-AWT-EventQueue-0] DEBUG VASSAL.counters.DragBuffer - dragBuffer.add: VASSAL.counters.ReportState@51a27fc[name=Blockade Marker,blablamorestuff]
Next questions I want to solve:
- who puts the wrong object into the DragBuffer for the initial move, and why
- why, once fixed, do the moves 2-N work correctly, why is the correct object put into the DragBuffer, what is different between move 1 and moves 2-N
- is there any unwanted side effects by putting the ReportState into the DragBuffer instead of the Stack
Also, I browsed the other posts in this thread, sorry for going a bit over the edge, I have very high standards where code automatically deteriorates if it is not cleaned up and refactored into a manageable state, and thanks a lot for the input from whoever else analyzed this issue, and I completely understand why fixing this in the form of a “dirty hack” is better, safer and more backward-compatible than a full heart surgery. Once I narrowed down the source of the bug and found a way to fix it, I will present the solution and then we can still think about how we package it, how much we change and how much we leave as it is. I think I am almost there, I can already fix the bug when running inside the debugger, now I just have to follow the call hierarchy and find the exact source of the bug.
One other observation I have made - Stacks seem to be created dynamically whenever they are needed, and this creating of the Stacks and the whole merging functionality seems to work well (enough), and this Stack stuff is not related to the undo bug.