[longomatch] Fix events resynchronization after syncing periods
- From: Andoni Morales Alastruey <amorales src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [longomatch] Fix events resynchronization after syncing periods
- Date: Tue, 5 May 2015 09:09:12 +0000 (UTC)
commit b990a6ea55403a2497b11e24c7107d6df9d1ffb4
Author: Andoni Morales Alastruey <ylatuya gmail com>
Date: Tue Apr 28 20:07:09 2015 +0200
Fix events resynchronization after syncing periods
LongoMatch.Core/Store/Period.cs | 9 +-
LongoMatch.Core/Store/Project.cs | 48 ++++++++++++
.../CanvasObjects/Dashboard/TimerObject.cs | 1 +
.../Gui/Component/SynchronizationWidget.cs | 42 +---------
Tests/Core/Store/TestProject.cs | 79 ++++++++++++++++++++
5 files changed, 138 insertions(+), 41 deletions(-)
---
diff --git a/LongoMatch.Core/Store/Period.cs b/LongoMatch.Core/Store/Period.cs
index 3a4bed5..5c61e95 100644
--- a/LongoMatch.Core/Store/Period.cs
+++ b/LongoMatch.Core/Store/Period.cs
@@ -17,18 +17,18 @@
//
using System;
using System.Linq;
-using System.Collections.Generic;
using Newtonsoft.Json;
namespace LongoMatch.Core.Store
{
+ [Serializable]
public class Period: Timer
{
public Period ()
{
}
-
+
[JsonIgnore]
public TimeNode PeriodNode {
get {
@@ -39,8 +39,9 @@ namespace LongoMatch.Core.Store
if (stop.MSeconds == 0) {
stop = null;
}
- return new TimeNode {Name=Name,
- Start = start, Stop = stop};
+ return new TimeNode {Name = Name,
+ Start = start, Stop = stop
+ };
}
set {
foreach (TimeNode tn in Nodes) {
diff --git a/LongoMatch.Core/Store/Project.cs b/LongoMatch.Core/Store/Project.cs
index f6a849f..2a8f278 100644
--- a/LongoMatch.Core/Store/Project.cs
+++ b/LongoMatch.Core/Store/Project.cs
@@ -497,6 +497,54 @@ namespace LongoMatch.Core.Store
Description.VisitorGoals = GetScore (TeamType.VISITOR);
}
+
+ /// <summary>
+ /// Resynchronize events with the periods synced with the video file.
+ /// Imported projects or fake analysis projects create events assuming periods
+ /// don't have gaps between them.
+ /// After adding a file to the project and synchronizing the periods with the
+ /// video file, all events must be offseted with the new start time of the period.
+ ///
+ /// Before sync:
+ /// Period 1: start=00:00:00 Period 2: start=00:30:00
+ /// evt1 00:10:00 evt2 00:32:00
+ /// After sync:
+ /// Period 1: start=00:05:00 Period 2: start= 00:39:00
+ /// evt1 00:15:00 evt2 00:41:00
+ /// </summary>
+ /// <param name="periods">The new periods syncrhonized with the video file.</param>
+ public void ResyncEvents (List<Period> periods)
+ {
+ List<TimelineEvent> newTimeline = new List<TimelineEvent> ();
+
+ if (periods.Count != Periods.Count) {
+ throw new IndexOutOfRangeException (
+ "Periods count is different from the project's ones");
+ }
+
+ for (int i = 0; i < periods.Count; i++) {
+ Period oldPeriod = Periods [i];
+ TimeNode oldTN = oldPeriod.PeriodNode;
+ TimeNode newTN = periods [i].PeriodNode;
+ Time diff = newTN.Start - oldTN.Start;
+
+ /* Find the events in this period */
+ var periodEvents = Timeline.Where (e =>
+ e.EventTime >= oldTN.Start &&
+ e.EventTime <= oldTN.Stop).ToList ();
+
+ /* Apply new offset and move the new timeline so that the next
+ * iteration for the following period does not use them anymore */
+ periodEvents.ForEach (e => {
+ e.Move (diff);
+ newTimeline.Add (e);
+ Timeline.Remove (e);
+ });
+ oldPeriod.Nodes.ForEach (t => t.Move (diff));
+ }
+ Timeline = newTimeline;
+ }
+
public bool Equals (Project project)
{
if (project == null)
diff --git a/LongoMatch.Drawing/CanvasObjects/Dashboard/TimerObject.cs
b/LongoMatch.Drawing/CanvasObjects/Dashboard/TimerObject.cs
index 0120802..d1cdc55 100644
--- a/LongoMatch.Drawing/CanvasObjects/Dashboard/TimerObject.cs
+++ b/LongoMatch.Drawing/CanvasObjects/Dashboard/TimerObject.cs
@@ -18,6 +18,7 @@
using LongoMatch.Core.Common;
using LongoMatch.Core.Interfaces.Drawing;
using LongoMatch.Core.Store;
+using System.IO;
namespace LongoMatch.Drawing.CanvasObjects.Dashboard
{
diff --git a/LongoMatch.GUI/Gui/Component/SynchronizationWidget.cs
b/LongoMatch.GUI/Gui/Component/SynchronizationWidget.cs
index a044cde..ca09325 100644
--- a/LongoMatch.GUI/Gui/Component/SynchronizationWidget.cs
+++ b/LongoMatch.GUI/Gui/Component/SynchronizationWidget.cs
@@ -39,7 +39,7 @@ namespace LongoMatch.Gui.Component
Time duration;
Project project;
PeriodsMenu menu;
- Dictionary<Period, Period> periodsDict;
+ List<Period> periods;
double maxSecondsPerPixels;
enum DidacticMessage
@@ -179,39 +179,13 @@ namespace LongoMatch.Gui.Component
if (!resyncEvents)
return;
-
- /* Resynchronize events with the new start times of the period they belong too.
- * Imported projects or fake analysis projects create events assuming periods
- * don't have gaps between them.
- * After adding a file to the project and synchronizing the periods with the
- * video file, all events must be offseted with the new start time of the period.
- *
- * Before sync:
- * Period 1: start=00:00:00 Period 2: start=00:30:00
- * evt1 00:10:00 evt2 00:32:00
- * After sync:
- * Period 1: start=00:05:00 Period 2: start= 00:39:00
- * evt1 00:15:00 evt2 00:41:00
- */
- foreach (Period p in periodsDict.Keys) {
- Period newp = periodsDict [p];
- TimeNode tn = p.PeriodNode;
- Time diff = newp.PeriodNode.Start - tn.Start;
- foreach (TimelineEvent evt in project.Timeline.Where
- (e=>e.EventTime > tn.Start && e.EventTime < tn.Stop)) {
- evt.Move (diff);
- }
- foreach (TimeNode t in p.Nodes) {
- t.Move (diff);
- }
- }
+ project.ResyncEvents (periods);
}
public Project Project {
set {
Time start, pDuration;
List<string> gamePeriods;
- List<Period> periods;
MediaFile file;
this.project = value;
@@ -223,7 +197,6 @@ namespace LongoMatch.Gui.Component
file = fileSet.FirstOrDefault ();
duration = file.Duration;
pDuration = new Time (duration.MSeconds / gamePeriods.Count);
- periodsDict = new Dictionary <Period, Period> ();
if (project.Periods == null || project.Periods.Count == 0) {
/* If no periods are provided create the default ones
* defined in the dashboard */
@@ -238,14 +211,9 @@ namespace LongoMatch.Gui.Component
}
value.Periods = periods;
} else {
- /* Create a copy of the original periods and a mapping
- * to resynchronize the events in SaveChanges() */
- foreach (Period p in project.Periods) {
- Period newp = new Period { Name = p.Name };
- newp.Nodes.Add (p.PeriodNode);
- periodsDict.Add (p, newp);
- }
- periods = periodsDict.Values.ToList ();
+ /* Create a copy of the project periods and keep the
+ * project ones to resynchronize the events in SaveChanges() */
+ periods = project.Periods.Clone ();
}
camerasLabels.Load (fileSet);
diff --git a/Tests/Core/Store/TestProject.cs b/Tests/Core/Store/TestProject.cs
index 197e23b..8aa3685 100644
--- a/Tests/Core/Store/TestProject.cs
+++ b/Tests/Core/Store/TestProject.cs
@@ -269,5 +269,84 @@ namespace Tests.Core.Store
public void TestImport ()
{
}
+
+ [Test ()]
+ public void TestResyncEvents ()
+ {
+ Project p = CreateProject (false);
+ int offset1 = 100, offset2 = 120, offset3 = 150;
+ Period period;
+ List<Period> syncedPeriods;
+
+ period = new Period ();
+ period.Nodes.Add (new TimeNode { Start = new Time (0),
+ Stop = new Time (3000)
+ });
+ p.Periods.Add (period);
+ period = new Period ();
+ period.Nodes.Add (new TimeNode { Start = new Time (3001),
+ Stop = new Time (6000)
+ });
+ p.Periods.Add (period);
+ period = new Period ();
+ period.Nodes.Add (new TimeNode { Start = new Time (6001),
+ Stop = new Time (6500)
+ });
+ p.Periods.Add (period);
+
+ /* Test with a list of periods that don't match */
+ Assert.Throws<IndexOutOfRangeException> (
+ delegate {
+ p.ResyncEvents (new List<Period> ());
+ });
+
+ syncedPeriods = new List<Period> ();
+ period = new Period ();
+ period.Nodes.Add (new TimeNode {
+ Start = new Time (0 + offset1),
+ Stop = new Time (3000 + offset1)
+ });
+ syncedPeriods.Add (period);
+ period = new Period ();
+ period.Nodes.Add (new TimeNode {
+ Start = new Time (3001 + offset2),
+ Stop = new Time (6000 + offset2)
+ });
+ syncedPeriods.Add (period);
+ period = new Period ();
+ period.Nodes.Add (new TimeNode {
+ Start = new Time (6001 + offset3),
+ Stop = new Time (6500 + offset3)
+ });
+ syncedPeriods.Add (period);
+
+ /* 1st Period */
+ p.Timeline.Add (new TimelineEvent { EventTime = new Time (0) });
+ p.Timeline.Add (new TimelineEvent { EventTime = new Time (1500) });
+ p.Timeline.Add (new TimelineEvent { EventTime = new Time (3000) });
+ /* 2nd Period */
+ p.Timeline.Add (new TimelineEvent { EventTime = new Time (3001) });
+ p.Timeline.Add (new TimelineEvent { EventTime = new Time (4500) });
+ p.Timeline.Add (new TimelineEvent { EventTime = new Time (6000) });
+ /* 3nd Period */
+ p.Timeline.Add (new TimelineEvent { EventTime = new Time (6001) });
+ p.Timeline.Add (new TimelineEvent { EventTime = new Time (6200) });
+ p.Timeline.Add (new TimelineEvent { EventTime = new Time (6500) });
+
+ List<TimelineEvent> oldTimeline = p.Timeline.Clone ();
+
+ p.ResyncEvents (syncedPeriods);
+ Assert.AreEqual (oldTimeline [0].EventTime + offset1, p.Timeline [0].EventTime);
+ Assert.AreEqual (oldTimeline [1].EventTime + offset1, p.Timeline [1].EventTime);
+ Assert.AreEqual (oldTimeline [2].EventTime + offset1, p.Timeline [2].EventTime);
+
+ Assert.AreEqual (oldTimeline [3].EventTime + offset2, p.Timeline [3].EventTime);
+ Assert.AreEqual (oldTimeline [4].EventTime + offset2, p.Timeline [4].EventTime);
+ Assert.AreEqual (oldTimeline [5].EventTime + offset2, p.Timeline [5].EventTime);
+
+ Assert.AreEqual (oldTimeline [6].EventTime + offset3, p.Timeline [6].EventTime);
+ Assert.AreEqual (oldTimeline [7].EventTime + offset3, p.Timeline [7].EventTime);
+ Assert.AreEqual (oldTimeline [8].EventTime + offset3, p.Timeline [8].EventTime);
+ }
}
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]