New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Don't cancel recorded macro when running the macro stopped #161
Comments
Possibly related: when pressing X many times and being interrupted I sometimes (e.g., when an actor is spotted) get "Macro recording aborted". |
Hey, could you describe briefly how did you imagine the macro system to work? There's a subtle interplay inside From my experience, as for now, the only use case of macros is to start recording one, keep fingers crossed and bash LambdaHack/engine-src/Game/LambdaHack/Client/UI.hs Lines 151 to 155 in 6f5cc3b
and then we record last pressed key in LambdaHack/engine-src/Game/LambdaHack/Client/UI/FrameM.hs Lines 140 to 142 in 96f10b2
Then if we want to replay a macro, e.g. pressing LambdaHack/engine-src/Game/LambdaHack/Client/UI/HandleHumanLocalM.hs Lines 680 to 686 in 17f751b
I've been tinkering with the code here and there, but before I go into details I would like to make sure what were your design choices. Do we want to clear macro buffer whenever we replay the macro? Does constraining macros to |
I remember the system was broken a few times. Perhaps it is broken currently. I will check soon. In any case, it's probably too complex per it's usefulness, if it gets broken so often and the breakage is spotted so late (or it works fine, but it's so hard to use/document, it seems broken), so if at some point you come up with alternative designs, feel free to experiment. |
Before I even look at this code: the in-game macro system is an afterthought, "because I can". The real purpose of the system is defining complex commands from simple commands, as seen in the game engine in in the game content in and in user config file in (though actually there are no macros in the config ATM and the command is expressed algebraically instead; but there could be and the user is rather more likely to be able to write macros that to be able to write algebraic terms with commands in them). And the main use-case for the in-game macro recording is the functionality from Angband, namely "repeat previous command", easily generalizable to "repeat previous command 100 times" (not sure if that's in Angband). I hope this sets the boundary conditions or at least the context for the design. In particular, I wouldn't mind forcing the user to write only algebraic terms in config and restricting the in-game macro to the basic cases, if the result is that we never ever need to mix abstract syntax (the algebraic terms, |
So, the in-game macro system is quite broken indeed. It was supposed to let you record a macro, between a pair of I think you are right about the meaning of
When a macro is replayed, it should be ready to be replayed again. However, it should not be ready to be extended by further keystrokes. Either
Not strictly, but I've had so many cases of the macros run amok, that it was probably just fire safety. :) |
When we're not recording, Also, aren't predefined macros interpreted in LambdaHack/engine-src/Game/LambdaHack/Client/UI/HandleHumanM.hs Lines 59 to 62 in 17f751b
Sorry if I mix things up, it's quite dense :-D |
What you write reminds me that in the absence of explicitly recorded macros, the last issued command is implicitly regarded as the recorded macro, so that Yes, we are surely holding the player UI commands and macros inserted from game content/config/engine in the same buffers. That was the idea --- to unify all this. However, quite possibly we've gone overboard and separate input buffers, at least, would be better. Yes, predefined macros are handled by |
Some tests are failing. Possibly I don't understand how this should work. Changing the tests so that they show the intermediate steps of macro unwinding (as some other tests do) would surely clarify the matter. Feel free to do that. |
It's a bug. Some contents of predefined macros are being unnecessarily recorded. Let's take a closer look at two failing test cases. Case 15: a := x ( The easiest way out is to bypass keys binded to
I did by hand case 19. It's essentially the same thing. Case 19: a := 'x'v
|
Thank you for the analysis. So it's not an error in my test mock, but real bug in my code? BTW, you can tweak the tests to print tables similar to what you provide (but without the formatting) by giving it a dummy expected answer and looking at the error report. |
I've reasoned how it supposed to work with pen & paper (well, more like keyboard & org-mode), then compared that roughly with the real code simply by running the game and printing out intermediate values. Your test assertions seem right, those two failing tests cases gave the same output as I expected doing the thing manually, so implementation is (rather) correct, but the system is flawed. Passing by macro-keystrokes is a hopeless idea. Just tried that out and broke the whole thing. I'm thinking right now if there's still any point in recording actions by taking them one by one from |
Sure, for a |
Oh, to clear things out, in previous post I mistook case 18 with case 19. I've edited that post. Case 18 passes fine. |
Hang on, I believe I found the ultimate solution. I think that merging data ActionBuffer = ActionBuffer
{ slastPlay :: KeyMacro
, smacroBuffer :: Either [K.KM] KeyMacro
, slastAction :: Maybe K.KM
} gives us exactly what we need. Both I've refactored quite a lot already, but this will take a while longer. |
We handle each macro locally, pushing onto the stack a buffer with macro contents, a separate place for in-game macros (recorded by the macro) and a last action performed by the handled macro. We pop the buffer when all actions introduced by the macro are handled. Since predefined macros can make use of other predefined macros, buffers stack on top of each other. We consume them from the top until there's only one left, i.e. the user's buffer for his in-game macros. Resolves: LambdaHack#161
This is finally completely resolved, with sugar on top. Closing. |
See the comment "Needed to properly cancel macros that contain apostrophes". This seems to be buggy and triggered not only for nested macros.
Also, the whole macro subsystem needs a review (what is the meaning of k=0? why is k not set to 0 after macro recording is finished), simplification (perhaps increment k after each keypress, not each action? disallow recording macros when inside macros?) and code comments.
The text was updated successfully, but these errors were encountered: