Skip to content

Commit

Permalink
fw_node/fw_req/fw_resp/fw_fcp: support subclass
Browse files Browse the repository at this point in the history
The glib crate enables users to implement subclass of existent object
class. It requires some helper implementations.

Signed-off-by: Takashi Sakamoto <[email protected]>
  • Loading branch information
takaswie committed May 2, 2022
1 parent abb0fe2 commit 510967a
Show file tree
Hide file tree
Showing 11 changed files with 333 additions and 6 deletions.
4 changes: 2 additions & 2 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
hinawa Rust bindings
====================

2021/11/17
2022/05/02
Takashi Sakamoto

Introduction
Expand All @@ -22,7 +22,7 @@ MIT License
Sample code
===========

Read 1 quadlet from address ``0xfffff0000404`` on the node represented as ``/dev/fw0`` ::
Read 1 quadlet from address ``0xfffff0000404`` on the node expressed as ``/dev/fw0`` ::

extern crate hinawa;
extern crate glib;
Expand Down
2 changes: 1 addition & 1 deletion gir
Submodule gir updated 143 files
2 changes: 1 addition & 1 deletion gir-files
2 changes: 1 addition & 1 deletion hinawa-sys/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "hinawa-sys"
version = "0.5.0"
version = "0.5.1"
description = "FFI bindings for libhinawa2 library"
authors = ["Takashi Sakamoto <[email protected]>"]
links = "hinawa"
Expand Down
2 changes: 1 addition & 1 deletion hinawa/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "hinawa"
version = "0.5.0"
version = "0.5.1"
description = "API bindings for libhinawa2 library"
authors = ["Takashi Sakamoto <[email protected]>"]
license = "MIT"
Expand Down
2 changes: 2 additions & 0 deletions hinawa/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,5 @@ pub use snd_motu::*;

mod snd_motu_register_dsp_parameter;
pub use snd_motu_register_dsp_parameter::*;

pub mod subclass;
49 changes: 49 additions & 0 deletions hinawa/src/subclass/fw_fcp.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
// SPDX-License-Identifier: MIT

use super::*;

pub trait FwFcpImpl: ObjectImpl + 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().get_parent_class() as *mut hinawa_sys::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 FwFcpClass {
fn override_vfuncs(&mut self) {
<glib::ObjectClass as IsSubclassable<T>>::override_vfuncs(self);
unsafe {
let klass = &mut *(self as *mut Self as *mut hinawa_sys::HinawaFwFcpClass);
klass.responded = Some(fw_fcp_responded::<T>);
}
}
}

unsafe extern "C" fn fw_fcp_responded<T: FwFcpImpl>(
ptr: *mut hinawa_sys::HinawaFwFcp,
frame: *const u8,
length: c_uint,
) {
let instance = &*(ptr as *mut T::Instance);
let imp = instance.get_impl();
let wrap: Borrowed<FwFcp> = from_glib_borrow(ptr);

imp.responded(&wrap, std::slice::from_raw_parts(frame, length as usize))
}
71 changes: 71 additions & 0 deletions hinawa/src/subclass/fw_node.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
// 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().get_parent_class() as *mut hinawa_sys::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().get_parent_class() as *mut hinawa_sys::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 FwNodeClass {
fn override_vfuncs(&mut self) {
<glib::ObjectClass as IsSubclassable<T>>::override_vfuncs(self);
unsafe {
let klass = &mut *(self as *mut Self as *mut hinawa_sys::HinawaFwNodeClass);
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 hinawa_sys::HinawaFwNode) {
let instance = &*(ptr as *mut T::Instance);
let imp = instance.get_impl();
let wrap: Borrowed<FwNode> = from_glib_borrow(ptr);

imp.bus_update(&wrap)
}

unsafe extern "C" fn fw_node_disconnected<T: FwNodeImpl>(ptr: *mut hinawa_sys::HinawaFwNode) {
let instance = &*(ptr as *mut T::Instance);
let imp = instance.get_impl();
let wrap: Borrowed<FwNode> = from_glib_borrow(ptr);

imp.disconnected(&wrap)
}
59 changes: 59 additions & 0 deletions hinawa/src/subclass/fw_req.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
// 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().get_parent_class() as *mut hinawa_sys::HinawaFwReqClass;
let f = (*parent_class)
.responded
.expect("No parent class implementation for \"responded\"");
f(
req.to_glib_none().0,
rcode.to_glib(),
frame.as_ptr(),
frame.len() as u32,
)
}
}
}

