use crate::q_meta_object::Connection;
use crate::QObject;
use cpp_utils::{CastInto, CppBox, CppDeletable, MutPtr, MutRef, Ptr, Ref};
use std::ffi::CStr;
use std::fmt;
use std::marker::PhantomData;
pub trait ArgumentsCompatible<T> {}
pub struct Receiver<Arguments> {
q_object: Ref<QObject>,
receiver_id: &'static CStr,
_marker: PhantomData<Arguments>,
}
impl<A> Clone for Receiver<A> {
fn clone(&self) -> Self {
Receiver {
q_object: self.q_object,
receiver_id: self.receiver_id,
_marker: PhantomData,
}
}
}
impl<A> Copy for Receiver<A> {}
impl<A> fmt::Debug for Receiver<A> {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
fmt.debug_struct("Receiver")
.field("qobject", &self.q_object)
.field("receiver_id", &self.receiver_id)
.finish()
}
}
impl<A> Receiver<A> {
pub unsafe fn new(q_object: impl CastInto<Ref<QObject>>, receiver_id: &'static CStr) -> Self {
Self {
q_object: q_object.cast_into(),
receiver_id,
_marker: PhantomData,
}
}
}
pub struct Signal<Arguments>(Receiver<Arguments>);
impl<A> Clone for Signal<A> {
fn clone(&self) -> Self {
Signal(self.0)
}
}
impl<A> Copy for Signal<A> {}
impl<A> fmt::Debug for Signal<A> {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
fmt.debug_struct("Signal")
.field("qobject", &self.0.q_object)
.field("receiver_id", &self.0.receiver_id)
.finish()
}
}
impl<A> Signal<A> {
pub unsafe fn new(q_object: impl CastInto<Ref<QObject>>, receiver_id: &'static CStr) -> Self {
Signal(Receiver::new(q_object, receiver_id))
}
}
pub trait AsReceiver {
type Arguments;
fn as_receiver(&self) -> Receiver<Self::Arguments>;
}
impl<A> AsReceiver for Receiver<A> {
type Arguments = A;
fn as_receiver(&self) -> Receiver<A> {
*self
}
}
impl<A> AsReceiver for Signal<A> {
type Arguments = A;
fn as_receiver(&self) -> Receiver<A> {
self.0
}
}
impl<T> AsReceiver for MutPtr<T>
where
T: AsReceiver,
{
type Arguments = <T as AsReceiver>::Arguments;
fn as_receiver(&self) -> Receiver<Self::Arguments> {
(**self).as_receiver()
}
}
impl<T> AsReceiver for Ptr<T>
where
T: AsReceiver,
{
type Arguments = <T as AsReceiver>::Arguments;
fn as_receiver(&self) -> Receiver<Self::Arguments> {
(**self).as_receiver()
}
}
impl<T> AsReceiver for MutRef<T>
where
T: AsReceiver,
{
type Arguments = <T as AsReceiver>::Arguments;
fn as_receiver(&self) -> Receiver<Self::Arguments> {
(**self).as_receiver()
}
}
impl<T> AsReceiver for Ref<T>
where
T: AsReceiver,
{
type Arguments = <T as AsReceiver>::Arguments;
fn as_receiver(&self) -> Receiver<Self::Arguments> {
(**self).as_receiver()
}
}
impl<'a, T: CppDeletable> AsReceiver for &'a CppBox<T>
where
T: AsReceiver,
{
type Arguments = <T as AsReceiver>::Arguments;
fn as_receiver(&self) -> Receiver<Self::Arguments> {
(***self).as_receiver()
}
}
impl<SignalArguments> Signal<SignalArguments> {
pub unsafe fn connect<R>(&self, receiver: R) -> CppBox<Connection>
where
R: AsReceiver,
SignalArguments: ArgumentsCompatible<R::Arguments>,
{
let receiver = receiver.as_receiver();
crate::QObject::connect_4a(
self.0.q_object.as_ptr(),
Ptr::from_raw(self.0.receiver_id.as_ptr()),
receiver.q_object.as_ptr(),
Ptr::from_raw(receiver.receiver_id.as_ptr()),
)
}
}