Hello Ventuzians!
THE FORUMS ARE CLOSED!

Please join our discord server HERE!! << click me :D

We are shutting our Ventuz Forum, but don't worry, it will all be archived for you to search in if you have a query. From now on, please add all your comments, questions or observations into our Discord Server

Thanks for the great time - see you on discord!!
Dee, Karol, Daniel and the whoooole Product and Support team!

Ventuz.Remoting4

Q and A about functionality and how to solve a special task for your application.

Moderator: Support

mofo7777

Ventuz.Remoting4

Post by mofo7777 » 20 Jan 2014, 15:54

Hello.

I'm working with Ventuz.Remoting4. I want to get the animation(s) from a loaded scene. Because i don't know nothing about the scene and the machines, i need to discover all things.

For now, i'm using the Cluster class to discover the machines. This is ok.

Next i suppose i need the pipe info from a loaded scene to get the IID. The problem is LayoutIID from pipe info is null (there is a machine). The over problem is i don't know where to find the name of the scene.

For the next step, i suppose i should use "SceneModel.FromStream" to get the animations. I need the xaml Stream, but i don't really know how to get it from a specific scene. Perhaps i should use Cluster.SceneModel, but i need the IID.

Could you tell me the right way to do this ?

Here is some code i tried :

Code: Select all

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using Ventuz.Remoting4;
using Ventuz.Remoting4.SceneModel;
using System.Windows.Markup;

namespace VentuzDirectorTest
{
    /// <summary>
    /// Interaction logic for VentuzDirectorTest-Window
    /// </summary>
    public partial class Window : UserControl
    {
        VentuzDirectorTest.Plugin plugin;
        private Cluster m_Cluster = null;
        private VentuzInfo vtzInfo;

        public Window(VentuzDirectorTest.Plugin plugin)
        {
            this.plugin = plugin;
            this.DataContext = plugin;
            InitializeComponent();
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            if (m_Cluster != null)
                return;

            try
            {

                m_Cluster = new Cluster();
                m_Cluster.Name = "Ventuz";
                //m_Cluster.VentuzInfo;
                //{ Name = "Ventuz" };
                m_Cluster.AddMachine(new System.Net.IPEndPoint(System.Net.IPAddress.Parse("127.0.0.1"), 19400));
                //m_Cluster.AddMachine(new System.Net.IPEndPoint(System.Net.IPAddress.Parse("10.0.0.8"), 19400));

                m_Cluster.Log += cluster_Log;
                m_Cluster.ClusterStateChanged += cluster_ClusterStateChanged;
                m_Cluster.VentuzInfoChanged += cluster_VentuzInfoChanged;
                m_Cluster.Start();
            }
            catch (Exception ex)
            {
                MessageBox.Show("Error Init : " + ex.Message);
            }
        }

        private void Button_Click_1(object sender, RoutedEventArgs e)
        {
            if (m_Cluster == null)
                return;

            try
            {

                m_Cluster.Shutdown();

            }
            catch (Exception ex)
            {
                MessageBox.Show("Error End : " + ex.Message);
            }
            finally
            {

                m_Cluster = null;
            }
        }

        private void cluster_Log(object sender, LogEventArgs e)
        {
            if(m_Cluster != null)
                TexBlock1.Dispatcher.BeginInvoke((Action)(() => { TexBlock1.Text += string.Format("Log : {0}: {1} {2} {3}\r\n", m_Cluster.Name, e.Level, e.Module, e.Message); }));
        }

