diff options
author | Takashi Sakamoto <o-takashi@sakamocchi.jp> | 2022-05-06 17:52:13 +0900 |
---|---|---|
committer | Takashi Sakamoto <o-takashi@sakamocchi.jp> | 2022-05-06 17:53:06 +0900 |
commit | df4b3f2d577d4f0d54c64aa8724c6fb6697f43c5 (patch) | |
tree | d9d6d0cbe890985b01cf616baf45744cad30ff8f | |
parent | 1e5a789c75cc387eea9f7659dfdd31fbb043dca0 (diff) | |
download | hinawa-rs-df4b3f2d577d4f0d54c64aa8724c6fb6697f43c5.tar.gz |
hinawa: add support for subclass
The glib crate enables users to implement subclass of existent object
class. It requires some helper implementations.
This commit adds support for the subclass. Currently subclass for below
classes are available:
* FwNode
* FwReq
* FwResp
* FwFcp
The subclass for the other classes will be available by the other crate
project.
Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
-rw-r--r-- | hinawa/src/lib.rs | 2 | ||||
-rw-r--r-- | hinawa/src/subclass/fw_fcp.rs | 47 | ||||
-rw-r--r-- | hinawa/src/subclass/fw_node.rs | 68 | ||||
-rw-r--r-- | hinawa/src/subclass/fw_req.rs | 57 | ||||
-rw-r--r-- | hinawa/src/subclass/fw_resp.rs | 131 | ||||
-rw-r--r-- | hinawa/src/subclass/mod.rs | 22 |
6 files changed, 327 insertions, 0 deletions
diff --git a/hinawa/src/lib.rs b/hinawa/src/lib.rs index 1acbb9b..595cc32 100644 --- a/hinawa/src/lib.rs +++ b/hinawa/src/lib.rs @@ -10,6 +10,8 @@ mod snd_motu_register_dsp_parameter; mod snd_tscm; mod snd_unit; +pub mod subclass; + pub use crate::{ auto::*, fw_node::*, fw_req::*, fw_resp::*, snd_efw::*, snd_motu::*, snd_motu_register_dsp_parameter::*, snd_tscm::*, snd_unit::*, diff --git a/hinawa/src/subclass/fw_fcp.rs b/hinawa/src/subclass/fw_fcp.rs new file mode 100644 index 0000000..e1a0dd0 --- /dev/null +++ b/hinawa/src/subclass/fw_fcp.rs @@ -0,0 +1,47 @@ +// SPDX-License-Identifier: MIT + +use super::*; + +pub trait FwFcpImpl: ObjectImpl + FwRespImpl + FwFcpImplExt { + fn responded(&self, fcp: &FwFcp, frame: &[u8]) { + self.parent_responded(fcp, frame) + } +} + +pub trait FwFcpImplExt: ObjectSubclass { + fn parent_responded(&self, fcp: &FwFcp, frame: &[u8]); +} + +impl<T: FwFcpImpl> FwFcpImplExt for T { + fn parent_responded(&self, fcp: &FwFcp, frame: &[u8]) { + unsafe { + let data = T::type_data(); + let parent_class = data.as_ref().parent_class() as *mut ffi::HinawaFwFcpClass; + let f = (*parent_class) + .responded + .expect("No parent class implementation for \"responded\""); + f(fcp.to_glib_none().0, frame.as_ptr(), frame.len() as u32) + } + } +} + +unsafe impl<T: FwFcpImpl> IsSubclassable<T> for FwFcp { + fn class_init(class: &mut Class<Self>) { + Self::parent_class_init::<T>(class); + + let klass = class.as_mut(); + klass.responded = Some(fw_fcp_responded::<T>); + } +} + +unsafe extern "C" fn fw_fcp_responded<T: FwFcpImpl>( + ptr: *mut ffi::HinawaFwFcp, + frame: *const u8, + length: c_uint, +) { + let instance = &*(ptr as *mut T::Instance); + let imp = instance.imp(); + let wrap: Borrowed<FwFcp> = from_glib_borrow(ptr); + + imp.responded(&wrap, std::slice::from_raw_parts(frame, length as usize)) +} diff --git a/hinawa/src/subclass/fw_node.rs b/hinawa/src/subclass/fw_node.rs new file mode 100644 index 0000000..0503049 --- /dev/null +++ b/hinawa/src/subclass/fw_node.rs @@ -0,0 +1,68 @@ +// SPDX-License-Identifier: MIT + +use super::*; + +pub trait FwNodeImpl: ObjectImpl + FwNodeImplExt { + fn bus_update(&self, node: &FwNode) { + self.parent_bus_update(node) + } + + fn disconnected(&self, node: &FwNode) { + self.parent_disconnected(node) + } +} + +pub trait FwNodeImplExt: ObjectSubclass { + fn parent_bus_update(&self, node: &FwNode); + fn parent_disconnected(&self, node: &FwNode); +} + +impl<T: FwNodeImpl> FwNodeImplExt for T { + fn parent_bus_update(&self, node: &FwNode) { + unsafe { + let data = T::type_data(); + let parent_class = data.as_ref().parent_class() as *mut ffi::HinawaFwNodeClass; + let f = (*parent_class) + .bus_update + .expect("No parent class implementation for \"bus_update\""); + f(node.to_glib_none().0) + } + } + + fn parent_disconnected(&self, node: &FwNode) { + unsafe { + let data = T::type_data(); + let parent_class = data.as_ref().parent_class() as *mut ffi::HinawaFwNodeClass; + let f = (*parent_class) + .disconnected + .expect("No parent class implementation for \"disconnected\""); + f(node.to_glib_none().0); + } + } +} + +unsafe impl<T: FwNodeImpl> IsSubclassable<T> for FwNode { + fn class_init(class: &mut Class<Self>) { + Self::parent_class_init::<T>(class); + + let klass = class.as_mut(); + klass.bus_update = Some(fw_node_bus_update::<T>); + klass.disconnected = Some(fw_node_disconnected::<T>); + } +} + +unsafe extern "C" fn fw_node_bus_update<T: FwNodeImpl>(ptr: *mut ffi::HinawaFwNode) { + let instance = &*(ptr as *mut T::Instance); + let imp = instance.imp(); + let wrap: Borrowed<FwNode> = from_glib_borrow(ptr); + + imp.bus_update(&wrap) +} + +unsafe extern "C" fn fw_node_disconnected<T: FwNodeImpl>(ptr: *mut ffi::HinawaFwNode) { + let instance = &*(ptr as *mut T::Instance); + let imp = instance.imp(); + let wrap: Borrowed<FwNode> = from_glib_borrow(ptr); + + imp.disconnected(&wrap) +} diff --git a/hinawa/src/subclass/fw_req.rs b/hinawa/src/subclass/fw_req.rs new file mode 100644 index 0000000..d174715 --- /dev/null +++ b/hinawa/src/subclass/fw_req.rs @@ -0,0 +1,57 @@ +// SPDX-License-Identifier: MIT + +use super::*; + +pub trait FwReqImpl: ObjectImpl + FwReqImplExt { + fn responded(&self, req: &FwReq, rcode: FwRcode, frame: &[u8]) { + self.parent_responded(req, rcode, frame) + } +} + +pub trait FwReqImplExt: ObjectSubclass { + fn parent_responded(&self, req: &FwReq, rcode: FwRcode, frame: &[u8]); +} + +impl<T: FwReqImpl> FwReqImplExt for T { + fn parent_responded(&self, req: &FwReq, rcode: FwRcode, frame: &[u8]) { + unsafe { + let data = T::type_data(); + let parent_class = data.as_ref().parent_class() as *mut ffi::HinawaFwReqClass; + let f = (*parent_class) + .responded + .expect("No parent class implementation for \"responded\""); + f( + req.to_glib_none().0, + rcode.into_glib(), + frame.as_ptr(), + frame.len() as u32, + ) + } + } +} + +unsafe impl<T: FwReqImpl> IsSubclassable<T> for FwReq { + fn class_init(class: &mut Class<Self>) { + Self::parent_class_init::<T>(class); + + let klass = class.as_mut(); + klass.responded = Some(fw_req_responded::<T>); + } +} + +unsafe extern "C" fn fw_req_responded<T: FwReqImpl>( + ptr: *mut ffi::HinawaFwReq, + rcode: ffi::HinawaFwRcode, + frame: *const u8, + length: c_uint, +) { + let instance = &*(ptr as *mut T::Instance); + let imp = instance.imp(); + let wrap: Borrowed<FwReq> = from_glib_borrow(ptr); + + imp.responded( + &wrap, + from_glib(rcode), + std::slice::from_raw_parts(frame, length as usize), + ) +} diff --git a/hinawa/src/subclass/fw_resp.rs b/hinawa/src/subclass/fw_resp.rs new file mode 100644 index 0000000..8e003a9 --- /dev/null +++ b/hinawa/src/subclass/fw_resp.rs @@ -0,0 +1,131 @@ +// SPDX-License-Identifier: MIT + +use super::*; + +pub trait FwRespImpl: ObjectImpl + FwRespImplExt { + fn requested(&self, resp: &FwResp, tcode: FwTcode) -> FwRcode { + self.parent_requested(resp, tcode) + } + + fn requested2( + &self, + resp: &FwResp, + tcode: FwTcode, + offset: u64, + src: u32, + dst: u32, + card: u32, + generation: u32, + frame: &[u8], + ) -> FwRcode { + self.parent_requested2(resp, tcode, offset, src, dst, card, generation, frame) + } +} + +pub trait FwRespImplExt: ObjectSubclass { + fn parent_requested(&self, resp: &FwResp, tcode: FwTcode) -> FwRcode; + fn parent_requested2( + &self, + resp: &FwResp, + tcode: FwTcode, + offset: u64, + src: u32, + dst: u32, + card: u32, + generation: u32, + frame: &[u8], + ) -> FwRcode; +} + +impl<T: FwRespImpl> FwRespImplExt for T { + fn parent_requested(&self, resp: &FwResp, tcode: FwTcode) -> FwRcode { + unsafe { + let data = T::type_data(); + let parent_class = data.as_ref().parent_class() as *mut ffi::HinawaFwRespClass; + let f = (*parent_class) + .requested + .expect("No parent class implementation for \"requested\""); + from_glib(f(resp.to_glib_none().0, tcode.into_glib())) + } + } + + fn parent_requested2( + &self, + resp: &FwResp, + tcode: FwTcode, + offset: u64, + src: u32, + dst: u32, + card: u32, + generation: u32, + frame: &[u8], + ) -> FwRcode { + unsafe { + let data = T::type_data(); + let parent_class = data.as_ref().parent_class() as *mut ffi::HinawaFwRespClass; + let f = (*parent_class) + .requested2 + .expect("No parent class implementation for \"requested\""); + from_glib(f( + resp.to_glib_none().0, + tcode.into_glib(), + offset, + src, + dst, + card, + generation, + frame.as_ptr(), + frame.len() as u32, + )) + } + } +} + +unsafe impl<T: FwRespImpl> IsSubclassable<T> for FwResp { + fn class_init(class: &mut Class<Self>) { + Self::parent_class_init::<T>(class); + + let klass = class.as_mut(); + klass.requested = Some(fw_resp_requested::<T>); + klass.requested2 = Some(fw_resp_requested2::<T>); + } +} + +unsafe extern "C" fn fw_resp_requested<T: FwRespImpl>( + ptr: *mut ffi::HinawaFwResp, + tcode: ffi::HinawaFwTcode, +) -> ffi::HinawaFwRcode { + let instance = &*(ptr as *mut T::Instance); + let imp = instance.imp(); + let wrap: Borrowed<FwResp> = from_glib_borrow(ptr); + + imp.requested(&wrap, from_glib(tcode)).into_glib() +} + +unsafe extern "C" fn fw_resp_requested2<T: FwRespImpl>( + ptr: *mut ffi::HinawaFwResp, + tcode: ffi::HinawaFwTcode, + offset: u64, + src: u32, + dst: u32, + card: u32, + generation: u32, + frame: *const u8, + length: c_uint, +) -> ffi::HinawaFwRcode { + let instance = &*(ptr as *mut T::Instance); + let imp = instance.imp(); + let wrap: Borrowed<FwResp> = from_glib_borrow(ptr); + + imp.requested2( + &wrap, + from_glib(tcode), + offset, + src, + dst, + card, + generation, + std::slice::from_raw_parts(frame, length as usize), + ) + .into_glib() +} diff --git a/hinawa/src/subclass/mod.rs b/hinawa/src/subclass/mod.rs new file mode 100644 index 0000000..e8477a5 --- /dev/null +++ b/hinawa/src/subclass/mod.rs @@ -0,0 +1,22 @@ +// SPDX-License-Identifier: MIT + +pub mod fw_fcp; +pub mod fw_node; +pub mod fw_req; +pub mod fw_resp; + +pub mod prelude { + pub use { + super::fw_fcp::{FwFcpImpl, FwFcpImplExt}, + super::fw_node::{FwNodeImpl, FwNodeImplExt}, + super::fw_req::{FwReqImpl, FwReqImplExt}, + super::fw_resp::{FwRespImpl, FwRespImplExt}, + }; +} + +use { + self::prelude::*, + super::*, + glib::{subclass::prelude::*, translate::*, Class}, + libc::*, +}; |