aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTakashi Sakamoto <o-takashi@sakamocchi.jp>2022-05-06 17:52:13 +0900
committerTakashi Sakamoto <o-takashi@sakamocchi.jp>2022-05-06 17:53:06 +0900
commitdf4b3f2d577d4f0d54c64aa8724c6fb6697f43c5 (patch)
treed9d6d0cbe890985b01cf616baf45744cad30ff8f
parent1e5a789c75cc387eea9f7659dfdd31fbb043dca0 (diff)
downloadhinawa-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.rs2
-rw-r--r--hinawa/src/subclass/fw_fcp.rs47
-rw-r--r--hinawa/src/subclass/fw_node.rs68
-rw-r--r--hinawa/src/subclass/fw_req.rs57
-rw-r--r--hinawa/src/subclass/fw_resp.rs131
-rw-r--r--hinawa/src/subclass/mod.rs22
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::*,
+};