Skip to content

Commit

Permalink
Make Context an opaque type and add a (stupid) example
Browse files Browse the repository at this point in the history
  • Loading branch information
crumblingstatue committed Oct 23, 2024
1 parent 54b68a2 commit 60e1efc
Show file tree
Hide file tree
Showing 7 changed files with 84 additions and 50 deletions.
30 changes: 30 additions & 0 deletions CSFML/src/Window/Context.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#include <SFML/Window/Context.hpp>
#include <cstdint>

extern "C" sf::Context *sfContext_new(void) {
return new sf::Context;
}

extern "C" void sfContext_del(sf::Context *context) {
delete context;
}

extern "C" bool sfContext_setActive(sf::Context *context, bool active) {
return context->setActive(active);
}

extern "C" const sf::ContextSettings *sfContext_getSettings(const sf::Context *context) {
return &context->getSettings();
}

extern "C" uint64_t sfContext_getActiveContextId() {
return sf::Context::getActiveContextId();
}

extern "C" const sf::Context *sfContext_getActiveContext() {
return sf::Context::getActiveContext();
}

extern "C" sf::GlFunctionPointer sfContext_getFunction(const char *name) {
return sf::Context::getFunction(name);
}
25 changes: 0 additions & 25 deletions CSFML/src/Window/Window.cpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
#include "System/Vector2.hpp"
#include "Window/VideoMode.hpp"
#include <SFML/Window/Window.hpp>
#include <SFML/Window/Context.hpp>
#include <SFML/Window/Touch.hpp>
#include <cstdint>

Expand Down Expand Up @@ -122,27 +121,3 @@ extern "C" void sfWindow_setJoystickThreshold(sf::Window *window, float threshol
extern "C" sf::WindowHandle sfWindow_getSystemHandle(const sf::Window *window) {
return window->getSystemHandle();
}

extern "C" sf::Context *sfContext_new(void) {
return new sf::Context;
}

extern "C" void sfContext_del(sf::Context *context) {
delete context;
}

extern "C" bool sfContext_setActive(sf::Context *context, bool active) {
return context->setActive(active);
}

extern "C" const sf::ContextSettings *sfContext_getSettings(const sf::Context *context) {
return &context->getSettings();
}

extern "C" uint64_t sfContext_getActiveContextId() {
return sf::Context::getActiveContextId();
}

extern "C" sf::GlFunctionPointer sfContext_getFunction(const char *name) {
return sf::Context::getFunction(name);
}
1 change: 1 addition & 0 deletions build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,7 @@ fn main() {
"CSFML/src/Window/Touch.cpp",
"CSFML/src/Window/VideoMode.cpp",
"CSFML/src/Window/Window.cpp",
"CSFML/src/Window/Context.cpp",
]
.iter(),
);
Expand Down
29 changes: 29 additions & 0 deletions examples/opengl-context.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
use sfml::{window::Context, SfResult};

fn main() -> SfResult<()> {
// We have no active context, so this should be null
assert_eq!(Context::active_context(), std::ptr::null());
{
// Let's create a context
let mut ctx = Context::new()?;
// I guess the active context should now be the same as what we have
assert_eq!(Context::active_context(), &*ctx);
eprintln!("Active context id: {}", Context::active_context_id());
let settings = ctx.settings();
eprintln!("Settings of created context: {settings:#?}");
ctx.set_active(false)?;
// Deactivated context, so this should be null
assert_eq!(Context::active_context(), std::ptr::null());
eprintln!("Active context id: {}", Context::active_context_id());
ctx.set_active(true)?;
// Activated once again
assert_eq!(Context::active_context(), &*ctx);
eprintln!("Active context id: {}", Context::active_context_id());
}
// Once again, no active context, so this should be null
assert_eq!(Context::active_context(), std::ptr::null());
// Try to query a random OpenGL function
dbg!(Context::get_function(c"glWhatever"));
eprintln!("Okay then... Goodbye!");
Ok(())
}
5 changes: 1 addition & 4 deletions src/ffi/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,10 @@ use crate::{
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};

decl_opaque! {
pub(crate) sfContext;
}

pub(super) type sfWindow = crate::window::Window;
pub(super) type sfCursor = crate::window::Cursor;
pub(crate) type sfVideoModeVector = crate::cpp::CppVector<sfVideoMode>;
pub(super) type sfContext = crate::window::Context;

