Skip to content

Commit

Permalink
Simplify client codegen with w_proxy_create
Browse files Browse the repository at this point in the history
  • Loading branch information
elinorbgr committed Feb 27, 2018
1 parent bd5a6a2 commit dec90e7
Show file tree
Hide file tree
Showing 2 changed files with 103 additions and 62 deletions.
69 changes: 65 additions & 4 deletions wayland-client/src/proxy.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use wayland_commons::{Implementation, Interface};
use wayland_commons::{Implementation, Interface, MessageGroup};

#[cfg(feature = "native_lib")]
use wayland_sys::client::wl_proxy;
use wayland_sys::client::*;

use std::sync::Arc;
use std::sync::atomic::{AtomicBool, AtomicPtr, Ordering};
Expand All @@ -28,6 +28,36 @@ pub struct Proxy<I: Interface> {
}

impl<I: Interface> Proxy<I> {
pub fn send(&self, msg: I::Requests) {
#[cfg(not(feature = "native_lib"))]
{
if !self.internal.alive.load(Ordering::Acquire) {
// don't send message to dead objects !
return;
}
unimplemented!()
}
#[cfg(feature = "native_lib")]
{
if let Some(ref internal) = self.internal {
// object is managed
if !internal.alive.load(Ordering::Acquire) {
// don't send message to dead objects !
return;
}
}
msg.as_raw_c_in(|opcode, args| unsafe {
ffi_dispatch!(
WAYLAND_CLIENT_HANDLE,
wl_proxy_marshal_array,
self.ptr,
opcode,
args.as_ptr() as *mut _
);
});
}
}

// returns false is external
pub fn is_alive(&self) -> bool {
#[cfg(not(feature = "native_lib"))]
Expand Down Expand Up @@ -85,12 +115,38 @@ impl<I: Interface> Proxy<I> {
}

#[doc(hidden)]
#[cfg(feature = "native_lib")]
pub unsafe fn new_null() -> Proxy<I> {
Proxy {
_i: ::std::marker::PhantomData,
internal: None,
ptr: ::std::ptr::null_mut(),
ptr: ::std::ptr::null_mut()
}
}

pub fn child<C: Interface>(&self) -> NewProxy<C> {
#[cfg(feature = "native_lib")]
{
let ptr = unsafe { ffi_dispatch!(
WAYLAND_CLIENT_HANDLE,
wl_proxy_create,
self.ptr,
C::c_interface()
) };
NewProxy {
_i: ::std::marker::PhantomData,
ptr: ptr,
}
}
}
}

#[cfg(feature = "native_lib")]
impl Proxy<::protocol::wl_display::WlDisplay> {
pub(crate) fn from_display(d: *mut wl_display) -> Proxy<::protocol::wl_display::WlDisplay> {
Proxy {
_i: ::std::marker::PhantomData,
internal: None,
ptr: d as *mut wl_proxy
}
}
}
Expand Down Expand Up @@ -139,6 +195,11 @@ impl<I: Interface + 'static> NewProxy<I> {
}
}

#[cfg(feature = "native_lib")]
pub fn c_ptr(&self) -> *mut wl_proxy {
self.ptr
}

