-
Notifications
You must be signed in to change notification settings - Fork 230
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
Enable yielding in opcodes and functions #1807
Enable yielding in opcodes and functions #1807
Conversation
Opcode.cs * Remove OpcodeEndWait which isn't used * Add new method YieldProgram which starts waiting and registers the YieldFinishedDelegate * Add new method CheckYield which evaluates YieldFinishedDelegate * Add virtual BeginYield and EndYield methods so an opcode may override entering or leaving the yield condition. This is mostly to allow opcodes that change DeltaInstructionPointer to still do so even if they use the new wait logic. CPU.cs * When executing opcodes, check for IsYielding and if so call CheckYield instead of Execute SafeFunctionBase.cs * Provide a method for functions to call Opcode.YieldProgram without accessing the opcode directly Misc.cs * Update the stage function to wait for one tick before returning to the program code. * This is done because some things update immediately on stage (thrust) while others do not (position, mass).
Did you check to see if the change to the
expecting that you have to wait after a stage, but with your new change, that wait became superfluous. At any rate, if |
@hvacengi can you do me a favor and show a minimal example case of a script that encounters the problem you mention when there is a yeild happening in an instruction that is both called from a trigger and from mainline code? I'm trying to get a handle on what the actual problem is that happens when you do this. I think I might be able to come up with an alternate solution that avoids the problem, if I can see a concrete example of it. |
Hm, I did not think to add a comment to the staging documentation. While not technically "breaking" it does break the behavior with previous versions so we might want to add that label so we remember to catch it in a change log. The wait opcode is the only good way to force the error I talked about:
It should give you a casting error when returning from the original call to |
This is a re-work of the ideas in PR KSP-KOS#1807, done a different way that avoids some of the problems that solution had. This is a collaborative effort between @hvacengi and @Dunbaratu to refine the solution into something more robust.
Automatic code formatting revisions even though @Dunbaratu doesn't like it. I just can't stand the extra white space.
stage.rst * Fix stage example not working * Fix no mention of the stage function * Note that the stage function now introduces a wait.
Fixes #1805
One of the few outstanding issues with this code is that it will technically crash in one very specific instance: if you call the exact same opcode while it is already waiting in mainline code, from a trigger. In that case there should be a stack misalignment, because the trigger will have pushed something to the stack for the opcode, but then the opcode will return from the wait for the trigger before it returns to mainline code. That means the trigger will attempt to continue to execute, without popping any previous arguments off of the stack first. I'm not sure of a good solution for this issue, and more importantly I think that this is why we should make it clear to users that they need to be careful about executing the same section of code from inside of triggers and mainline code at the same time.
Opcode.cs
CPU.cs
SafeFunctionBase.cs
Misc.cs