mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-01 03:52:25 +00:00
more tests and Dispose() in Gst.Object
git-svn-id: svn://anonsvn.mono-project.com/source/branches/abock/gstreamer-sharp@63657 e3ebcda4-bce8-0310-ba0a-eca2169e7518
This commit is contained in:
parent
8ad1c333e7
commit
13873a6559
10 changed files with 230 additions and 23 deletions
|
@ -1,3 +1,7 @@
|
||||||
|
2006-08-11 Khaled Mohammed <khaled.mohammed@gmail.com>
|
||||||
|
* gstreamer-sharp/Object.custom: overriden Dispose() function.
|
||||||
|
* gstreamer-sharp/tests: added more tests
|
||||||
|
|
||||||
2006-08-05 Khaled Mohammed <khaled.mohammed@gmail.com>
|
2006-08-05 Khaled Mohammed <khaled.mohammed@gmail.com>
|
||||||
* gstreamer-sharp/GStreamer.metadata: added a new xml node to hide
|
* gstreamer-sharp/GStreamer.metadata: added a new xml node to hide
|
||||||
generation of Refcount by GAPI.
|
generation of Refcount by GAPI.
|
||||||
|
|
|
@ -39,16 +39,12 @@
|
||||||
base.SetProperty(propertyName, new GLib.Value(value));
|
base.SetProperty(propertyName, new GLib.Value(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
[DllImport("gstreamer-0.10.dll")]
|
|
||||||
private static extern bool gst_element_query_position(IntPtr raw, ref Format format, out long cur);
|
|
||||||
|
|
||||||
public bool QueryPosition(Gst.Format format, out long current)
|
public bool QueryPosition(Gst.Format format, out long current)
|
||||||
{
|
{
|
||||||
return gst_element_query_position(Handle, ref format, out current);
|
return gst_element_query_position(Handle, ref format, out current);
|
||||||
}
|
}
|
||||||
|
|
||||||
[DllImport("gstreamer-0.10.dll")]
|
|
||||||
private static extern bool gst_element_query_duration(IntPtr raw, ref Format format, out long duration);
|
|
||||||
|
|
||||||
public bool QueryDuration(Gst.Format format, out long duration)
|
public bool QueryDuration(Gst.Format format, out long duration)
|
||||||
{
|
{
|
||||||
|
@ -64,3 +60,20 @@
|
||||||
{
|
{
|
||||||
GLib.DynamicSignal.Disconnect(this, signal, handler);
|
GLib.DynamicSignal.Disconnect(this, signal, handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool AddPad(Pad p)
|
||||||
|
{
|
||||||
|
bool ret = gst_element_add_pad(this.Handle, p == null ? IntPtr.Zero : p.Handle);
|
||||||
|
if(ret)
|
||||||
|
Gst.Object.Ref(p.Handle);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
[DllImport("gstreamer-0.10.dll")]
|
||||||
|
private static extern bool gst_element_query_position(IntPtr raw, ref Format format, out long cur);
|
||||||
|
|
||||||
|
[DllImport("gstreamer-0.10.dll")]
|
||||||
|
private static extern bool gst_element_query_duration(IntPtr raw, ref Format format, out long duration);
|
||||||
|
|
||||||
|
[DllImport("gstreamer-0.10.dll")]
|
||||||
|
static extern bool gst_element_add_pad(IntPtr raw, IntPtr pad);
|
||||||
|
|
|
@ -2,9 +2,13 @@
|
||||||
<metadata>
|
<metadata>
|
||||||
<attr path="/api/namespace/object[@name='Bin']" name="disable_gtype_ctor">1</attr>
|
<attr path="/api/namespace/object[@name='Bin']" name="disable_gtype_ctor">1</attr>
|
||||||
<attr path="/api/namespace/object[@name='Pipeline']" name="disable_gtype_ctor">1</attr>
|
<attr path="/api/namespace/object[@name='Pipeline']" name="disable_gtype_ctor">1</attr>
|
||||||
|
<attr path="/api/namespace/object[@cname='GstPipeline']/method[@name='GetBus']/return-type" name="owned">true</attr>
|
||||||
|
<attr path="/api/namespace/object[@name='ElementFactory']/method[@name='Make']/return-type" name="owned">true</attr>
|
||||||
|
<attr path="/api/namespace/boxed[@name='Caps']/method[@name='FromString']/return-type" name="owned">true</attr>
|
||||||
|
<attr path="/api/namespace/object[@name='Buffer']/method[@name='GetCaps']/return-type" name="owned">true</attr>
|
||||||
<attr path="/api/namespace/object[@name='Object']/field[@name='Refcount']" name="hidden">1</attr>
|
<attr path="/api/namespace/object[@name='Object']/field[@name='Refcount']" name="hidden">1</attr>
|
||||||
|
<attr path="/api/namespace/object[@name='Message']/method[@cname='gst_message_new_error']" name="hidden">1</attr>
|
||||||
|
<attr path="/api/namespace/object[@name='Element']/method[@cname='gst_element_add_pad']" name="hidden">1</attr>
|
||||||
<attr path="/api/namespace/object[@name='Bin']/field[@name='Children']" name="hidden">1</attr>
|
<attr path="/api/namespace/object[@name='Bin']/field[@name='Children']" name="hidden">1</attr>
|
||||||
|
|
||||||
<attr path="/api/namespace/object[@name='Bin']/method[@name='Add']" name="hidden">1</attr>
|
<attr path="/api/namespace/object[@name='Bin']/method[@name='Add']" name="hidden">1</attr>
|
||||||
|
|
|
@ -8,3 +8,11 @@
|
||||||
error = GLib.Marshaller.PtrToStringGFree(err);
|
error = GLib.Marshaller.PtrToStringGFree(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[DllImport("gstreamersharpglue-0.10")]
|
||||||
|
private extern static IntPtr gstsharp_message_error_new();
|
||||||
|
|
||||||
|
public Message(Gst.Object src, string debug)
|
||||||
|
{
|
||||||
|
IntPtr error = gstsharp_message_error_new();
|
||||||
|
Raw = gst_message_new_error(src == null ? IntPtr.Zero : src.Handle, error, GLib.Marshaller.StringToPtrGStrdup(debug));
|
||||||
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#include <glib/gerror.h>
|
#include <glib/gerror.h>
|
||||||
#include <gst/gstmessage.h>
|
#include <gst/gstmessage.h>
|
||||||
|
#include <glib/gquark.h>
|
||||||
|
|
||||||
gchar *
|
gchar *
|
||||||
gstsharp_message_parse_error(GstMessage *message)
|
gstsharp_message_parse_error(GstMessage *message)
|
||||||
|
@ -14,3 +15,10 @@ gstsharp_message_parse_error(GstMessage *message)
|
||||||
|
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GError *
|
||||||
|
gstsharp_message_error_new()
|
||||||
|
{
|
||||||
|
GQuark domain = g_quark_from_string ("test");
|
||||||
|
return g_error_new (domain, 10, "test error");
|
||||||
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
//
|
//
|
||||||
// Authors:
|
// Authors:
|
||||||
// Aaron Bockover (abockover@novell.com)
|
// Aaron Bockover (abockover@novell.com)
|
||||||
|
// Khaled Mohammed (Khaled.Mohammed@gmail.com)
|
||||||
//
|
//
|
||||||
// (C) 2006 Novell, Inc.
|
// (C) 2006 Novell, Inc.
|
||||||
//
|
//
|
||||||
|
@ -33,15 +34,21 @@ public class BinTest
|
||||||
Bin bin = new Bin("test-bin");
|
Bin bin = new Bin("test-bin");
|
||||||
Element e1 = ElementFactory.Make("fakesrc", "fakesrc");
|
Element e1 = ElementFactory.Make("fakesrc", "fakesrc");
|
||||||
Element e2 = ElementFactory.Make("fakesink", "fakesink");
|
Element e2 = ElementFactory.Make("fakesink", "fakesink");
|
||||||
|
|
||||||
|
Assert.IsNotNull(bin, "Could not create bin");
|
||||||
|
Assert.IsNotNull(e1, "Could not create fakesrc");
|
||||||
|
Assert.IsNotNull(e2, "Could not create fakesink");
|
||||||
|
|
||||||
bin.AddMany(e1, e2);
|
bin.AddMany(e1, e2);
|
||||||
|
|
||||||
Assert.AreEqual(bin.ChildrenCount, 2);
|
Assert.AreEqual(bin.ChildrenCount, 2);
|
||||||
|
|
||||||
e1.Dispose();
|
|
||||||
e2.Dispose();
|
e2.Dispose();
|
||||||
|
e1.Dispose();
|
||||||
bin.Dispose();
|
bin.Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
[Test]
|
[Test]
|
||||||
public void TestGetByName()
|
public void TestGetByName()
|
||||||
{
|
{
|
||||||
|
@ -54,8 +61,8 @@ public class BinTest
|
||||||
Assert.IsNotNull(e1);
|
Assert.IsNotNull(e1);
|
||||||
Assert.AreEqual(e1.Name, "element-name");
|
Assert.AreEqual(e1.Name, "element-name");
|
||||||
|
|
||||||
e1.Dispose();
|
|
||||||
bin.Dispose();
|
bin.Dispose();
|
||||||
|
e1.Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
|
@ -83,5 +90,22 @@ public class BinTest
|
||||||
|
|
||||||
bin.Dispose();
|
bin.Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestInterface()
|
||||||
|
{
|
||||||
|
Bin bin = new Bin(String.Empty);
|
||||||
|
Assert.IsNotNull(bin, "Could not create bin");
|
||||||
|
|
||||||
|
Element filesrc = ElementFactory.Make("filesrc", String.Empty);
|
||||||
|
Assert.IsNotNull(filesrc, "Could not create filesrc");
|
||||||
|
|
||||||
|
bin.Add(filesrc);
|
||||||
|
|
||||||
|
bin.Dispose();
|
||||||
|
filesrc.Dispose();
|
||||||
|
|
||||||
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -27,28 +27,146 @@ public class ElementTest
|
||||||
Application.Deinit();
|
Application.Deinit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestBinAdd()
|
||||||
|
{
|
||||||
|
Element src = ElementFactory.Make("fakesrc", null);
|
||||||
|
Element sink = ElementFactory.Make("fakesink", null);
|
||||||
|
|
||||||
|
Assert.AreEqual(src.Refcount, 1, "fakesrc");
|
||||||
|
Assert.AreEqual(sink.Refcount, 1, "fakesink");
|
||||||
|
|
||||||
|
Element pipeline = new Pipeline(String.Empty);
|
||||||
|
|
||||||
|
Assert.AreEqual(pipeline.Refcount, 1, "pipeline");
|
||||||
|
|
||||||
|
Bin bin = (Bin) pipeline;
|
||||||
|
Assert.AreEqual(bin.Refcount, 1, "bin");
|
||||||
|
Assert.AreEqual(pipeline.Refcount, 1, "pipeline");
|
||||||
|
|
||||||
|
bin.AddMany(src, sink);
|
||||||
|
Assert.AreEqual(src.Refcount, 2, "src");
|
||||||
|
Assert.AreEqual(sink.Refcount, 2, "sink");
|
||||||
|
Assert.AreEqual(bin.Refcount, 1, "bin");
|
||||||
|
Assert.AreEqual(pipeline.Refcount, 1, "pipeline");
|
||||||
|
|
||||||
|
src.Link(sink);
|
||||||
|
|
||||||
|
src.Dispose();
|
||||||
|
sink.Dispose();
|
||||||
|
pipeline.Dispose();
|
||||||
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void TestAddRemovePad()
|
public void TestAddRemovePad()
|
||||||
{
|
{
|
||||||
Element e = ElementFactory.Make("fakesrc", "source");
|
Element e = ElementFactory.Make("fakesrc", "source");
|
||||||
/* create a new floating pad with refcount 1 */
|
|
||||||
Pad p = new Pad("source", PadDirection.Src);
|
Pad p = new Pad("source", PadDirection.Src);
|
||||||
Assert.AreEqual(p.Refcount, 1, "pad");
|
Assert.AreEqual(p.Refcount, 1, "pad");
|
||||||
|
|
||||||
/* ref it for ourselves */
|
|
||||||
Gst.Object.Ref(p.Handle);
|
|
||||||
Assert.AreEqual(p.Refcount, 2, "pad");
|
|
||||||
/* adding it sinks the pad -> not floating, same refcount */
|
|
||||||
e.AddPad(p);
|
e.AddPad(p);
|
||||||
Assert.AreEqual(p.Refcount, 2, "pad");
|
Assert.AreEqual(p.Refcount, 2, "pad");
|
||||||
|
|
||||||
/* removing it reduces the refcount */
|
|
||||||
e.RemovePad(p);
|
e.RemovePad(p);
|
||||||
Assert.AreEqual(p.Refcount, 1, "pad");
|
|
||||||
|
|
||||||
/* clean up our own reference */
|
|
||||||
p.Dispose();
|
p.Dispose();
|
||||||
e.Dispose();
|
e.Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestAddPadUnrefElement ()
|
||||||
|
{
|
||||||
|
Element e = ElementFactory.Make("fakesrc", "source");
|
||||||
|
Assert.IsNotNull(e, "Could not create fakesrc");
|
||||||
|
Assert.IsTrue(e.GetType() == typeof(Gst.Element));
|
||||||
|
Assert.AreEqual(e.Refcount, 1);
|
||||||
|
|
||||||
|
Pad p = new Pad("source", PadDirection.Src);
|
||||||
|
Assert.AreEqual(p.Refcount, 1, "pad");
|
||||||
|
|
||||||
|
Gst.Object.Ref(p.Handle);
|
||||||
|
Assert.AreEqual(p.Refcount, 2, "pad");
|
||||||
|
|
||||||
|
e.AddPad(p);
|
||||||
|
Assert.AreEqual(p.Refcount, 3, "pad");
|
||||||
|
|
||||||
|
Gst.Object.Unref(p.Handle);
|
||||||
|
Assert.AreEqual(p.Refcount, 2, "pad");
|
||||||
|
|
||||||
|
Assert.AreEqual(e.Refcount, 1);
|
||||||
|
|
||||||
|
e.Dispose();
|
||||||
|
Assert.AreEqual(p.Refcount, 1, "pad");
|
||||||
|
|
||||||
|
p.Dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestErrorNoBus()
|
||||||
|
{
|
||||||
|
Element e = ElementFactory.Make("fakesrc", "source");
|
||||||
|
e.Dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
[Test]
|
||||||
|
public void TestLink()
|
||||||
|
{
|
||||||
|
State state, pending;
|
||||||
|
|
||||||
|
Element source = ElementFactory.Make("fakesrc", "source");
|
||||||
|
Assert.IsNotNull(source);
|
||||||
|
|
||||||
|
Element sink = ElementFactory.Make("fakesink", "sink");
|
||||||
|
Assert.IsNotNull(sink);
|
||||||
|
|
||||||
|
Assert.AreEqual(source.Refcount, 1, source.Name);
|
||||||
|
Assert.AreEqual(sink.Refcount, 1, "sink");
|
||||||
|
Assert.IsTrue(source.LinkPads("src", sink, "sink"));
|
||||||
|
|
||||||
|
sink.SetState(State.Paused);
|
||||||
|
source.SetState(State.Paused);
|
||||||
|
|
||||||
|
Assert.AreEqual(source.Refcount, 1, "src");
|
||||||
|
Assert.AreEqual(sink.Refcount, 1, "sink");
|
||||||
|
|
||||||
|
sink.GetState(out state, out pending, Clock.TimeNone);
|
||||||
|
|
||||||
|
sink.SetState(State.Playing);
|
||||||
|
source.SetState(State.Playing);
|
||||||
|
|
||||||
|
// Sleep
|
||||||
|
System.Threading.Thread.Sleep(500);
|
||||||
|
|
||||||
|
sink.SetState(State.Paused);
|
||||||
|
source.SetState(State.Paused);
|
||||||
|
|
||||||
|
sink.GetState(out state, out pending, Clock.TimeNone);
|
||||||
|
|
||||||
|
Assert.AreEqual(sink.Refcount, 1, "sink");
|
||||||
|
Assert.AreEqual(source.Refcount, 1, "src");
|
||||||
|
|
||||||
|
source.UnlinkPads("src", sink, "sink");
|
||||||
|
|
||||||
|
Assert.AreEqual(sink.Refcount, 1, "sink");
|
||||||
|
Assert.AreEqual(source.Refcount, 1, "src");
|
||||||
|
|
||||||
|
source.Dispose();
|
||||||
|
sink.Dispose();
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestLinkNoPads()
|
||||||
|
{
|
||||||
|
Element src = new Bin("src");
|
||||||
|
Element sink = new Bin("sink");
|
||||||
|
|
||||||
|
Assert.IsFalse(src.Link(sink));
|
||||||
|
|
||||||
|
src.Dispose();
|
||||||
|
sink.Dispose();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@ NUNIT_FLAGS = @MONO_NUNIT_LIBS@
|
||||||
|
|
||||||
ASSEMBLY_NAME = gstreamer-tests
|
ASSEMBLY_NAME = gstreamer-tests
|
||||||
ASSEMBLY = $(ASSEMBLY_NAME).dll
|
ASSEMBLY = $(ASSEMBLY_NAME).dll
|
||||||
ASSEMBLY_CSFILES = $(srcdir)/ApplicationTest.cs $(srcdir)/BinTest.cs $(srcdir)/CapsTest.cs $(srcdir)/PadTest.cs $(srcdir)/ElementTest.cs $(srcdir)/PipelineTest.cs
|
ASSEMBLY_CSFILES = $(srcdir)/ApplicationTest.cs $(srcdir)/BinTest.cs $(srcdir)/BufferTest.cs $(srcdir)/CapsTest.cs $(srcdir)/PadTest.cs $(srcdir)/ElementTest.cs $(srcdir)/MessageTest.cs $(srcdir)/PipelineTest.cs
|
||||||
|
|
||||||
|
|
||||||
NUNIT_TESTER_NAME = ConsoleUi
|
NUNIT_TESTER_NAME = ConsoleUi
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
//
|
//
|
||||||
// Authors:
|
// Authors:
|
||||||
// Michael Dominic K. (michaldominik@gmail.com)
|
// Michael Dominic K. (michaldominik@gmail.com)
|
||||||
|
// Khaled Mohammed (khaled.mohammed@gmail.com)
|
||||||
//
|
//
|
||||||
// (C) 2006 Novell, Inc.
|
// (C) 2006 Novell, Inc.
|
||||||
//
|
//
|
||||||
|
@ -26,7 +27,7 @@ public class PadTest
|
||||||
{
|
{
|
||||||
Application.Deinit();
|
Application.Deinit();
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
[Test]
|
[Test]
|
||||||
public void TestPlainCreation()
|
public void TestPlainCreation()
|
||||||
{
|
{
|
||||||
|
@ -89,11 +90,11 @@ public class PadTest
|
||||||
Caps sinkcaps = sink.Caps;
|
Caps sinkcaps = sink.Caps;
|
||||||
Assert.IsTrue(sinkcaps.IsAny, "How come sink pad caps is not ANY?");
|
Assert.IsTrue(sinkcaps.IsAny, "How come sink pad caps is not ANY?");
|
||||||
|
|
||||||
|
element.Dispose();
|
||||||
src.Dispose();
|
src.Dispose();
|
||||||
sink.Dispose();
|
sink.Dispose();
|
||||||
srccaps.Dispose();
|
srccaps.Dispose();
|
||||||
sinkcaps.Dispose();
|
sinkcaps.Dispose();
|
||||||
element.Dispose();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
|
@ -123,4 +124,26 @@ public class PadTest
|
||||||
element.Dispose();
|
element.Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestLink()
|
||||||
|
{
|
||||||
|
Pad src = new Pad("source", PadDirection.Src);
|
||||||
|
Assert.IsNotNull(src, "Pad could not be created");
|
||||||
|
Assert.AreEqual(src.Refcount, 1, "source pad");
|
||||||
|
|
||||||
|
string name = src.Name;
|
||||||
|
Assert.AreEqual(name, "source");
|
||||||
|
Assert.AreEqual(src.Refcount, 1, "source pad");
|
||||||
|
|
||||||
|
Pad sink = new Pad("sink", PadDirection.Sink);
|
||||||
|
Assert.IsNotNull(sink, "Pad could not be created");
|
||||||
|
|
||||||
|
Assert.AreEqual(src.Link(sink), PadLinkReturn.Noformat);
|
||||||
|
Assert.AreEqual(src.Refcount, 1, "source pad");
|
||||||
|
Assert.AreEqual(sink.Refcount, 1, "sink pad");
|
||||||
|
|
||||||
|
sink.Dispose();
|
||||||
|
src.Dispose();
|
||||||
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,7 @@ public class PipelineTest
|
||||||
{
|
{
|
||||||
Application.Deinit();
|
Application.Deinit();
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
[Test]
|
[Test]
|
||||||
public void TestAsyncStateChangeEmpty()
|
public void TestAsyncStateChangeEmpty()
|
||||||
{
|
{
|
||||||
|
@ -52,8 +52,10 @@ public class PipelineTest
|
||||||
Assert.AreEqual(((Element)pipeline).SetState(State.Ready), StateChangeReturn.Success);
|
Assert.AreEqual(((Element)pipeline).SetState(State.Ready), StateChangeReturn.Success);
|
||||||
|
|
||||||
pipeline.Dispose();
|
pipeline.Dispose();
|
||||||
|
src.Dispose();
|
||||||
|
sink.Dispose();
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
[Test]
|
[Test]
|
||||||
public void TestAsyncStateChangeFake()
|
public void TestAsyncStateChangeFake()
|
||||||
{
|
{
|
||||||
|
@ -88,7 +90,7 @@ public class PipelineTest
|
||||||
//bus.Dispose();
|
//bus.Dispose();
|
||||||
pipeline.Dispose();
|
pipeline.Dispose();
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
[Test]
|
[Test]
|
||||||
public void TestGetBus()
|
public void TestGetBus()
|
||||||
{
|
{
|
||||||
|
@ -190,5 +192,8 @@ public class PipelineTest
|
||||||
Pad sink = fakesink.GetPad("sink");
|
Pad sink = fakesink.GetPad("sink");
|
||||||
|
|
||||||
pipeline.Dispose();
|
pipeline.Dispose();
|
||||||
|
fakesrc.Dispose();
|
||||||
|
fakesink.Dispose();
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue