If you do not expire the layout being modified, some exceptions may cause the splash screen to appear

(My Environment: cms: 2.3.4, player: dotnetplayer 254.1)

Hello.

As the title suggests, if you do not expire the modified layout, internally, some exceptions are caught and a splash screen is displayed.

(1)
The triggering method is “ScheduleManager - LoadNewSchedule” which does not check the validity of the currently playing layout.

(2)
The root cause is that the SetRequiredFiles method in the RequiredFiles class deletes the modified layout as a “Delete the old file as it is wrong” in the process of creating the download list (From RequiredFiles.xml).

(3)
As a result , a blank period where xlf does not exist for the modified layout is happen.

The point is:
If the following three conditions (①, ②, ③) are met, this topic’s event will occur.

① The current layout has been changed.
② The current layout cycle ends before the download of the new xlf and its dependencies is complete.
③ There is no other layout for the next appointment (So I repeat myself again.), or all of the layouts for the next appointment are disabled.

Because the above (1) makes a layout that doesn’t have xlf valid, the player tries to find it, but the file doesn’t exist.
This results in two exceptions ((a) and (b)):.

(a)
Layout Preparation Failed Exception (xlf not found)
[UI Thread] MainForm-PrepareLayout IOException: System.IO.FileNotFoundException:
(b)
Exceptions that the layout you plan to view next cannot be changed (Occurs due to previously described NotFound)
[UI Thread] MainForm-ChangeToNextLayout Layout Change to C: \Users \ (username) \Documents \XiboClient Library (layoutId) .xlf failed.

I think that some users like me, who use a layout that changes dynamically, turn off the expiration setting in order to avoid the interruption of the running layout (new stuff pops up when the download is complete).

[Related topics]

I avoid this by “Do not delete and overwrite xlf so it does not create a blank period”.
The work is simple: if you have xlf in SetRequiredFiles (), it won’t delete it even if it changes.

■before

■after

Because xlf always loads dependencies first, playing a new xlf will not cause an error.

The only concern is that old xlf dependencies will be out of control and will be removed by the libraryAgent.
However, by default, there is a 2-day grace period for removal, during which time the new xlf dependencies should have been downloaded.

I look forward to your comment. :smile:

It was not v 254.1 but v 201 that I saw this phenomenon.
Excuse me.
In v 254.1, the value of “CurrentLayoutId” is not set in the Schedule class (Always remain at 0), so (1) in the previous post does not occur.
This is because the following “CurrentLayoutId” settings in v 201 do not exist in v 254.1:.

(Schedule.cs)


        /// '<'summary'>'
        /// The current layout id
        /// '<'/summary'>'
        public int CurrentLayoutId
        {
            get
            {
                return _currentLayoutId;
            }
            set
            {
                _currentLayoutId = value;

                if (_scheduleManager != null)
                    _scheduleManager.CurrentLayoutId = _currentLayoutId;
            }
        }
        private int _currentLayoutId;

As a result, my next post

will be
because the following if statement is always false:.

(ScheduleManager.cs)


                if (!ApplicationSettings.Default.ExpireModifiedLayouts && layout.id == CurrentLayoutId)
                {
                    Trace.WriteLine(new LogMessage("ScheduleManager - LoadNewSchedule", "Skipping validity test for current layout."), LogType.Audit.ToString());
                }

As a result, in our case (v 254.1),
Instead of a splash screen caused by an invalid layout being incorrectly treated as valid,
As a result, the default layout is displayed.

Some interesting discoveries you’ve made there - thanks for the time and write up :+1: :bowing_man:

I think it is implied in our documentation and past topics that when a Layout gets modified, existing Players will stop playing the old version of that Layout. The “expire modified layouts” setting just controls whether or not a Layout already playing is allowed to play out, or if its changed immediately. Therefore the test in ScheduleManager which isn’t working (thanks - fixed that) is intended to make sure that if the Layout is being currently shown, then it remains on screen until it is finished.

With the modification you propose, it would mean that the Layout would continue to play in its old format, until the new Layout could be downloaded. This would be a breaking change in the logic, because some users rely on being able to effectively guarantee that the old Layout won’t be shown (which is why we delete it).

Does that make sense?

Edit: I should add that i’d expect the default layout to be played in that situation - not the splash screen.

1 Like

I understand well.
There are some people who need to discard old layouts immediately.
I see.

About what is written in Edit: …
I agree that in the case I presented (Errors that cause non-existent layouts to be executed), the default layout is better than the splash screen.
I would appreciate it if you could consider it.

Thank you for your continued support.

I think this might also be solved in R255, but I am not sure. Would you be able to try it and see?