        private void cluster_ClusterStateChanged(object sender, EventArgs e)
        {
            if (m_Cluster != null){

                TexBlock1.Dispatcher.BeginInvoke((Action)(() => { TexBlock1.Text += string.Format("ClusterState : {0}\r\n", m_Cluster.ClusterState); }));

                /*if (m_Cluster.ClusterState == ClusterState.Ok)
                {
                    DataModel projectDM = (DataModel)System.Windows.Markup.XamlReader.Parse(m_Cluster.DataModel(null).Result);

                    if (!projectDM.IsEmpty)
                    {
                        foreach (DataItem dt in projectDM.Items)
                        {
                            TexBlock1.Dispatcher.BeginInvoke((Action)(() => { TexBlock1.Text += string.Format("{0}: {1} {2} {3} {4}\r\n", dt.Name, dt.Description, dt.Label, dt.Mode, dt.UserData); }));
                        }
                    }
                }*/

                if (m_Cluster.ClusterState == ClusterState.Ok)
                {
                    /*try
                    {

                        //DataModel liveOptionsDM = (DataModel)XamlReader.Parse(m_Cluster.OptionsDataModel(null).Result);

                        DataModel projectDM = (DataModel)System.Windows.Markup.XamlReader.Parse(m_Cluster.DataModel(null).Result);
                        MessageBox.Show(projectDM.ToString());

                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show(ex.Message);
                    }*/

                     PipeInfo pp = new PipeInfo();
                     bool bTest = m_Cluster.TryGetPipeInfo(0, 0, out pp);

                     if (bTest)
                     {
                         TexBlock1.Dispatcher.BeginInvoke((Action)(() => { TexBlock1.Text += string.Format("LayoutIID : {0}\r\n", pp.LayoutIID); }));
                     }

                    /*IID[] iiis = m_Cluster.Scenes("0000", true, null).Result;

                    foreach (IID iii in iiis)
                    {
                        TexBlock1.Dispatcher.BeginInvoke((Action)(() => { TexBlock1.Text += string.Format("{0}\r\n", iii.ToString()); }));
                    }*/
                }

                //string sm = m_Cluster.SceneModel(null).Result;
                //TexBlock1.Dispatcher.BeginInvoke((Action)(() => { TexBlock1.Text += sm; }));
            }
        }

        private void cluster_VentuzInfoChanged(object sender, VentuzInfoChangedEventArgs e)
        {
            vtzInfo = e.Info;
            TexBlock1.Dispatcher.BeginInvoke((Action)(() => { TexBlock1.Text += string.Format("Info : {0}\r\n", vtzInfo); }));

            PipeInfo pp = new PipeInfo();
            bool bTest = m_Cluster.TryGetPipeInfo(0, 0, out pp);

            if (bTest)
            {
                TexBlock1.Dispatcher.BeginInvoke((Action)(() => { TexBlock1.Text += string.Format("LayoutIID 2 : {0}\r\n", pp.LayoutIID); }));
            }

            /*try
            {

                DataModel liveOptionsDM = (DataModel)XamlReader.Parse(m_Cluster.OptionsDataModel(null).Result);
                MessageBox.Show(liveOptionsDM.ToString());

            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }*/
        }

        private void Button_Click_2(object sender, RoutedEventArgs e)
        {
            TexBlock1.Text = "";
        }
    }
}

mofo7777

Re: Ventuz.Remoting4

Post by mofo7777 » 21 Jan 2014, 18:37

Hello.

I've made some few progress. It seems that some tasks from the Cluster class can only be use in the thread that creates the Cluster. It would be nice that Cluster class use some SynchronizationContext for all of his events, so this will make the remoting4 Library easier to use.

So now i get the two LayoutIID from the machine. According to the documentation, the IID from the scene is unknown at first time. Your sample use Cluster.Load with the name of the scene to get IID scene. But what if i don't the scene name. How to get it when i just have the PipeInfo IID ?

Here is the current code i tested :

Code: Select all

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using Ventuz.Remoting4;
using Ventuz.Remoting4.SceneModel;
using System.Windows.Markup;

namespace VentuzDirectorTest
{
    /// <summary>
    /// Interaction logic for VentuzDirectorTest-Window
    /// </summary>
    public partial class Window : UserControl
    {
        VentuzDirectorTest.Plugin plugin;
        private Cluster m_Cluster = null;
        private VentuzInfo vtzInfo;

        public Window(VentuzDirectorTest.Plugin plugin)
        {
            this.plugin = plugin;
            this.DataContext = plugin;
            InitializeComponent();
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            if (m_Cluster != null)
                return;

            try
            {

                m_Cluster = new Cluster();
                m_Cluster.Name = "Ventuz";
                //m_Cluster.VentuzInfo;
                //{ Name = "Ventuz" };
                m_Cluster.AddMachine(new System.Net.IPEndPoint(System.Net.IPAddress.Parse("127.0.0.1"), 19400));
                //m_Cluster.AddMachine(new System.Net.IPEndPoint(System.Net.IPAddress.Parse("10.0.0.8"), 19400));

                m_Cluster.Log += cluster_Log;
                m_Cluster.ClusterStateChanged += cluster_ClusterStateChanged;
                m_Cluster.VentuzInfoChanged += cluster_VentuzInfoChanged;
                m_Cluster.Start();
            }
            catch (Exception ex)
            {
                MessageBox.Show("Error Init : " + ex.Message);
            }
        }

