1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
use browser_window_ffi::*;
use std::ops::Deref;
use std::rc::Rc;
use std::sync::Arc;

use super::common::*;



/// A thread-unsafe handle to an application instance.

/// Use this to start the application with.

#[derive(Clone)]
pub struct Application {
	pub inner: Rc<ApplicationInner>
}



/// A thread-safe application handle.

/// This handle also allows you to dispatch code to be executed on the GUI thread.

#[derive(Clone)]
pub struct ApplicationAsync {
	pub inner: Arc<ApplicationInner>
}



/// An application handle that can not be instantiated,

///     but is provided by certain handlers.

#[derive(Clone)]
pub struct ApplicationHandle {
	pub _ffi_handle: *mut bw_Application
}
unsafe impl Send for ApplicationHandle {}
unsafe impl Sync for ApplicationHandle {}

/// The future that dispatches a closure onto the GUI thread

pub type ApplicationDispatchFuture<'a,R> = DispatchFuture<'a, ApplicationHandle, R>;

pub struct ApplicationInner {
	pub inner: ApplicationHandle
}



impl Application {

	/// Get an async clone of this handle

	pub fn into_async( self ) -> ApplicationAsync {
		
		// Convert an Rc to an Arc

		let inner = unsafe { Arc::from_raw( Rc::into_raw( self.inner ) ) };
		
		ApplicationAsync {
			inner: inner
		}
	}

	/// Constructs a new application handle

	/// Only call this once

	pub fn new() -> Self {
		let ffi_handle = unsafe { bw_Application_new() };

		Self {
			inner: Rc::new( ApplicationInner{
				inner: ApplicationHandle {
					_ffi_handle: ffi_handle
				}
			} )
		}
	}

	/// Run the main loop.

	/// This method finishes when all windows are closed.

	pub fn run( &self ) -> i32 {
		unsafe { bw_Application_run( self.inner._ffi_handle ) }
	}
}

impl Deref for Application {
	type Target = ApplicationHandle;

	fn deref( &self ) -> &Self::Target {
		&**self.inner
	}
}

impl AppHandle for ApplicationHandle {
	fn app_handle( &self ) -> ApplicationHandle {
		ApplicationHandle {
			_ffi_handle: self._ffi_handle
		}
	}
}

impl ApplicationAsync {

	/// Clones the async version of this application handle into a non-async version.

	/// This is unsafe because the non-async version of the handle may only be used on the thread it was created on,

	///  while this method might not have been called on that thread

	unsafe fn clone_threadunsafe_handle( &self ) -> ApplicationHandle {
		ApplicationHandle {
			_ffi_handle: (**self.inner)._ffi_handle.clone()
		}
	}

	/// Executes the given closure on the GUI thread.

	pub fn dispatch<'a,F,R>( &self, func: F ) -> ApplicationDispatchFuture<'a,R> where
		F: FnOnce( ApplicationHandle ) -> R + Send + 'a,
		R: Send
	{
		ApplicationDispatchFuture::<'a,R>::new( unsafe { self.clone_threadunsafe_handle() }, func )
	}

	/// Signals the application to exit.

	/// The run command will return the exit code provided.

	pub fn exit( &self, exit_code: u32 ) {
		// The thread-safe version of bw_Application_exit:

		unsafe { bw_Application_exitAsync( self.inner._ffi_handle, exit_code as _ ); }
	}
}

impl From<Application> for ApplicationAsync {
	fn from( app: Application ) -> Self {
		app.into_async()
	}
}



impl ApplicationHandle {

	/// Causes the run function to exit.

	/// 

	/// # Arguments

	/// * `exit_code` - The code that will be returned by the run function when it stops.

	pub fn exit( &self, exit_code: u32 ) {
		unsafe { bw_Application_exit( self._ffi_handle, exit_code as _ ); }
	}

	// Constructs an ApplicationHandle from an internal C handle

	pub fn from_ptr( ptr: &mut bw_Application ) -> ApplicationHandle {
		ApplicationHandle {
			_ffi_handle: ptr
		}
	}
}



impl Deref for ApplicationInner {
	type Target = ApplicationHandle;

	fn deref( &self ) -> &Self::Target {
		&self.inner
	}
}

impl Drop for ApplicationInner {
	fn drop( &mut self ) {
		unsafe { bw_Application_free( self._ffi_handle ) }
	}
}