/// Enumeration of the native system cursor types.
///
Expand Down
14 changes: 8 additions & 6 deletions src/ffi/window_bindgen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,14 @@ unsafe extern "C" {
// Clipboard.cpp
pub fn sfClipboard_getUnicodeString() -> *mut sfString;
pub fn sfClipboard_setUnicodeString(text: *const u32);
// Context.cpp
pub fn sfContext_new() -> *mut sfContext;
pub fn sfContext_del(context: *mut sfContext);
pub fn sfContext_setActive(context: *mut sfContext, active: bool) -> bool;
pub fn sfContext_getSettings(context: *const sfContext) -> *const sfContextSettings;
pub fn sfContext_getActiveContextId() -> u64;
pub fn sfContext_getActiveContext() -> *const sfContext;
pub fn sfContext_getFunction(name: *const c_char) -> sfGlFunctionPointer;
// Cursor.cpp
pub fn sfCursor_new() -> *mut sfCursor;
pub fn sfCursor_del(cursor: *mut sfCursor);
Expand Down Expand Up @@ -75,11 +83,5 @@ pub fn sfWindow_display(window: *mut sfWindow);
pub fn sfWindow_setFramerateLimit(window: *mut sfWindow, limit: c_uint);
pub fn sfWindow_setJoystickThreshold(window: *mut sfWindow, threshold: f32);
pub fn sfWindow_getSystemHandle(window: *const sfWindow) -> sfWindowHandle;
pub fn sfContext_new() -> *mut sfContext;
pub fn sfContext_del(context: *mut sfContext);
pub fn sfContext_setActive(context: *mut sfContext, active: bool) -> bool;
pub fn sfContext_getSettings(context: *const sfContext) -> *const sfContextSettings;
pub fn sfContext_getActiveContextId() -> u64;
pub fn sfContext_getFunction(name: *const c_char) -> sfGlFunctionPointer;

}
30 changes: 15 additions & 15 deletions src/window/context.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
use {
crate::{ffi::window as ffi, window::ContextSettings, IntoSfResult, SfResult},
crate::{cpp::FBox, ffi::window as ffi, window::ContextSettings, IntoSfResult, SfResult},
std::ffi::CStr,
};

decl_opaque! {
/// Type holding a valid drawing context.
///
/// If you need to make OpenGL calls without having an active window (like in a thread),
Expand All @@ -16,30 +17,35 @@ use {
/// To use a `Context` instance, just construct it and let it live as long as you need
/// a valid context. No explicit activation is needed, all it has to do is to exist.
/// Its destructor will take care of deactivating and freeing all the attached resources.
#[derive(Debug)]
pub struct Context(*mut ffi::sfContext);
pub Context;
}

impl Context {
/// Creates and activates a new context.
#[must_use]
pub fn new() -> Context {
Context(unsafe { ffi::sfContext_new() })
pub fn new() -> SfResult<FBox<Self>> {
FBox::new(unsafe { ffi::sfContext_new() }).into_sf_result()
}

/// Explicitly activates or deactivates the context.
///
/// # Arguments
/// * active - `true` to activate, `false` to deactivate
pub fn set_active(&mut self, active: bool) -> SfResult<()> {
unsafe { ffi::sfContext_setActive(self.0, active) }.into_sf_result()
unsafe { ffi::sfContext_setActive(self, active) }.into_sf_result()
}
/// Get the settings of the context.
///
/// Note that these settings may be different than the ones passed to the constructor;
/// they are indeed adjusted if the original settings are not directly supported by the system.
#[must_use]
pub fn settings(&self) -> &ContextSettings {
unsafe { &*ffi::sfContext_getSettings(self.0) }
unsafe { &*ffi::sfContext_getSettings(self) }
}

/// Return a raw pointer to the currently active context
pub fn active_context() -> *const Context {
unsafe { ffi::sfContext_getActiveContext()}
}

/// Get the currently active context's ID.
Expand Down Expand Up @@ -69,7 +75,7 @@ fn test_settings() {
Window::new_open((32, 32), "test", Default::default(), &Default::default()).unwrap();
let win_settings = *window.settings();
thread::spawn(move || {
let context = Context::new();
let context = Context::new().unwrap();
assert_eq!(context.settings(), &win_settings);
})
.join()
Expand All @@ -80,13 +86,7 @@ impl Drop for Context {
/// Deactivates and destroys the context.
fn drop(&mut self) {
unsafe {
ffi::sfContext_del(self.0);
ffi::sfContext_del(self);
}
}
}

impl Default for Context {
fn default() -> Self {
Context::new()
}
}

0 comments on commit 60e1efc

Please sign in to comment.