-
Notifications
You must be signed in to change notification settings - Fork 50
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
Can we remove most of the conditional compilation stuff? #16
Comments
Have we considered removing the non-exhaustive What is the purpose of giving up guarantees by wrapping the handle in an non-exhaustive enum when our users have to write platform-specific code anyway? |
No the point is that an end user of this communication point sees it as just one thing let surface = instance.make_surface_for_window(&window).unwrap(); Since some systems potentially have more than one window system available, for this to move all the complexity away from the end user there cannot be window specific methods. |
@Lokathor The same way we currently force our users to pattern match using conditional compilation, we can force them to declare a function using conditional compilation too (they probably have to do this anyway): #[cfg(target_os = "ios")]
fn make_surface_for_window<W: HasIOSHandle>(&self, window: &W) -> Result<Surface, Error> {
// window.ui_window()
// window.ui_view()
// ...
} The main difference is that there won't be any need for non-exhaustive enums or fields, and there won't be misleading APIs taking an unsupported window handle and erroring at runtime. |
No, graphics libs aren't the end users. Graphics libs and window libs can both have a hard time and I don't much care because you sort it out a few times and then it's done. I mean actual end users that want to make a window and then tell a backend to work on that window. That is the situation that will be written out over and over in countless new projects and demos, and that's the case that we want to optimize simplicity for. |
@Lokathor I don't think my proposal would affect end users. In fact, I think it would help them. With my approach, if our end users try to compile a graphics library on an unsupported platform, they will get a compilation error instead of a runtime error. |
@Lokathor Reading through your argument, I don't see how removing the conditional compilation stuff makes things any easier for downstream users. I'd argue that it actually makes it harder to understand - making @hecrj We actually had a platform-specific trait design originally, although it admittedly wasn't exactly how you're proposing. That was removed because the people involved in the discussion didn't like the design (#1 #4 @kvark @Ralith), so we switched to the enum system. Looks like you can't please everyone 😅. That being said, switching to a design where you had a different top-level trait for each platform would complicate this crate's usage substantially, since you'd either need to have different functions for each platform that takes each different trait, or conditionally compile the different platform trait into a single function. I don't like either of those solutions. Believe me, I've done a lot of work with compile-time trait matching, and I don't think the complexity of that solution is worth the benefits here. |
@Osspial What about exposing #[cfg(target_os = "linux")]
pub trait HasRawWindowHandle: crate::unix::HasUnixHandle {}
#[cfg(target_os = "windows")]
pub trait HasRawWindowHandle: crate::windows::HasWindowsHandle {} Graphics libraries could then write a single function: impl Instance {
pub fn create_surface<W: HasRawWindowHandle>(&mut self, window: &W) -> Result<Surface, Error> {
#[cfg(target_os = "linux")]
let surface = self.create_surface_for_unix(window)?;
#[cfg(target_os = "windows")]
let surface = self.create_surface_for_windows(window)?;
// ...
Ok(surface)
}
} Would this work? This is very similar to what |
@hecrj ...huh! I can't see why that wouldn't work. Could you throw together a prototype implementing that? One small addition to that design is that It looks like we'll have to do a breaking change to differentiate between XLib and XCB anyway, so this design works I'm tempted to roll both changes into a single release. |
Closing this issue, since there doesn't seem to be a compelling reason to do this and the discussion in this issue has moved to a different topic. We can continue discussion of the trait prototype in #23. |
The conditional compilation stuff is an unnecessary complication to the system.
Basically, every library that consumes a
HasRawWindowHandle
value already needs to have a default, catch-all case where they get some unknown handle type and then error out. We even want the enum to be tagged as non-exhaustive so that the library can be "future proof" and force people to have a default cause so that we don't break semver when new window systems are eventually added.So since your consuming code's match statement already needs to say
at the end of it, then having the IOS handle conditionally compiled to not exist on windows doesn't actually add anything. Either way you can't have exhaustive matching.
And since we're just giving all of our handle definitions in terms of libc types and
core::ffi::c_void
and so forth there's not really a problem with pulling in all sorts of platform dependencies if we just have every variant compiled in on all platforms.So I think that never doing any conditional compilation is probably better in the long term. Makes things simpler to reason about.
The text was updated successfully, but these errors were encountered: