Struct gstreamer_video::VideoOverlay [−][src]
pub struct VideoOverlay(_);
The crate::VideoOverlay
interface is used for 2 main purposes :
- To get a grab on the Window where the video sink element is going to render. This is achieved by either being informed about the Window identifier that the video sink element generated, or by forcing the video sink element to use a specific Window identifier for rendering.
- To force a redrawing of the latest video frame the video sink element
displayed on the Window. Indeed if the
crate::gst::Pipeline
is incrate::gst::State::Paused
state, moving the Window around will damage its content. Application developers will want to handle the Expose events themselves and force the video sink element to refresh the Window’s content.
Using the Window created by the video sink is probably the simplest scenario, in some cases, though, it might not be flexible enough for application developers if they need to catch events such as mouse moves and button clicks.
Setting a specific Window identifier on the video sink element is the most
flexible solution but it has some issues. Indeed the application needs to set
its Window identifier at the right time to avoid internal Window creation
from the video sink element. To solve this issue a crate::gst::Message
is posted on
the bus to inform the application that it should set the Window identifier
immediately. Here is an example on how to do that correctly:
static GstBusSyncReply
create_window (GstBus * bus, GstMessage * message, GstPipeline * pipeline)
{
// ignore anything but 'prepare-window-handle' element messages
if (!gst_is_video_overlay_prepare_window_handle_message (message))
return GST_BUS_PASS;
win = XCreateSimpleWindow (disp, root, 0, 0, 320, 240, 0, 0, 0);
XSetWindowBackgroundPixmap (disp, win, None);
XMapRaised (disp, win);
XSync (disp, FALSE);
gst_video_overlay_set_window_handle (GST_VIDEO_OVERLAY (GST_MESSAGE_SRC (message)),
win);
gst_message_unref (message);
return GST_BUS_DROP;
}
...
int
main (int argc, char **argv)
{
...
bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
gst_bus_set_sync_handler (bus, (GstBusSyncHandler) create_window, pipeline,
NULL);
...
}
Two basic usage scenarios
There are two basic usage scenarios: in the simplest case, the application
uses playbin
or playsink
or knows exactly what particular element is used
for video output, which is usually the case when the application creates
the videosink to use (e.g. xvimagesink
, ximagesink
, etc.) itself; in this
case, the application can just create the videosink element, create and
realize the window to render the video on and then
call [Self::set_window_handle()
] directly with the XID or native
window handle, before starting up the pipeline.
As playbin
and playsink
implement the video overlay interface and proxy
it transparently to the actual video sink even if it is created later, this
case also applies when using these elements.
In the other and more common case, the application does not know in advance
what GStreamer video sink element will be used for video output. This is
usually the case when an element such as autovideosink
is used.
In this case, the video sink element itself is created
asynchronously from a GStreamer streaming thread some time after the
pipeline has been started up. When that happens, however, the video sink
will need to know right then whether to render onto an already existing
application window or whether to create its own window. This is when it
posts a prepare-window-handle message, and that is also why this message needs
to be handled in a sync bus handler which will be called from the streaming
thread directly (because the video sink will need an answer right then).
As response to the prepare-window-handle element message in the bus sync
handler, the application may use [Self::set_window_handle()
] to tell
the video sink to render onto an existing window surface. At this point the
application should already have obtained the window handle / XID, so it
just needs to set it. It is generally not advisable to call any GUI toolkit
functions or window system functions from the streaming thread in which the
prepare-window-handle message is handled, because most GUI toolkits and
windowing systems are not thread-safe at all and a lot of care would be
required to co-ordinate the toolkit and window system calls of the
different threads (Gtk+ users please note: prior to Gtk+ 2.18
GDK_WINDOW_XID
was just a simple structure access, so generally fine to do
within the bus sync handler; this macro was changed to a function call in
Gtk+ 2.18 and later, which is likely to cause problems when called from a
sync handler; see below for a better approach without GDK_WINDOW_XID
used in the callback).
GstVideoOverlay and Gtk+
#include <gst/video/videooverlay.h>
#include <gtk/gtk.h>
#ifdef GDK_WINDOWING_X11
#include <gdk/gdkx.h> // for GDK_WINDOW_XID
#endif
#ifdef GDK_WINDOWING_WIN32
#include <gdk/gdkwin32.h> // for GDK_WINDOW_HWND
#endif
...
static guintptr video_window_handle = 0;
...
static GstBusSyncReply
bus_sync_handler (GstBus * bus, GstMessage * message, gpointer user_data)
{
// ignore anything but 'prepare-window-handle' element messages
if (!gst_is_video_overlay_prepare_window_handle_message (message))
return GST_BUS_PASS;
if (video_window_handle != 0) {
GstVideoOverlay *overlay;
// GST_MESSAGE_SRC (message) will be the video sink element
overlay = GST_VIDEO_OVERLAY (GST_MESSAGE_SRC (message));
gst_video_overlay_set_window_handle (overlay, video_window_handle);
} else {
g_warning ("Should have obtained video_window_handle by now!");
}
gst_message_unref (message);
return GST_BUS_DROP;
}
...
static void
video_widget_realize_cb (GtkWidget * widget, gpointer data)
{
#if GTK_CHECK_VERSION(2,18,0)
// Tell Gtk+/Gdk to create a native window for this widget instead of
// drawing onto the parent widget.
// This is here just for pedagogical purposes, GDK_WINDOW_XID will call
// it as well in newer Gtk versions
if (!gdk_window_ensure_native (widget->window))
g_error ("Couldn't create native window needed for GstVideoOverlay!");
#endif
#ifdef GDK_WINDOWING_X11
{
gulong xid = GDK_WINDOW_XID (gtk_widget_get_window (video_window));
video_window_handle = xid;
}
#endif
#ifdef GDK_WINDOWING_WIN32
{
HWND wnd = GDK_WINDOW_HWND (gtk_widget_get_window (video_window));
video_window_handle = (guintptr) wnd;
}
#endif
}
...
int
main (int argc, char **argv)
{
GtkWidget *video_window;
GtkWidget *app_window;
...
app_window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
...
video_window = gtk_drawing_area_new ();
g_signal_connect (video_window, "realize",
G_CALLBACK (video_widget_realize_cb), NULL);
gtk_widget_set_double_buffered (video_window, FALSE);
...
// usually the video_window will not be directly embedded into the
// application window like this, but there will be many other widgets
// and the video window will be embedded in one of them instead
gtk_container_add (GTK_CONTAINER (ap_window), video_window);
...
// show the GUI
gtk_widget_show_all (app_window);
// realize window now so that the video window gets created and we can
// obtain its XID/HWND before the pipeline is started up and the videosink
// asks for the XID/HWND of the window to render onto
gtk_widget_realize (video_window);
// we should have the XID/HWND now
g_assert (video_window_handle != 0);
...
// set up sync handler for setting the xid once the pipeline is started
bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
gst_bus_set_sync_handler (bus, (GstBusSyncHandler) bus_sync_handler, NULL,
NULL);
gst_object_unref (bus);
...
gst_element_set_state (pipeline, GST_STATE_PLAYING);
...
}
GstVideoOverlay and Qt
#include <glib.h>;
#include <gst/gst.h>;
#include <gst/video/videooverlay.h>;
#include <QApplication>;
#include <QTimer>;
#include <QWidget>;
int main(int argc, char *argv[])
{
if (!g_thread_supported ())
g_thread_init (NULL);
gst_init (&argc, &argv);
QApplication app(argc, argv);
app.connect(&app, SIGNAL(lastWindowClosed()), &app, SLOT(quit ()));
// prepare the pipeline
GstElement *pipeline = gst_pipeline_new ("xvoverlay");
GstElement *src = gst_element_factory_make ("videotestsrc", NULL);
GstElement *sink = gst_element_factory_make ("xvimagesink", NULL);
gst_bin_add_many (GST_BIN (pipeline), src, sink, NULL);
gst_element_link (src, sink);
// prepare the ui
QWidget window;
window.resize(320, 240);
window.show();
WId xwinid = window.winId();
gst_video_overlay_set_window_handle (GST_VIDEO_OVERLAY (sink), xwinid);
// run the pipeline
GstStateChangeReturn sret = gst_element_set_state (pipeline,
GST_STATE_PLAYING);
if (sret == GST_STATE_CHANGE_FAILURE) {
gst_element_set_state (pipeline, GST_STATE_NULL);
gst_object_unref (pipeline);
// Exit application
QTimer::singleShot(0, QApplication::activeWindow(), SLOT(quit()));
}
int ret = app.exec();
window.hide();
gst_element_set_state (pipeline, GST_STATE_NULL);
gst_object_unref (pipeline);
return ret;
}
Implements
crate::prelude::VideoOverlayExt
, crate::prelude::VideoOverlayExtManual
Trait Implementations
impl Clone for VideoOverlay
[src]
impl Clone for VideoOverlay
[src]fn clone(&self) -> VideoOverlay
[src]
fn clone(&self) -> VideoOverlay
[src]Returns a copy of the value. Read more
fn clone_from(&mut self, source: &Self)
1.0.0[src]
fn clone_from(&mut self, source: &Self)
1.0.0[src]Performs copy-assignment from source
. Read more
impl Debug for VideoOverlay
[src]
impl Debug for VideoOverlay
[src]impl Hash for VideoOverlay
[src]
impl Hash for VideoOverlay
[src]impl Ord for VideoOverlay
[src]
impl Ord for VideoOverlay
[src]impl<T: ObjectType> PartialEq<T> for VideoOverlay
[src]
impl<T: ObjectType> PartialEq<T> for VideoOverlay
[src]impl<T: ObjectType> PartialOrd<T> for VideoOverlay
[src]
impl<T: ObjectType> PartialOrd<T> for VideoOverlay
[src]fn partial_cmp(&self, other: &T) -> Option<Ordering>
[src]
fn partial_cmp(&self, other: &T) -> Option<Ordering>
[src]This method returns an ordering between self
and other
values if one exists. Read more
#[must_use]fn lt(&self, other: &Rhs) -> bool
1.0.0[src]
#[must_use]fn lt(&self, other: &Rhs) -> bool
1.0.0[src]This method tests less than (for self
and other
) and is used by the <
operator. Read more
#[must_use]fn le(&self, other: &Rhs) -> bool
1.0.0[src]
#[must_use]fn le(&self, other: &Rhs) -> bool
1.0.0[src]This method tests less than or equal to (for self
and other
) and is used by the <=
operator. Read more
impl StaticType for VideoOverlay
[src]
impl StaticType for VideoOverlay
[src]fn static_type() -> Type
[src]
fn static_type() -> Type
[src]Returns the type identifier of Self
.
impl Eq for VideoOverlay
[src]
impl Send for VideoOverlay
[src]
impl StructuralEq for VideoOverlay
[src]
impl Sync for VideoOverlay
[src]
Auto Trait Implementations
Blanket Implementations
impl<T> BorrowMut<T> for T where
T: ?Sized,
[src]
impl<T> BorrowMut<T> for T where
T: ?Sized,
[src]pub fn borrow_mut(&mut self) -> &mut T
[src]
pub fn borrow_mut(&mut self) -> &mut T
[src]Mutably borrows from an owned value. Read more
impl<T> Cast for T where
T: ObjectType,
[src]
impl<T> Cast for T where
T: ObjectType,
[src]fn upcast<T>(self) -> T where
Self: IsA<T>,
T: ObjectType,
[src]
fn upcast<T>(self) -> T where
Self: IsA<T>,
T: ObjectType,
[src]Upcasts an object to a superclass or interface T
. Read more
fn upcast_ref<T>(&self) -> &T where
Self: IsA<T>,
T: ObjectType,
[src]
fn upcast_ref<T>(&self) -> &T where
Self: IsA<T>,
T: ObjectType,
[src]Upcasts an object to a reference of its superclass or interface T
. Read more
fn downcast<T>(self) -> Result<T, Self> where
Self: CanDowncast<T>,
T: ObjectType,
[src]
fn downcast<T>(self) -> Result<T, Self> where
Self: CanDowncast<T>,
T: ObjectType,
[src]Tries to downcast to a subclass or interface implementor T
. Read more
fn downcast_ref<T>(&self) -> Option<&T> where
Self: CanDowncast<T>,
T: ObjectType,
[src]
fn downcast_ref<T>(&self) -> Option<&T> where
Self: CanDowncast<T>,
T: ObjectType,
[src]Tries to downcast to a reference of its subclass or interface implementor T
. Read more
fn dynamic_cast<T>(self) -> Result<T, Self> where
T: ObjectType,
[src]
fn dynamic_cast<T>(self) -> Result<T, Self> where
T: ObjectType,
[src]Tries to cast to an object of type T
. This handles upcasting, downcasting
and casting between interface and interface implementors. All checks are performed at
runtime, while downcast
and upcast
will do many checks at compile-time already. Read more
fn dynamic_cast_ref<T>(&self) -> Option<&T> where
T: ObjectType,
[src]
fn dynamic_cast_ref<T>(&self) -> Option<&T> where
T: ObjectType,
[src]Tries to cast to reference to an object of type T
. This handles upcasting, downcasting
and casting between interface and interface implementors. All checks are performed at
runtime, while downcast
and upcast
will do many checks at compile-time already. Read more
unsafe fn unsafe_cast<T>(self) -> T where
T: ObjectType,
[src]
unsafe fn unsafe_cast<T>(self) -> T where
T: ObjectType,
[src]Casts to T
unconditionally. Read more
unsafe fn unsafe_cast_ref<T>(&self) -> &T where
T: ObjectType,
[src]
unsafe fn unsafe_cast_ref<T>(&self) -> &T where
T: ObjectType,
[src]Casts to &T
unconditionally. Read more
impl<O> GObjectExtManualGst for O where
O: IsA<Object>,
[src]
impl<O> GObjectExtManualGst for O where
O: IsA<Object>,
[src]pub fn set_property_from_str(&self, name: &str, value: &str)
[src]
impl<T> ObjectExt for T where
T: ObjectType,
[src]
impl<T> ObjectExt for T where
T: ObjectType,
[src]pub fn is<U>(&self) -> bool where
U: StaticType,
[src]
pub fn is<U>(&self) -> bool where
U: StaticType,
[src]Returns true
if the object is an instance of (can be cast to) T
.
pub fn type_(&self) -> Type
[src]
pub fn object_class(&self) -> &Class<Object>
[src]
pub fn class(&self) -> &Class<T> where
T: IsClass,
[src]
T: IsClass,
pub fn class_of<U>(&self) -> Option<&Class<U>> where
U: IsClass,
[src]
U: IsClass,
pub fn interface<U>(&self) -> Option<InterfaceRef<'_, U>> where
U: IsInterface,
[src]
U: IsInterface,
pub fn set_properties(
&self,
property_values: &[(&str, &dyn ToValue)]
) -> Result<(), BoolError>
[src]
&self,
property_values: &[(&str, &dyn ToValue)]
) -> Result<(), BoolError>
pub fn set_properties_from_value(
&self,
property_values: &[(&str, Value)]
) -> Result<(), BoolError>
[src]
&self,
property_values: &[(&str, Value)]
) -> Result<(), BoolError>
pub fn set_property<'a, N, V>(
&self,
property_name: N,
value: V
) -> Result<(), BoolError> where
V: ToValue,
N: Into<&'a str>,
[src]
&self,
property_name: N,
value: V
) -> Result<(), BoolError> where
V: ToValue,
N: Into<&'a str>,
pub fn set_property_from_value<'a, N>(
&self,
property_name: N,
value: &Value
) -> Result<(), BoolError> where
N: Into<&'a str>,
[src]
&self,
property_name: N,
value: &Value
) -> Result<(), BoolError> where
N: Into<&'a str>,
pub fn property<'a, N>(&self, property_name: N) -> Result<Value, BoolError> where
N: Into<&'a str>,
[src]
N: Into<&'a str>,
pub unsafe fn qdata<QD>(&self, key: Quark) -> Option<NonNull<QD>> where
QD: 'static,
[src]
pub unsafe fn qdata<QD>(&self, key: Quark) -> Option<NonNull<QD>> where
QD: 'static,
[src]Safety Read more
pub unsafe fn steal_qdata<QD>(&self, key: Quark) -> Option<QD> where
QD: 'static,
[src]
pub unsafe fn steal_qdata<QD>(&self, key: Quark) -> Option<QD> where
QD: 'static,
[src]Safety Read more
pub unsafe fn data<QD>(&self, key: &str) -> Option<NonNull<QD>> where
QD: 'static,
[src]
pub unsafe fn data<QD>(&self, key: &str) -> Option<NonNull<QD>> where
QD: 'static,
[src]Safety Read more
pub unsafe fn steal_data<QD>(&self, key: &str) -> Option<QD> where
QD: 'static,
[src]
pub unsafe fn steal_data<QD>(&self, key: &str) -> Option<QD> where
QD: 'static,
[src]Safety Read more
pub fn block_signal(&self, handler_id: &SignalHandlerId)
[src]
pub fn unblock_signal(&self, handler_id: &SignalHandlerId)
[src]
pub fn stop_signal_emission(&self, signal_name: &str)
[src]
pub fn disconnect(&self, handler_id: SignalHandlerId)
[src]
pub fn connect_notify<F>(&self, name: Option<&str>, f: F) -> SignalHandlerId where
F: 'static + Fn(&T, &ParamSpec) + Send + Sync,
[src]
F: 'static + Fn(&T, &ParamSpec) + Send + Sync,
pub fn connect_notify_local<F>(
&self,
name: Option<&str>,
f: F
) -> SignalHandlerId where
F: 'static + Fn(&T, &ParamSpec),
[src]
&self,
name: Option<&str>,
f: F
) -> SignalHandlerId where
F: 'static + Fn(&T, &ParamSpec),
pub unsafe fn connect_notify_unsafe<F>(
&self,
name: Option<&str>,
f: F
) -> SignalHandlerId where
F: Fn(&T, &ParamSpec),
[src]
&self,
name: Option<&str>,
f: F
) -> SignalHandlerId where
F: Fn(&T, &ParamSpec),
pub fn notify<'a, N>(&self, property_name: N) where
N: Into<&'a str>,
[src]
N: Into<&'a str>,
pub fn notify_by_pspec(&self, pspec: &ParamSpec)
[src]
pub fn has_property<'a, N>(&self, property_name: N, type_: Option<Type>) -> bool where
N: Into<&'a str>,
[src]
N: Into<&'a str>,
pub fn property_type<'a, N>(&self, property_name: N) -> Option<Type> where
N: Into<&'a str>,
[src]
N: Into<&'a str>,
pub fn find_property<'a, N>(&self, property_name: N) -> Option<ParamSpec> where
N: Into<&'a str>,
[src]
N: Into<&'a str>,
pub fn list_properties(&self) -> Vec<ParamSpec, Global>
[src]
pub fn connect<'a, N, F>(
&self,
signal_name: N,
after: bool,
callback: F
) -> Result<SignalHandlerId, BoolError> where
F: Fn(&[Value]) -> Option<Value> + Send + Sync + 'static,
N: Into<&'a str>,
[src]
&self,
signal_name: N,
after: bool,
callback: F
) -> Result<SignalHandlerId, BoolError> where
F: Fn(&[Value]) -> Option<Value> + Send + Sync + 'static,
N: Into<&'a str>,
pub fn connect_id<F>(
&self,
signal_id: SignalId,
details: Option<Quark>,
after: bool,
callback: F
) -> Result<SignalHandlerId, BoolError> where
F: Fn(&[Value]) -> Option<Value> + Send + Sync + 'static,
[src]
pub fn connect_id<F>(
&self,
signal_id: SignalId,
details: Option<Quark>,
after: bool,
callback: F
) -> Result<SignalHandlerId, BoolError> where
F: Fn(&[Value]) -> Option<Value> + Send + Sync + 'static,
[src]Same as connect
but takes a SignalId
instead of a signal name.
pub fn connect_local<'a, N, F>(
&self,
signal_name: N,
after: bool,
callback: F
) -> Result<SignalHandlerId, BoolError> where
F: Fn(&[Value]) -> Option<Value> + 'static,
N: Into<&'a str>,
[src]
&self,
signal_name: N,
after: bool,
callback: F
) -> Result<SignalHandlerId, BoolError> where
F: Fn(&[Value]) -> Option<Value> + 'static,
N: Into<&'a str>,
pub fn connect_local_id<F>(
&self,
signal_id: SignalId,
details: Option<Quark>,
after: bool,
callback: F
) -> Result<SignalHandlerId, BoolError> where
F: Fn(&[Value]) -> Option<Value> + 'static,
[src]
pub fn connect_local_id<F>(
&self,
signal_id: SignalId,
details: Option<Quark>,
after: bool,
callback: F
) -> Result<SignalHandlerId, BoolError> where
F: Fn(&[Value]) -> Option<Value> + 'static,
[src]Same as connect_local
but takes a SignalId
instead of a signal name.
pub unsafe fn connect_unsafe<'a, N, F>(
&self,
signal_name: N,
after: bool,
callback: F
) -> Result<SignalHandlerId, BoolError> where
F: Fn(&[Value]) -> Option<Value>,
N: Into<&'a str>,
[src]
&self,
signal_name: N,
after: bool,
callback: F
) -> Result<SignalHandlerId, BoolError> where
F: Fn(&[Value]) -> Option<Value>,
N: Into<&'a str>,
pub unsafe fn connect_unsafe_id<F>(
&self,
signal_id: SignalId,
details: Option<Quark>,
after: bool,
callback: F
) -> Result<SignalHandlerId, BoolError> where
F: Fn(&[Value]) -> Option<Value>,
[src]
pub unsafe fn connect_unsafe_id<F>(
&self,
signal_id: SignalId,
details: Option<Quark>,
after: bool,
callback: F
) -> Result<SignalHandlerId, BoolError> where
F: Fn(&[Value]) -> Option<Value>,
[src]Same as connect_unsafe
but takes a SignalId
instead of a signal name.
pub fn emit(
&self,
signal_id: SignalId,
args: &[&dyn ToValue]
) -> Result<Option<Value>, BoolError>
[src]
pub fn emit(
&self,
signal_id: SignalId,
args: &[&dyn ToValue]
) -> Result<Option<Value>, BoolError>
[src]Emit signal by signal id.
pub fn emit_with_details(
&self,
signal_id: SignalId,
details: Quark,
args: &[&dyn ToValue]
) -> Result<Option<Value>, BoolError>
[src]
pub fn emit_with_details(
&self,
signal_id: SignalId,
details: Quark,
args: &[&dyn ToValue]
) -> Result<Option<Value>, BoolError>
[src]Emit signal with details by signal id.
pub fn emit_by_name<'a, N>(
&self,
signal_name: N,
args: &[&dyn ToValue]
) -> Result<Option<Value>, BoolError> where
N: Into<&'a str>,
[src]
pub fn emit_by_name<'a, N>(
&self,
signal_name: N,
args: &[&dyn ToValue]
) -> Result<Option<Value>, BoolError> where
N: Into<&'a str>,
[src]Emit signal by it’s name.
pub fn downgrade(&self) -> WeakRef<T>
[src]
pub fn bind_property<'a, O, N, M>(
&'a self,
source_property: N,
target: &'a O,
target_property: M
) -> BindingBuilder<'a> where
O: ObjectType,
N: Into<&'a str>,
M: Into<&'a str>,
[src]
&'a self,
source_property: N,
target: &'a O,
target_property: M
) -> BindingBuilder<'a> where
O: ObjectType,
N: Into<&'a str>,
M: Into<&'a str>,
pub fn ref_count(&self) -> u32
[src]
pub fn emit_with_values(
&self,
signal_id: SignalId,
args: &[Value]
) -> Result<Option<Value>, BoolError>
[src]
pub fn emit_with_values(
&self,
signal_id: SignalId,
args: &[Value]
) -> Result<Option<Value>, BoolError>
[src]Same as emit
but takes Value
for the arguments.
impl<T> ToOwned for T where
T: Clone,
[src]
impl<T> ToOwned for T where
T: Clone,
[src]type Owned = T
type Owned = T
The resulting type after obtaining ownership.
pub fn to_owned(&self) -> T
[src]
pub fn to_owned(&self) -> T
[src]Creates owned data from borrowed data, usually by cloning. Read more
pub fn clone_into(&self, target: &mut T)
[src]
pub fn clone_into(&self, target: &mut T)
[src]🔬 This is a nightly-only experimental API. (toowned_clone_into
)
recently added
Uses borrowed data to replace owned data, usually by cloning. Read more
impl<T> ToSendValue for T where
T: Send + ToValue + ?Sized,
[src]
impl<T> ToSendValue for T where
T: Send + ToValue + ?Sized,
[src]pub fn to_send_value(&self) -> SendValue
[src]
pub fn to_send_value(&self) -> SendValue
[src]Returns a SendValue
clone of self
.
impl<Super, Sub> CanDowncast<Sub> for Super where
Sub: IsA<Super>,
Super: IsA<Super>,
[src]
Sub: IsA<Super>,
Super: IsA<Super>,
impl<'a, T, C> FromValueOptional<'a> for T where
C: ValueTypeChecker<Error = ValueTypeMismatchOrNoneError>,
T: FromValue<'a, Checker = C>,
[src]
C: ValueTypeChecker<Error = ValueTypeMismatchOrNoneError>,
T: FromValue<'a, Checker = C>,