Skip to content
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

feat: fire input action events, synchronize methods #1

Merged
merged 23 commits into from
Jan 22, 2024

Conversation

wlsnmrk
Copy link
Contributor

@wlsnmrk wlsnmrk commented Jan 22, 2024

Action events

Improves support for the separation of input action events and action state in Godot 4.2, by changing StartAction() and EndAction() extension methods to fire input events. (That is, they now cause the engine to call, e.g., Node::_Input() as well as setting, e.g., Input::IsActionPressed().) Added tests for both events and state.

Synchronization

Improves testability by removing multi-frame waits (and async/await) from as many driver functions as practicable. This change permits users to test that operations happen at the time they're invoked, rather than at an indeterminate point in asynchronous frame processing. This is especially useful for operations that require same-frame checks, such as Input::IsActionJustPressed/Released(). This change also speeds up many tests, since there is less waiting on the engine to process frames. Users can continue to support multi-frame tests by using the waiting extension methods themselves.

Exceptions to synchronization

  • ActionsControlExtensions::HoldActionFor() - requires an await to hold the action
  • KeyboardControlExtensions::HoldKeyFor() - requires an await to hold the key press
  • Camera2DDriver::MoveIntoView() and Camera2DDriver::WaitUntilSteady() - because Camera2D incorporates its own motion-easing model, it's not straightforward to eliminate asynchrony in waiting for its motion to finish. I've added a method that starts moving the camera and returns immediately, but users who want to have the camera at its new position afterwards will need to use WaitUntilSteady() themselves.
  • Fixture::AddToRoot() and dependent methods - requires waiting a frame for a new Node's _Ready() method to be called
  • Fixture cleanup actions - may require asynchronous operations (e.g., deleting a file)

Synchronization friction points

I've made TabContainerDriver methods for selecting a tab synchronous, even though Godot takes an extra frame to update content visibility. In lieu of waiting for contents to become visible, I've added a note to the documentation for tab-selection methods about this, and updated the content-visibility test to manually wait a frame after selecting a tab and before checking visibility.

Documentation

Updated README to remove references to async/await where they were no longer applicable, and to note that input extensions are no longer asynchronous.

BREAKING CHANGES

Most driver methods are no longer async, are void instead of returning Task (or return T instead of Task<T>), and do not have a frame delay.

Added:
* New input action in the test project
* New test scene for action inputs
* New test script with tests for changes to global input state sim
  in Godot 4.2, in which Input::ParseInputEvent() no longer sets
  Input::IsActionPressed().
Added:
* New fake test node class for receiving and recording input events
* New tests checking that Start/EndAction() cause input events to
  be sent (currently failing)
Fixed Start/EndAction() in input extensions to fire input events for
starting and end actions, in addition to setting global state. New
tests for input events now pass.
Added new tests for Input::IsActionJustPressed/Released(), which
should be true immediately after starting or ending an action,
respectively.
BREAKING CHANGE: where possible, keyboard-input methods are no longer
async, are void instead of returning Task, and have no frame delay.
To make tests relying on mouse input more frame-accurate, made mouse-
input extensions synchronous. Set Relative property on simulated
mouse-motion events, since relative motion will no longer accumulate
in input buffer with immediate event flushing. Propagated
synchronicity to dependent driver methods and tests.

BREAKING CHANGE: mouse-input methods and many driver methods are no
longer async, are void instead of returning Task, and have no frame
delay.
To make tests relying on Control behavior more frame-accurate, made
control driver's GrabFocus() and ReleaseFocus() methods synchronous.

BREAKING CHANGE: Control driver's Grab/ReleaseFocus() methods are no
longer async, are void instead of returning Task, and have no frame
delay.
Made BaseButtonDriver::Press() synchronous and updated dependent
tests.

BREAKING CHANGE: BaseButtonDriver::Press() is no longer async, is
void instead of returning Task, and has no frame delay.
Verified the return value of the Camera2DDriver::MoveIntoView()
method to ensure the camera stabilized in its new position. Fixed
comment to reflect truth/falsity of sprite visibility.
BREAKING CHANGE: ItemList driver methods are no longer async, are
void instead of returning Task, and have no frame delay.
BREAKING CHANGE: LineEdit driver methods are no longer async, are
void instead of returning Task, and have no frame delay.
BREAKING CHANGE: OptionButtuon driver methods are no longer async,
are void instead of returning Task, and have no frame delay.
BREAKING CHANGE: PopupMenu driver methods are no longer async, are
void instead of returning Task, and have no frame delay.
BREAKING CHANGE: TextEdit driver methods are no longer async, are
void instead of returning Task, and have no frame delay.
BREAKING CHANGE: Window driver methods are no longer async, are void
instead of returning Task, and have no frame delay.
Updated description of WindowDriver::Close() to reflect that it
doesn't operate by clicking.
Also updated docs to reflect that Godot requires a frame after a tab
is selected before updating visibility of tab contents.

Also updated TabContainerDriver test to wait a frame after selecting
a tab, before checking content visibility, since the driver method no
longer has a frame delay.

BREAKING CHANGE: TabContainer driver methods are no longer async, are
void instead of returning Task, and have no frame delay.
BREAKING CHANGE: Fixture::LoadScene() methods are no longer async,
return T instead of Task<T>, and have no frame delay.
Changed Fixture::AddToRoot() to wait 1 frame intead of 2 for a new
node's _Ready() to be called.
To provide a synchronous option to users, added a method to the
Camera2D driver to start moving a target position into view without
waiting for the camera's motion to finish.
* Changed code examples in README that no longer require async/await
* Updated description of input simulation to reflect synchrony
* Pointed users toward the waiting extension examples from other
  parts of README in case they need to pump frames in tests
* Removed guidance to limit state modification to the engine's
  process notifications
* Removed guidance to include frame delays in driver code, in favor
  of precise frame pumping in tests as needed
Fixed documented return values for button and text-edit drivers, and
action and mouse input extensions, to reflect that they are now void
instead of returning Tasks.
@wlsnmrk wlsnmrk marked this pull request as ready for review January 22, 2024 21:20
@jolexxa jolexxa merged commit d10266f into chickensoft-games:main Jan 22, 2024
1 check passed
@wlsnmrk wlsnmrk deleted the synchronicity branch January 23, 2024 06:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants