{"action":"opened","issue":{"url":"https://api.github.com/repos/AngryLawyer/rust-sdl2/issues/322","labels_url":"https://api.github.com/repos/AngryLawyer/rust-sdl2/issues/322/labels{/name}","comments_url":"https://api.github.com/repos/AngryLawyer/rust-sdl2/issues/322/comments","events_url":"https://api.github.com/repos/AngryLawyer/rust-sdl2/issues/322/events","html_url":"https://github.com/AngryLawyer/rust-sdl2/issues/322","id":56628588,"number":322,"title":"Window mutability, event loop, serious lifetime issues","user":{"login":"nukep","id":1551458,"avatar_url":"https://avatars.githubusercontent.com/u/1551458?v=3","gravatar_id":"","url":"https://api.github.com/users/nukep","html_url":"https://github.com/nukep","followers_url":"https://api.github.com/users/nukep/followers","following_url":"https://api.github.com/users/nukep/following{/other_user}","gists_url":"https://api.github.com/users/nukep/gists{/gist_id}","starred_url":"https://api.github.com/users/nukep/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/nukep/subscriptions","organizations_url":"https://api.github.com/users/nukep/orgs","repos_url":"https://api.github.com/users/nukep/repos","events_url":"https://api.github.com/users/nukep/events{/privacy}","received_events_url":"https://api.github.com/users/nukep/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":0,"created_at":"2015-02-05T05:16:36Z","updated_at":"2015-02-05T05:16:36Z","closed_at":null,"body":"`Window`:  **It's a clusterf* *k.**\r\n\r\nSo far, the methods in `Window` only take shared `&self` references. I considered the possibility of changing the setters to `&mut self`, but there are deep-rooted problems...\r\n\r\nSDL can change just about everything about a `Window` from the event loop. If the user resizes or drags the window, the window will get mutated at the event loop and our exclusive `&mut self` method call will do us no good.\r\nSo at that point, I gathered that the \"setters\" such as `set_title()` or `set_size()` could stay as `&self` and could be seen more as \"event sending\". It's very race-condition-y (but not quite a race condition), but that's how SDL decided to do things. Fine. We can work with that.\r\n\r\n**But then there's `Window::get_surface()`, or `SDL_GetWindowSurface()`.** Hoh boy.\r\n\r\n`SDL_GetWindowSurface()` obtains a surface handle owned by the window. It's useful for when we want to draw directly to the window without using a renderer.\r\n\r\nHere's a rather large caveat: every time the window is resized, the `Surface` is _destroyed and reallocated_.\r\n* Proof: https://github.com/spurious/SDL-mirror/blob/c2c793b74c2c9478814e4d49ea44577a6829c154/src/video/SDL_video.c#L2161 https://github.com/spurious/SDL-mirror/blob/c2c793b74c2c9478814e4d49ea44577a6829c154/src/video/SDL_video.c#L1962\r\n\r\n```rust\r\nloop {\r\n   let surface = window.get_surface();\r\n   run_sdl2_event_loop();\r\n   surface.get_size();         // CRASH (sometimes)\r\n   // ...\r\n}\r\n```\r\n\r\nWe really need some way to enforce the lifetime of a `Surface` obtained from a window.\r\nAny time that the window _could_ be resized (such as at the event loop or `Window::set_size()`), the lifetime must end.\r\nWe could add `&mut self` to window setters and add a lifetime parameter to `Surface`--which would partially solve the problem--but we would also need to ensure that no `Surface<'window>` values live through the event loop.\r\n\r\n**And don't forget about Renderer, which can consume a Window.**\r\n\r\nI'm currently unsure what will happen if you:\r\n\r\n1. Create a software renderer and draw a shape\r\n2. Resize the window with `Window::set_size()`\r\n3. Draw another shape and present\r\n\r\nIt's probably not good.\r\n\r\n---\r\nThe most ideal implementation is that we add `&mut self` to the window setters, _and_ guarantee a lifetime when the event loop won't intervene with the Window. It would solve the Surface issue, and mutable setters are generally clearer for intent. The question is how to safely pull it off...\r\n\r\n:confounded: :confounded: :confounded: "}}