#[cfg(feature = "native_lib")]
pub unsafe fn from_c_ptr(ptr: *mut wl_proxy) -> Self {
NewProxy {
Expand Down
96 changes: 38 additions & 58 deletions wayland-scanner/src/c_code_gen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -354,17 +354,7 @@ pub fn write_messagegroup_impl<O: Write>(
}
Type::NewId => {
if a.interface.is_some() {
if side == Side::Server {
// serialize like a regular object
if a.allow_null {
writeln!(out, "_args_array[{}].o = {}.map(|o| o.c_ptr() as *mut _).unwrap_or(::std::ptr::null_mut());", j, a.name)?;
} else {
writeln!(out, "_args_array[{}].o = {}.c_ptr() as *mut _;", j, a.name)?;
}
} else {
// this must be a NULL, ignore the dummy object received
writeln!(out, "_args_array[{}].o = ::std::ptr::null_mut();", j)?;
}
writeln!(out, "_args_array[{}].o = {}.c_ptr() as *mut _;", j, a.name)?;
} else {
if side == Side::Server {
panic!("Cannot serialize anonymous NewID from server.");
Expand Down Expand Up @@ -459,62 +449,53 @@ fn write_client_methods<O: Write>(name: &str, messages: &[Message], out: &mut O)
writeln!(out, " return;")?;
}
writeln!(out, " }}")?;
// prepare the proxies if applicable
let mut has_newp = false;
for a in &msg.args {
if a.typ == Type::NewId {
if let Some(ref iface) = a.interface {
writeln!(out, " let _arg_{}_newproxy = self.child::<super::{}::{}>();", a.name, iface, snake_to_camel(&iface))?;
has_newp = true;
}
}
}
// actually send the stuff
write!(
out,
" let msg = Requests::{}",
snake_to_camel(&msg.name)
)?;
if msg.args.len() > 0 {
write!(out, " {{ ")?;
writeln!(out, " {{ ")?;
for a in &msg.args {
write!(out, " ")?;
if a.typ == Type::NewId {
if let Some(ref iface) = a.interface {
write!(
writeln!(
out,
"{}: unsafe {{ Proxy::<super::{}::{}>::new_null() }}, ",
"{}: unsafe {{ Proxy::<super::{1}::{2}>::from_c_ptr(_arg_{0}_newproxy.c_ptr()) }}, ",
a.name,
iface,
snake_to_camel(&iface)
)?;
} else {
write!(out, "{}: (T::NAME.into(), version, unsafe {{ Proxy::<AnonymousObject>::new_null() }}),", a.name)?;
writeln!(out, "{}: (T::NAME.into(), version, unsafe {{ Proxy::<AnonymousObject>::new_null() }}),", a.name)?;
}
} else if a.typ == Type::Object {
if a.allow_null {
write!(out, "{0} : {0}.map(|o| o.clone()), ", a.name)?;
writeln!(out, "{0} : {0}.map(|o| o.clone()), ", a.name)?;
} else {
write!(out, "{0}: {0}.clone(), ", a.name)?;
writeln!(out, "{0}: {0}.clone(), ", a.name)?;
}
} else {
write!(out, "{}, ", a.name)?;
writeln!(out, "{0}: {0}, ", a.name)?;
}
}
write!(out, " }}")?;
write!(out, " }}")?;
}
writeln!(out, ";")?;
if let Some(ret_type) = return_type {
if let Some(ref iface) = ret_type.interface {
writeln!(
out,
r#"
unsafe {{
let ret = msg.as_raw_c_in(|opcode, args| {{
ffi_dispatch!(
WAYLAND_CLIENT_HANDLE,
wl_proxy_marshal_array_constructor,
self.c_ptr(),
opcode,
args.as_mut_ptr(),
super::{0}::{1}::c_interface()
)
}});
Ok(NewProxy::<super::{0}::{1}>::from_c_ptr(ret))
}}"#,
iface,
snake_to_camel(iface)
)?;
} else {
match return_type {
Some(ret_type) if ret_type.interface.is_none() => {
writeln!(
out,
r#"
Expand All @@ -533,25 +514,24 @@ fn write_client_methods<O: Write>(name: &str, messages: &[Message], out: &mut O)
Ok(NewProxy::<T>::from_c_ptr(ret))
}}"#
)?;
},
_ => {
writeln!(
out,
" self.send(msg);"
)?;
if has_newp {
for a in &msg.args {
if a.typ == Type::NewId {
if let Some(ref iface) = a.interface {
writeln!(out, " Ok(_arg_{}_newproxy)", a.name)?;
}
}
}
}
}
} else {
writeln!(
out,
r#"
unsafe {{
msg.as_raw_c_in(|opcode, args| {{
ffi_dispatch!(
WAYLAND_CLIENT_HANDLE,
wl_proxy_marshal_array,
self.c_ptr(),
opcode,
args.as_mut_ptr()
);
}});
}}"#
)?;
}
writeln!(out, " }}")?;
writeln!(out, " }}\n")?;
}
writeln!(out, " }}")?;

Expand Down

0 comments on commit dec90e7

Please sign in to comment.