unsafe impl<T: FwReqImpl> IsSubclassable<T> for FwReqClass {
fn override_vfuncs(&mut self) {
<glib::ObjectClass as IsSubclassable<T>>::override_vfuncs(self);
unsafe {
let klass = &mut *(self as *mut Self as *mut hinawa_sys::HinawaFwReqClass);
klass.responded = Some(fw_req_responded::<T>);
}
}
}

unsafe extern "C" fn fw_req_responded<T: FwReqImpl>(
ptr: *mut hinawa_sys::HinawaFwReq,
rcode: hinawa_sys::HinawaFwRcode,
frame: *const u8,
length: c_uint,
) {
let instance = &*(ptr as *mut T::Instance);
let imp = instance.get_impl();
let wrap: Borrowed<FwReq> = from_glib_borrow(ptr);

imp.responded(
&wrap,
from_glib(rcode),
std::slice::from_raw_parts(frame, length as usize),
)
}
134 changes: 134 additions & 0 deletions hinawa/src/subclass/fw_resp.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
// 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().get_parent_class() as *mut hinawa_sys::HinawaFwRespClass;
let f = (*parent_class)
.requested
.expect("No parent class implementation for \"requested\"");
from_glib(f(resp.to_glib_none().0, tcode.to_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().get_parent_class() as *mut hinawa_sys::HinawaFwRespClass;
let f = (*parent_class)
.requested2
.expect("No parent class implementation for \"requested\"");
from_glib(f(
resp.to_glib_none().0,
tcode.to_glib(),
offset,
src,
dst,
card,
generation,
frame.as_ptr(),
frame.len() as u32,
))
}
}
}

unsafe impl<T: FwRespImpl> IsSubclassable<T> for FwRespClass {
fn override_vfuncs(&mut self) {
<glib::ObjectClass as IsSubclassable<T>>::override_vfuncs(self);
unsafe {
let klass = &mut *(self as *mut Self as *mut hinawa_sys::HinawaFwRespClass);
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 hinawa_sys::HinawaFwResp,
tcode: hinawa_sys::HinawaFwTcode,
) -> hinawa_sys::HinawaFwRcode {
let instance = &*(ptr as *mut T::Instance);
let imp = instance.get_impl();
let wrap: Borrowed<FwResp> = from_glib_borrow(ptr);

imp.requested(&wrap, from_glib(tcode)).to_glib()
}

unsafe extern "C" fn fw_resp_requested2<T: FwRespImpl>(
ptr: *mut hinawa_sys::HinawaFwResp,
tcode: hinawa_sys::HinawaFwTcode,
offset: u64,
src: u32,
dst: u32,
card: u32,
generation: u32,
frame: *const u8,
length: c_uint,
) -> hinawa_sys::HinawaFwRcode {
let instance = &*(ptr as *mut T::Instance);
let imp = instance.get_impl();
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),
)
.to_glib()
}
12 changes: 12 additions & 0 deletions hinawa/src/subclass/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// SPDX-License-Identifier: MIT

pub mod fw_fcp;
pub mod fw_node;
pub mod fw_req;
pub mod fw_resp;

use {
super::*,
glib::{subclass::prelude::*, translate::*},
libc::*,
};

0 comments on commit 510967a

Please sign in to comment.