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

Exposed a CursorPosition resource #5079

Closed
wants to merge 3 commits into from

Conversation

ManevilleF
Copy link
Contributor

@ManevilleF ManevilleF commented Jun 23, 2022

Objective

Addresses #5034

Solution

I added a CursorPosition resource, updated every frame if WindowPlugin::update_cursor_position is enabled.

Usage:

Instead of:

fn my_system(windows: Res<Windows>) {
     let position = windows.get_primary().unwrap().cursor_position;
     if let Some(pos) = position {
        // Do stuff
     }
}

We have:

fn my_system(cursor: Res<CursorPosition>) {
     if let Some(pos) = cursor.position() {
        // Do stuff
     }
}

Notes

I think the update system should probably be in a PreUpdate stage?

Comment on lines 13 to 30
pub fn get(&self, id: WindowId) -> Option<Vec2> {
self.positions.get(&id).copied()
}

/// Retrieves the cursor position from the *primary* window
pub fn primary_position(&self) -> Option<Vec2> {
self.get(WindowId::primary())
}

/// Returns an iterator on cursor positions
pub fn positions_iter(&self) -> impl Iterator<Item = &Vec2> {
self.positions.values()
}

/// Returns an iterator on window ids and cursor positions
pub fn iter(&self) -> impl Iterator<Item = (&WindowId, &Vec2)> {
self.positions.iter()
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not just have these be methods on Windows?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I mean it could be but the related issue #5034 wants a separate resource

@tim-blackbird
Copy link
Contributor

tim-blackbird commented Jun 23, 2022

Only one window can have the cursor hover over it at a time, so window.cursor_position() only returns Some on one window each frame (I hope).
How about structuring the resource like this:

pub struct CursorPosition {
    pub(crate) position: Option<(Vec2, WindowId)>,
}

impl CursorPosition {
    // Most games only have one window. Make this case the simpler one.
    pub fn get(&self) -> Option<Vec2> {
        self.position.map(|(pos, _)| pos)
    }

    pub fn get_with_id(&self) -> Option<(Vec2, WindowId)> {
        self.position
    } 
}

Then it becomes:

fn my_system(cursor_position: Res<CursorPosition>) {
     if let Some(pos) = cursor_position.get() {
        // Do stuff
     }
}

@ManevilleF
Copy link
Contributor Author

@devil-ira thanks, I didn't know that only one window could store the cursor position.

I updated the resource

@ManevilleF ManevilleF changed the title Exposed a CursorPositions resource Exposed a CursorPosition resource Jun 23, 2022
@ManevilleF
Copy link
Contributor Author

I'm not very happy with this API. I'm closing it

@ManevilleF ManevilleF closed this Jun 23, 2022
@tim-blackbird
Copy link
Contributor

Whaaat. I like this though. It's certainly an improvement over the current state.

Can you say exactly what you're unhappy with?
Also, I don't mind adopting this if you don't want to work on it 😄

@ManevilleF
Copy link
Contributor Author

Sure, you can adopt it !

I don't really like the extra system approach, I think Windows could just have a getter for this.

@Weibye
Copy link
Contributor

Weibye commented Jun 23, 2022

The idea and API is good, I do think that this should be considered along with or after #4530
Or in other words, I believe #4530 is the "root cause" that this is trying to relieve a part of.

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.

4 participants