Hi, Dan.
Sorry for my late reply.
I don’t have a working test of this yet, but I looked at the source directly.
I am referring to the following processing within ChangeToNextLayout () in MainWindow.xaml.cs:.


        /// 
        /// Change to the next layout
        /// 
        /// 
        private void ChangeToNextLayout(ScheduleItem scheduleItem)
        {
            Debug.WriteLine("ChangeToNextLayout: called", "MainWindow");

            if (ApplicationSettings.Default.PreventSleep)
            {
                try
                {
                    SetThreadExecutionState(EXECUTION_STATE.ES_DISPLAY_REQUIRED | EXECUTION_STATE.ES_SYSTEM_REQUIRED | EXECUTION_STATE.ES_CONTINUOUS);
                }
                catch
                {
                    Trace.WriteLine(new LogMessage("MainForm - ChangeToNextLayout", "Unable to set Thread Execution state"), LogType.Info.ToString());
                }
            }

            try
            {
                // Destroy the Current Layout
                try
                {
                    if (this.currentLayout != null)
                    {
                        Debug.WriteLine("ChangeToNextLayout: stopping the current Layout", "MainWindow");

                        this.currentLayout.Stop();

                        DestroyLayout(this.currentLayout);

                        Debug.WriteLine("ChangeToNextLayout: stopped and removed the current Layout", "MainWindow");
                    }
                }
                catch (Exception e)
                {
                    // Force collect all controls
                    this.Scene.Children.Clear();

                    Trace.WriteLine(new LogMessage("MainForm", "ChangeToNextLayout: Destroy Layout Failed. Exception raised was: " + e.Message), LogType.Info.ToString());
                    throw e;
                }

                // Prepare the next layout
                try
                {
                    this.currentLayout = PrepareLayout(scheduleItem);

                    // We have loaded a layout background and therefore are no longer showing the splash screen
                    // Remove the Splash Screen Image
                    RemoveSplashScreen();

                    // Start the Layout.
                    StartLayout(this.currentLayout);
                }
                catch (DefaultLayoutException)
                {
                    throw;
                }
                catch (Exception e)
                {
                    Trace.WriteLine(new LogMessage("MainForm", "ChangeToNextLayout: Prepare/Start Layout Failed. Exception raised was: " + e.Message), LogType.Info.ToString());

                    // Remove the Layout again
                    if (this.currentLayout != null)
                    {
                        DestroyLayout(this.currentLayout);
                    }
                    throw;
                }
            }
            catch (Exception ex)
            {
                if (!(ex is DefaultLayoutException))
                {
                    Trace.WriteLine(new LogMessage("MainForm", "ChangeToNextLayout: Layout Change to " + scheduleItem.layoutFile + " failed. Exception raised was: " + ex.Message), LogType.Error.ToString());
                }

                // Do we have more than one Layout in our schedule?
                if (_schedule.ActiveLayouts > 1)
                {
                    _schedule.NextLayout();
                }
                else
                {
                    if (!_showingSplash)
                    {
                        ShowSplashScreen();
                    }

                    // In 10 seconds fire the next layout
                    DispatcherTimer timer = new DispatcherTimer()
                    {
                        Interval = new TimeSpan(0, 0, 10)
                    };
                    timer.Tick += new EventHandler(splashScreenTimer_Tick);
                    timer.Start();
                }
            }
        }

In the case of else, the only option is to have a splash screen, so in that case I wish I had a default layout instead. :slightly_smiling_face:

By the way, I would appreciate it if you could make the “Avoid removing xlf when checking hash values to avoid creating blank periods when xlf does not exist” that I proposed as an option.
I would appreciate it if you could add it to one of the ideas for future development.
I understand that some users want to delete xlf right away, but there are some users like me who are worried that xlf will be deleted.
I would appreciate it if you could consider it.

My explanation seems to be insufficient, so let me add a little bit about the problem I have.

・We are using only one layout.
・The current specification assumes that the current layout is unconditionally valid.
・I have also confirmed that this specification will not be a problem unless the current layout has been changed.
・On the other hand, we only use one layout (Layout ID does not change), so that xlf is deleted frequently every time the layout is updated.
(Specifically, the layout changes as the image in the dynamic playlist is updated.)
As a result, there are many cases where “ChangeToNextLayout () Could Not Download Updated Files in Time”.
Therefore, it is often the case that “Splash screen appears when a reference to xlf in the current layout occurs”.

This is the specific problem we have.

That’s why I made a proposal like the one in the previous post.
・Overwrite xlf instead of deleting it.
・If you’re going to get a splash screen anyway, set it to the default layout.

Sorry for the delay.

The player spec we work to says that we should only show the splash screen if we cannot do anything else. Change Layout should be doing that already, and the final catch block should only be activated if something very bad has happened.

Essentially prepare/start should throw a DefaultLayoutException in all cases where we want to switch to the default. (basically all the time unless we are actually the default).

So I think I agree with the way you’re expecting it to work, but I am not clear why it doesn’t already work that way.

In your case you have an Always schedule for 1 Layout, and then a different default layout? If that is true, then when your scheduled Layout becomes invalid (because the file is deleted), you should get a Default Layout instead of a splash screen.


For your other request, we would need to introduce a setting for this in the Display Settings profile - because people do expect it to work the way it does currently (i.e. if a Layout has been changed, do not show the old one anymore). I think it would be something like “keepRevisionsPendingDownload”

The implementation of that is quite simple, but we’re talking about editing 5 player code bases :slight_smile: so it might take a while. I suggest we do Windows first.

Would you mind creating two issues for this in the GitHub repository? With a link to this topic?

Thanks,
Dan

(After that, I left the signage department, so I wrote late. Sorry.
I leave a comment so that the topic does not expire.)

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.