        private void Button_Click_1(object sender, RoutedEventArgs e)
        {
            if (m_Cluster == null)
                return;

            try
            {

                m_Cluster.Shutdown();

            }
            catch (Exception ex)
            {
                MessageBox.Show("Error End : " + ex.Message);
            }
            finally
            {

                m_Cluster = null;
            }
        }

        private void cluster_Log(object sender, LogEventArgs e)
        {
            TexBlock1.Dispatcher.BeginInvoke((Action)(() => { TexBlock1.Text += string.Format("Log : {0}: {1} {2} {3}\r\n", m_Cluster.Name, e.Level, e.Module, e.Message); }));
        }

        private void cluster_ClusterStateChanged(object sender, EventArgs e)
        {
            TexBlock1.Dispatcher.BeginInvoke((Action)(() => { TexBlock1.Text += string.Format("ClusterState : {0}\r\n", m_Cluster.ClusterState); }));
        }

        private void cluster_VentuzInfoChanged(object sender, VentuzInfoChangedEventArgs e)
        {
            vtzInfo = e.Info;
            TexBlock1.Dispatcher.BeginInvoke((Action)(() => { 
                
                TexBlock1.Text += string.Format("Info : {0}\r\n", vtzInfo);

                PipeInfo pp = new PipeInfo();
                bool bTest = m_Cluster.TryGetPipeInfo(0, 0, out pp);
                // bool bTest = m_Cluster.TryGetPipeInfo(0, 1, out pp);

                if (bTest && pp.LayoutIID != null)
                {
                    TexBlock1.Text += string.Format("LayoutIID : {0}\r\n", pp.LayoutIID);
                }
                else
                {
                    TexBlock1.Text += "LayoutIID : null\r\n";
                }

                try
                {
                
                    // This is OK
                    //DataModel liveOptionsDM = (DataModel)XamlReader.Parse(m_Cluster.OptionsDataModel(null).Result);
                    //DataModel projectDM = (DataModel)System.Windows.Markup.XamlReader.Parse(m_Cluster.DataModel(null).Result);

                    // Here i don't know the scene name. so i try the projectname...
                    FlaggedIID iid = m_Cluster.Load(pp.LayoutIID.Value, vtzInfo.ProjectName, LoadFlags.New | LoadFlags.Existing, null).Result;

                    // Do not work
                    //var task = m_Cluster.Scenes(pp.LayoutIID.Value, true, null);
                    //task.Wait(1000);

                    // I tried "0000" and "0001"
                    var task = m_Cluster.Scenes("0000", true, null);
                    task.Wait(1000);

                    if (task.IsCompleted)
                    {
                        IID[] iids = task.Result;

                        if (iids.Length > 0)
                        {
                            TexBlock1.Text += ("Find IIDs " +  iids.Length.ToString() + "\r\n");
                        }
                    }
                    else
                    {
                        TexBlock1.Text += "Task error\r\n";
                    }

                    // Do not work
                    //var task = m_Cluster.SceneModel(pp.LayoutIID.Value, null);

                    // Do not work
                    //FlaggedIID iid = m_Cluster.PortStatus("0000", 0, true, null, null, null).Result;
                }
                catch (Exception ex)
                {
                    TexBlock1.Text += ex.Message;
                }
            
            }));
        }

        private void Button_Click_2(object sender, RoutedEventArgs e)
        {
            TexBlock1.Text = "";
        }
    }
}

User avatar
Robert
Posts: 318
Joined: 21 Jan 2012, 09:25
Location: Toulouse - France
Contact:

Re: Ventuz.Remoting4

Post by Robert » 21 Jan 2014, 21:43

Hey Dev team !

Since the documentation and sample codes are very light, it would be nice if we could have some quick answers.

R

mofo7777

Re: Ventuz.Remoting4

Post by mofo7777 » 23 Jan 2014, 19:01

Hello.

Some other progress. We change the Ventuz configuration project with a default layout and a default activated scene. I also upgrade the Ventuz version to the last update.

Now i can get scenes IID from Cluster.Scenes. I get 6 IIDs, 2 for the layout and 4 for the scene. After i check for the activated scene of the 6 IIDS with Cluster.Status. Next i get the data from the scene with Cluster.SceneModel. Here i can get the animations. The connections from the animations are present (Name and Namereverse).

My question is how to start the animation with the connection from the animation scene model ?

I think it's Cluster.DataItem, but i'm not sure and i don't know the parameters to use.

