This repository has been archived by the owner on Nov 26, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
5 changed files
with
426 additions
and
28 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,7 @@ | ||
[package] | ||
|
||
name = "grust" | ||
version = "0.1.3" | ||
version = "0.2.0-dev" | ||
authors = ["Mikhail Zabaluev <[email protected]>"] | ||
license = "LGPL-2.1+" | ||
readme = "README.md" | ||
|
@@ -15,6 +15,6 @@ generated crates. | |
repository = "https://github.com/gi-rust/grust.git" | ||
|
||
[dependencies] | ||
glib-2_0-sys = "0.1.0" | ||
glib-2_0-sys = "0.1.1" | ||
gobject-2_0-sys = "0.1.0" | ||
libc = "0.1" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,6 @@ | ||
// This file is part of Grust, GObject introspection bindings for Rust | ||
// | ||
// Copyright (C) 2014 Mikhail Zabaluev <[email protected]> | ||
// Copyright (C) 2014, 2015 Mikhail Zabaluev <[email protected]> | ||
// | ||
// This library is free software; you can redistribute it and/or | ||
// modify it under the terms of the GNU Lesser General Public | ||
|
@@ -17,12 +17,103 @@ | |
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | ||
|
||
use refcount::{Refcount, Ref}; | ||
use types::FALSE; | ||
use types::{FALSE, TRUE}; | ||
use types::{gboolean, gint, gpointer, guint}; | ||
use util::{box_free, box_from_pointer, box_into_pointer, into_destroy_notify}; | ||
use wrap; | ||
use wrap::Wrapper; | ||
|
||
use glib as ffi; | ||
use gobject; | ||
use std::convert; | ||
use std::marker; | ||
use std::mem; | ||
|
||
pub const PRIORITY_DEFAULT : gint = ffi::G_PRIORITY_DEFAULT; | ||
pub const PRIORITY_DEFAULT_IDLE : gint = ffi::G_PRIORITY_DEFAULT_IDLE; | ||
pub const PRIORITY_HIGH : gint = ffi::G_PRIORITY_HIGH; | ||
pub const PRIORITY_HIGH_IDLE : gint = ffi::G_PRIORITY_HIGH_IDLE; | ||
pub const PRIORITY_LOW : gint = ffi::G_PRIORITY_LOW; | ||
|
||
pub enum CallbackResult { Remove, Continue } | ||
pub use self::CallbackResult::*; | ||
|
||
pub struct RawCallback { | ||
func: ffi::GSourceFunc, | ||
data: gpointer, | ||
destroy: ffi::GDestroyNotify | ||
} | ||
|
||
impl Drop for RawCallback { | ||
fn drop(&mut self) { | ||
(self.destroy)(self.data); | ||
} | ||
} | ||
|
||
unsafe fn into_source_func(func: unsafe extern "C" fn(gpointer) -> gboolean) | ||
-> ffi::GSourceFunc | ||
{ | ||
mem::transmute(func) | ||
} | ||
|
||
unsafe extern "C" fn source_func<F>(callback_data: gpointer) -> gboolean | ||
where F: FnMut() -> CallbackResult | ||
{ | ||
let mut callback: Box<F> = box_from_pointer(callback_data); | ||
let res = callback(); | ||
mem::forget(callback); | ||
match res { | ||
Remove => FALSE, | ||
Continue => TRUE | ||
} | ||
} | ||
|
||
unsafe extern "C" fn source_once_func<F>(callback_data: gpointer) -> gboolean | ||
where F: FnOnce() | ||
{ | ||
let mut holder: Box<Option<F>> = box_from_pointer(callback_data); | ||
let callback = holder.take().expect("a callback closure expected"); | ||
mem::forget(holder); | ||
callback(); | ||
FALSE | ||
} | ||
|
||
pub struct SourceCallback(RawCallback); | ||
|
||
impl Into<RawCallback> for SourceCallback { | ||
#[inline] | ||
fn into(self) -> RawCallback { | ||
self.0 | ||
} | ||
} | ||
|
||
impl SourceCallback { | ||
pub fn new<F>(closure: F) -> Self | ||
where F: Send + 'static, F: FnMut() -> CallbackResult | ||
{ | ||
let boxed_closure = Box::new(closure); | ||
SourceCallback(unsafe { | ||
RawCallback { | ||
func: into_source_func(source_func::<F>), | ||
data: box_into_pointer(boxed_closure), | ||
destroy: into_destroy_notify(box_free::<F>) | ||
} | ||
}) | ||
} | ||
|
||
pub fn once<F>(closure: F) -> Self | ||
where F: Send + 'static, F: FnOnce() | ||
{ | ||
let holder = Box::new(Some(closure)); | ||
SourceCallback(unsafe { | ||
RawCallback { | ||
func: into_source_func(source_once_func::<F>), | ||
data: box_into_pointer(holder), | ||
destroy: into_destroy_notify(box_free::<Option<F>>) | ||
} | ||
}) | ||
} | ||
} | ||
|
||
#[repr(C)] | ||
pub struct MainContext { | ||
|
@@ -41,6 +132,19 @@ impl MainContext { | |
wrap::from_raw(ffi::g_main_context_default()) | ||
} | ||
} | ||
|
||
pub fn invoke(&self, callback: SourceCallback) { | ||
self.invoke_full(PRIORITY_DEFAULT, callback) | ||
} | ||
|
||
pub fn invoke_full(&self, priority: gint, callback: SourceCallback) { | ||
let raw: RawCallback = callback.into(); | ||
unsafe { | ||
ffi::g_main_context_invoke_full(self.as_mut_ptr(), | ||
priority, raw.func, raw.data, Some(raw.destroy)); | ||
} | ||
mem::forget(raw); | ||
} | ||
} | ||
|
||
impl Refcount for MainContext { | ||
|
@@ -56,6 +160,111 @@ impl Refcount for MainContext { | |
|
||
g_impl_boxed_type_for_ref!(MainContext, gobject::g_main_context_get_type); | ||
|
||
#[repr(C)] | ||
pub struct Source<Callback = SourceCallback> { | ||
raw: ffi::GSource, | ||
phantom_data: marker::PhantomData<Callback> | ||
} | ||
|
||
#[repr(C)] | ||
pub struct AttachedSource<Callback> { | ||
raw: ffi::GSource, | ||
phantom_data: marker::PhantomData<Callback> | ||
} | ||
|
||
unsafe impl<C> Send for Source<C> where C: Into<RawCallback> { } | ||
|
||
unsafe impl<C> Send for AttachedSource<C> where C: Into<RawCallback> { } | ||
unsafe impl<C> Sync for AttachedSource<C> where C: Into<RawCallback> { } | ||
|
||
macro_rules! common_source_impls { | ||
($name:ident) => { | ||
unsafe impl<C> Wrapper for $name<C> { | ||
type Raw = ffi::GSource; | ||
} | ||
|
||
impl<C> Refcount for $name<C> { | ||
unsafe fn inc_ref(&self) { | ||
ffi::g_source_ref(self.as_mut_ptr()); | ||
} | ||
unsafe fn dec_ref(&self) { | ||
ffi::g_source_unref(self.as_mut_ptr()); | ||
} | ||
} | ||
} | ||
} | ||
|
||
common_source_impls!(Source); | ||
common_source_impls!(AttachedSource); | ||
|
||
impl<C> Source<C> where C: Into<RawCallback> { | ||
pub fn set_callback(&self, callback: C) | ||
{ | ||
let raw: RawCallback = callback.into(); | ||
unsafe { | ||
ffi::g_source_set_callback(self.as_mut_ptr(), | ||
raw.func, raw.data, Some(raw.destroy)); | ||
} | ||
mem::forget(raw); | ||
} | ||
|
||
pub fn set_priority(&self, priority: gint) { | ||
unsafe { | ||
ffi::g_source_set_priority(self.as_mut_ptr(), priority); | ||
} | ||
} | ||
} | ||
|
||
impl<C> Ref<Source<C>> { | ||
pub fn attach(self, ctx: &MainContext) -> Ref<AttachedSource<C>> { | ||
unsafe { | ||
let source_ptr = self.as_mut_ptr(); | ||
ffi::g_source_attach(source_ptr, ctx.as_mut_ptr()); | ||
mem::forget(self); | ||
Ref::from_raw(source_ptr) | ||
} | ||
} | ||
} | ||
|
||
impl<C> AttachedSource<C> { | ||
#[inline] | ||
pub fn as_source(&self) -> &Source<C> { | ||
unsafe { wrap::from_raw(self.as_ptr()) } | ||
} | ||
|
||
pub fn destroy(&self) { | ||
unsafe { ffi::g_source_destroy(self.as_mut_ptr()) } | ||
} | ||
} | ||
|
||
impl<C> convert::AsRef<Source<C>> for AttachedSource<C> { | ||
#[inline] | ||
fn as_ref(&self) -> &Source<C> { | ||
self.as_source() | ||
} | ||
} | ||
|
||
pub fn idle_source_new() -> Ref<Source> { | ||
unsafe { | ||
let source = ffi::g_idle_source_new(); | ||
Ref::from_raw(source) | ||
} | ||
} | ||
|
||
pub fn timeout_source_new(interval: guint) -> Ref<Source> { | ||
unsafe { | ||
let source = ffi::g_timeout_source_new(interval); | ||
Ref::from_raw(source) | ||
} | ||
} | ||
|
||
pub fn timeout_source_new_seconds(interval: guint) -> Ref<Source> { | ||
unsafe { | ||
let source = ffi::g_timeout_source_new_seconds(interval); | ||
Ref::from_raw(source) | ||
} | ||
} | ||
|
||
#[repr(C)] | ||
pub struct MainLoop { | ||
raw: ffi::GMainLoop | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.