User avatar
Ralf Stanke
Posts: 11
Joined: 10 Jan 2012, 12:03

Re: Ventuz.Remoting4

Post by Ralf Stanke » 27 Jan 2014, 16:22

Hi!

If you like to control an animation that is part of the scene data make sure that this animation is not marked as a DataItem for the scene template. Simply remove the check mark in the Scene Data Editor.
When done, you can send control strings to the path the data item that represented the required animation.

http://www.ventuz.com/support/help/late ... ionControl

The old Remoting2 wasn't able to control animations directly - the only way was to trigger events (Begin, Next, etc). With Remoting4 you get control over the entire animation logic...

Here is a small demo code (C#, WinForms) that shows how to control a scene (including proper thread management)
Have a look to the PortStatus command where the special IID.Invalid is specified. This tells the renderer not to changed the current scene assigned in the addressed port! (see documentation of the setIID parameter)

Code: Select all

    public partial class Form1 : Form
    {
        Cluster cluster;
        IID iid;

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            // create and start a cluster to localhost
            this.cluster = new Cluster();
            this.cluster.AddMachine(new IPEndPoint(IPAddress.Loopback, Cluster.DEFAULT_PORT));
            this.cluster.ClusterStateChanged += cluster_ClusterStateChanged;
            this.cluster.Start();
        }

        // cluster_ClusterStateChanged may be executed by worker threads!
        async void cluster_ClusterStateChanged(object sender, EventArgs e)
        {
            // cluster state ok?
            if ( (this.cluster.ClusterState & ClusterState.ErrorMask) == 0 )
            {
                // yes - query the current IID of the scene that is in pipe 0, port 0
                var portStatus = await this.cluster.PortStatus(0, 0, null, IID.Invalid, null, null);
                // got an IID ?
                if ( portStatus.IID.HasValue )
                {
                    // yes - save IID
                    this.iid = portStatus.IID.Value;
                    // enable the button (on UI thread)
                    this.Invoke(new Action(() => { this.button1.Enabled = true; }));
                }
            }
            else
            {
                // cluster is in error state 
                this.iid = 0;
                // disable button (on UI thread)
                this.Invoke(new Action(() => { this.button1.Enabled = false; }));
            }
        }

        protected override void OnClosing(CancelEventArgs e)
        {
            // shutdown the cluster and all related thread
            this.cluster.Shutdown();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            try
            {
                // control the animation
                this.cluster.DataItem(this.iid, ".Animation1", "C1 W1 C-1", null, null);
            }
            catch ( Exception ex )
            {
                MessageBox.Show(ex.Message);
            }
        }
    }

User avatar
Ralf Stanke
Posts: 11
Joined: 10 Jan 2012, 12:03

Re: Ventuz.Remoting4

Post by Ralf Stanke » 27 Jan 2014, 16:28

... btw, this example requires a running Ventuz Runtime or Ventuz Designer that already has loaded the required scene!

User avatar
Karol
Posts: 640
Joined: 10 Jan 2012, 12:07

Re: Ventuz.Remoting4

Post by Karol » 27 Jan 2014, 17:45

We are working on demos for Remoting 4. Stay tuned...

mofo7777

Re: Ventuz.Remoting4

Post by mofo7777 » 27 Jan 2014, 17:56

Hello.

Thank you.

I have to check with Robert if there is a configuration to do in Ventuz Project, because i get this message from the Ventuz Runtime when i try to start the animation :
Remoting2: Set DataItem Scene scene 01 : .animRobert01 is read-only: invalid operation

Demos will be very usefull to discover the Remoting4 library. Thank you.

User avatar
Ralf Stanke
Posts: 11
Joined: 10 Jan 2012, 12:03

Re: Ventuz.Remoting4

Post by Ralf Stanke » 27 Jan 2014, 18:27

Hi,

If the animation is read-only you probably forgot to uncheck the DataItem as part of the Scene template. See Scene Data Editor.

We're currently working on some example codes. The Remoting4 is very powerful and reflects the entire capabilities of Ventuz in handling scenes, ports and the related data. As well the .NET async technologies are fully implemented for non-blocking user interfaces (like Ventuz Director). That's why it confuses many developers because the programming technique might be new for them. The current Remoting4 SDK is a low-level API - we also working on high-level wrappers that make life easier.

Ralf

mofo7777

Re: Ventuz.Remoting4

Post by mofo7777 » 27 Jan 2014, 18:59

Hello.

It's OK now. I can start the animation.

Thank you for your help.

Post Reply