Added parsing data using reflection, started work on generating watchface from config

fonts_experiment
Valeriy Mironov 2017-11-23 04:23:43 +02:00
parent 128d4ad242
commit 27671aafbe
41 changed files with 553 additions and 1119 deletions

View File

@ -1,53 +1,24 @@
using System;
using System.Collections.Generic;
using NLog;
using WatchFace.Elements.ActivityElements;
using WatchFace.Elements.ActivityElements;
using WatchFace.Elements.BasicElements;
using WatchFace.Models;
using WatchFace.Utils;
namespace WatchFace.Elements
{
public class Activity
{
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
[RawParameter(Id = 3)]
public Number Calories { get; set; }
[RawParameter(Id = 4)]
public Number Pulse { get; set; }
[RawParameter(Id = 1)]
public Number Steps { get; set; }
[RawParameter(Id = 2)]
public Number StepsGoal { get; set; }
[RawParameter(Id = 5)]
public FormattedNumber Distance { get; set; }
public static Activity Parse(List<Parameter> descriptor, string path)
{
Logger.Trace("Reading {0}", path);
if (descriptor == null)
throw new ArgumentNullException(nameof(descriptor));
var result = new Activity();
foreach (var parameter in descriptor)
{
var currentPath = string.Concat(path, '.', parameter.Id.ToString());
switch (parameter.Id)
{
case 1:
result.Steps = Number.Parse(parameter.Children, currentPath);
break;
case 2:
result.StepsGoal = Number.Parse(parameter.Children, currentPath);
break;
case 3:
result.Calories = Number.Parse(parameter.Children, currentPath);
break;
case 4:
result.Pulse = Number.Parse(parameter.Children, currentPath);
break;
case 5:
result.Distance = FormattedNumber.Parse(parameter.Children, currentPath);
break;
default:
throw new InvalidParameterException(parameter, path);
}
}
return result;
}
}
}

View File

@ -1,45 +1,17 @@
using System;
using System.Collections.Generic;
using NLog;
using WatchFace.Elements.BasicElements;
using WatchFace.Models;
using WatchFace.Elements.BasicElements;
using WatchFace.Utils;
namespace WatchFace.Elements.ActivityElements
{
public class FormattedNumber
{
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
[RawParameter(Id = 1)]
public Number Number { get; set; }
[RawParameter(Id = 2)]
public long SuffixImageIndex { get; set; }
[RawParameter(Id = 3)]
public long DecimalPointImageIndex { get; set; }
public static FormattedNumber Parse(List<Parameter> descriptor, string path)
{
Logger.Trace("Reading {0}", path);
if (descriptor == null)
throw new ArgumentNullException(nameof(descriptor));
var result = new FormattedNumber();
foreach (var parameter in descriptor)
{
var currentPath = string.Concat(path, '.', parameter.Id.ToString());
switch (parameter.Id)
{
case 1:
result.Number = Number.Parse(parameter.Children, currentPath);
break;
case 2:
result.SuffixImageIndex = parameter.Value;
break;
case 3:
result.DecimalPointImageIndex = parameter.Value;
break;
default:
throw new InvalidParameterException(parameter, path);
}
}
return result;
}
}
}

View File

@ -1,44 +1,17 @@
using System;
using System.Collections.Generic;
using NLog;
using WatchFace.Elements.BasicElements;
using WatchFace.Models;
using WatchFace.Elements.BasicElements;
using WatchFace.Utils;
namespace WatchFace.Elements
{
public class AnalogDialFace
{
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
[RawParameter(Id = 1)]
public ClockHand Hours { get; set; }
[RawParameter(Id = 2)]
public ClockHand Minutes { get; set; }
[RawParameter(Id = 3)]
public ClockHand Seconds { get; set; }
public static AnalogDialFace Parse(List<Parameter> descriptor, string path)
{
Logger.Trace("Reading {0}", path);
if (descriptor == null)
throw new ArgumentNullException(nameof(descriptor));
var result = new AnalogDialFace();
foreach (var parameter in descriptor)
{
var currentPath = string.Concat(path, '.', parameter.Id.ToString());
switch (parameter.Id)
{
case 1:
result.Hours = ClockHand.Parse(parameter.Children, currentPath);
break;
case 2:
result.Minutes = ClockHand.Parse(parameter.Children, currentPath);
break;
case 3:
result.Seconds = ClockHand.Parse(parameter.Children, currentPath);
break;
default:
throw new InvalidParameterException(parameter, path);
}
}
return result;
}
}
}

View File

@ -1,32 +1,11 @@
using System.Collections.Generic;
using NLog;
using WatchFace.Elements.BasicElements;
using WatchFace.Models;
using WatchFace.Elements.BasicElements;
using WatchFace.Utils;
namespace WatchFace.Elements
{
public class Background
{
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
[RawParameter(Id = 1)]
public Image Image { get; set; }
public static Background Parse(List<Parameter> parameters, string path)
{
Logger.Trace("Reading {0}", path);
var result = new Background();
foreach (var parameter in parameters)
{
var currentPath = string.Concat(path, '.', parameter.Id.ToString());
switch (parameter.Id)
{
case 1:
result.Image = Image.Parse(parameter.Children, currentPath);
break;
default:
throw new InvalidParameterException(parameter, path);
}
}
return result;
}
}
}

View File

@ -1,64 +1,34 @@
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using NLog;
using Newtonsoft.Json;
using WatchFace.JsonConverters;
using WatchFace.Models;
using WatchFace.Utils;
namespace WatchFace.Elements.BasicElements
{
public class CircleScale
{
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
[RawParameter(Id = 1)]
public long CenterX { get; set; }
[RawParameter(Id = 2)]
public long CenterY { get; set; }
[RawParameter(Id = 3)]
public long RadiusX { get; set; }
[RawParameter(Id = 4)]
public long RadiusY { get; set; }
[RawParameter(Id = 5)]
public long StartAngle { get; set; }
[RawParameter(Id = 6)]
public long EndAngle { get; set; }
[RawParameter(Id = 7)]
public long Width { get; set; }
[JsonConverter(typeof(HexStringJsonConverter))]
[RawParameter(Id = 8)]
public long Color { get; set; }
public static CircleScale Parse(List<Parameter> descriptor, string path)
{
Logger.Trace("Reading {0}", path);
if (descriptor == null)
throw new ArgumentNullException(nameof(descriptor));
var result = new CircleScale();
foreach (var parameter in descriptor)
switch (parameter.Id)
{
case 1:
result.CenterX = parameter.Value;
break;
case 2:
result.CenterY = parameter.Value;
break;
case 3:
result.RadiusX = parameter.Value;
break;
case 4:
result.RadiusY = parameter.Value;
break;
case 5:
result.StartAngle = parameter.Value;
break;
case 6:
result.EndAngle = parameter.Value;
break;
case 7:
result.Width = parameter.Value;
break;
case 8:
result.Color = parameter.Value;
break;
default:
throw new InvalidParameterException(parameter, path);
}
return result;
}
}
}

View File

@ -1,57 +1,26 @@
using System;
using System.Collections.Generic;
using System.Collections.Generic;
using Newtonsoft.Json;
using NLog;
using WatchFace.JsonConverters;
using WatchFace.Models;
using WatchFace.Utils;
namespace WatchFace.Elements.BasicElements
{
public class ClockHand
{
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
[RawParameter(Id = 1)]
public long Unknown1 { get; set; }
[JsonConverter(typeof(HexStringJsonConverter))]
[RawParameter(Id = 2)]
public long Color { get; set; }
[RawParameter(Id = 3)]
public Coordinates Center { get; set; }
[RawParameter(Id = 4)]
public List<Coordinates> Shape { get; set; }
[RawParameter(Id = 5)]
public Image CenterImage { get; set; }
public static ClockHand Parse(List<Parameter> descriptor, string path)
{
Logger.Trace("Reading {0}", path);
if (descriptor == null)
throw new ArgumentNullException(nameof(descriptor));
var result = new ClockHand {Shape = new List<Coordinates>()};
foreach (var parameter in descriptor)
{
var currentPath = string.Concat(path, '.', parameter.Id.ToString());
switch (parameter.Id)
{
case 1:
result.Unknown1 = parameter.Value;
break;
case 2:
result.Color = parameter.Value;
break;
case 3:
result.Center = Coordinates.Parse(parameter.Children, currentPath);
break;
case 4:
result.Shape.Add(Coordinates.Parse(parameter.Children, currentPath));
break;
case 5:
result.CenterImage = Image.Parse(parameter.Children, currentPath);
break;
default:
throw new InvalidParameterException(parameter, path);
}
}
return result;
}
}
}

View File

@ -1,36 +1,13 @@
using System;
using System.Collections.Generic;
using NLog;
using WatchFace.Models;
using WatchFace.Utils;
namespace WatchFace.Elements.BasicElements
{
public class Coordinates
{
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
[RawParameter(Id = 1)]
public long X { get; set; }
[RawParameter(Id = 2)]
public long Y { get; set; }
public static Coordinates Parse(List<Parameter> descriptor, string path)
{
Logger.Trace("Reading {0}", path);
if (descriptor == null)
throw new ArgumentNullException(nameof(descriptor));
var result = new Coordinates();
foreach (var parameter in descriptor)
switch (parameter.Id)
{
case 1:
result.X = parameter.Value;
break;
case 2:
result.Y = parameter.Value;
break;
default:
throw new InvalidParameterException(parameter, path);
}
return result;
}
}
}

View File

@ -1,40 +1,16 @@
using System;
using System.Collections.Generic;
using NLog;
using WatchFace.Models;
using WatchFace.Utils;
namespace WatchFace.Elements.BasicElements
{
public class Image
{
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
[RawParameter(Id = 1)]
public long X { get; set; }
[RawParameter(Id = 2)]
public long Y { get; set; }
[RawParameter(Id = 3)]
public long ImageIndex { get; set; }
public static Image Parse(List<Parameter> descriptor, string path)
{
Logger.Trace("Reading {0}", path);
if (descriptor == null)
throw new ArgumentNullException(nameof(descriptor));
var result = new Image();
foreach (var parameter in descriptor)
switch (parameter.Id)
{
case 1:
result.X = parameter.Value;
break;
case 2:
result.Y = parameter.Value;
break;
case 3:
result.ImageIndex = parameter.Value;
break;
default:
throw new InvalidParameterException(parameter, path);
}
return result;
}
}
}

View File

@ -1,44 +1,19 @@
using System;
using System.Collections.Generic;
using NLog;
using WatchFace.Models;
using WatchFace.Utils;
namespace WatchFace.Elements.BasicElements
{
public class ImageSet
{
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
[RawParameter(Id = 1)]
public long X { get; set; }
[RawParameter(Id = 2)]
public long Y { get; set; }
[RawParameter(Id = 3)]
public long ImageIndex { get; set; }
[RawParameter(Id = 4)]
public long ImagesCount { get; set; }
public static ImageSet Parse(List<Parameter> descriptor, string path)
{
Logger.Trace("Reading {0}", path);
if (descriptor == null)
throw new ArgumentNullException(nameof(descriptor));
var result = new ImageSet();
foreach (var parameter in descriptor)
switch (parameter.Id)
{
case 1:
result.X = parameter.Value;
break;
case 2:
result.Y = parameter.Value;
break;
case 3:
result.ImageIndex = parameter.Value;
break;
case 4:
result.ImagesCount = parameter.Value;
break;
default:
throw new InvalidParameterException(parameter, path);
}
return result;
}
}
}

View File

@ -1,60 +1,31 @@
using System;
using System.Collections.Generic;
using NLog;
using WatchFace.Models;
using WatchFace.Utils;
namespace WatchFace.Elements.BasicElements
{
public class Number
{
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
[RawParameter(Id = 1)]
public long TopLeftX { get; set; }
[RawParameter(Id = 2)]
public long TopLeftY { get; set; }
[RawParameter(Id = 3)]
public long BottomRightX { get; set; }
[RawParameter(Id = 4)]
public long BottomRightY { get; set; }
[RawParameter(Id = 5)]
public long Alignment { get; set; }
[RawParameter(Id = 6)]
public long Unknown6 { get; set; }
[RawParameter(Id = 7)]
public long ImageIndex { get; set; }
[RawParameter(Id = 8)]
public long ImagesCount { get; set; }
public static Number Parse(List<Parameter> descriptor, string path)
{
Logger.Trace("Reading {0}", path);
if (descriptor == null)
throw new ArgumentNullException(nameof(descriptor));
var result = new Number();
foreach (var parameter in descriptor)
switch (parameter.Id)
{
case 1:
result.TopLeftX = parameter.Value;
break;
case 2:
result.TopLeftY = parameter.Value;
break;
case 3:
result.BottomRightX = parameter.Value;
break;
case 4:
result.BottomRightY = parameter.Value;
break;
case 5:
result.Alignment = parameter.Value;
break;
case 6:
result.Unknown6 = parameter.Value;
break;
case 7:
result.ImageIndex = parameter.Value;
break;
case 8:
result.ImagesCount = parameter.Value;
break;
default:
throw new InvalidParameterException(parameter, path);
}
return result;
}
}
}

View File

@ -1,39 +1,14 @@
using System;
using System.Collections.Generic;
using NLog;
using WatchFace.Models;
using System.Collections.Generic;
using WatchFace.Utils;
namespace WatchFace.Elements.BasicElements
{
public class Scale
{
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
[RawParameter(Id = 1)]
public long StartImageIndex { get; set; }
[RawParameter(Id = 2)]
public List<Coordinates> Segments { get; set; }
public static Scale Parse(List<Parameter> descriptor, string path)
{
Logger.Trace("Reading {0}", path);
if (descriptor == null)
throw new ArgumentNullException(nameof(descriptor));
var result = new Scale {Segments = new List<Coordinates>()};
foreach (var parameter in descriptor)
{
var currentPath = string.Concat(path, '.', parameter.Id.ToString());
switch (parameter.Id)
{
case 1:
result.StartImageIndex = parameter.Value;
break;
case 2:
result.Segments.Add(Coordinates.Parse(parameter.Children, currentPath));
break;
default:
throw new InvalidParameterException(parameter, path);
}
}
return result;
}
}
}

View File

@ -1,39 +0,0 @@
using System;
using System.Collections.Generic;
using NLog;
using WatchFace.Models;
namespace WatchFace.Elements.BasicElements
{
public class TwoDigits
{
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
public ImageSet Tens { get; set; }
public ImageSet Ones { get; set; }
public static TwoDigits Parse(List<Parameter> descriptor, string path)
{
Logger.Trace("Reading {0}", path);
if (descriptor == null)
throw new ArgumentNullException(nameof(descriptor));
var result = new TwoDigits();
foreach (var parameter in descriptor)
{
var currentPath = string.Concat(path, '.', parameter.Id.ToString());
switch (parameter.Id)
{
case 1:
result.Tens = ImageSet.Parse(parameter.Children, currentPath);
break;
case 2:
result.Ones = ImageSet.Parse(parameter.Children, currentPath);
break;
default:
throw new InvalidParameterException(parameter, path);
}
}
return result;
}
}
}

View File

@ -1,44 +1,17 @@
using System;
using System.Collections.Generic;
using NLog;
using WatchFace.Elements.BasicElements;
using WatchFace.Models;
using WatchFace.Elements.BasicElements;
using WatchFace.Utils;
namespace WatchFace.Elements
{
public class Battery
{
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
[RawParameter(Id = 1)]
public Number Text { get; set; }
[RawParameter(Id = 2)]
public ImageSet Icon { get; set; }
[RawParameter(Id = 3)]
public Scale Scale { get; set; }
public static Battery Parse(List<Parameter> descriptor, string path)
{
Logger.Trace("Reading {0}", path);
if (descriptor == null)
throw new ArgumentNullException(nameof(descriptor));
var result = new Battery();
foreach (var parameter in descriptor)
{
var currentPath = string.Concat(path, '.', parameter.Id.ToString());
switch (parameter.Id)
{
case 1:
result.Text = Number.Parse(parameter.Children, currentPath);
break;
case 2:
result.Icon = ImageSet.Parse(parameter.Children, currentPath);
break;
case 3:
result.Scale = Scale.Parse(parameter.Children, currentPath);
break;
default:
throw new InvalidParameterException(parameter, path);
}
}
return result;
}
}
}

View File

@ -1,41 +1,15 @@
using System;
using System.Collections.Generic;
using NLog;
using WatchFace.Elements.BasicElements;
using WatchFace.Elements.BasicElements;
using WatchFace.Elements.DateElements;
using WatchFace.Models;
using WatchFace.Utils;
namespace WatchFace.Elements
{
public class Date
{
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
[RawParameter(Id = 1)]
public MonthAndDay MonthAndDay { get; set; }
[RawParameter(Id = 2)]
public ImageSet WeekDay { get; set; }
public static Date Parse(List<Parameter> descriptor, string path)
{
Logger.Trace("Reading {0}", path);
if (descriptor == null)
throw new ArgumentNullException(nameof(descriptor));
var result = new Date();
foreach (var parameter in descriptor)
{
var currentPath = string.Concat(path, '.', parameter.Id.ToString());
switch (parameter.Id)
{
case 1:
result.MonthAndDay = MonthAndDay.Parse(parameter.Children, currentPath);
break;
case 2:
result.WeekDay = ImageSet.Parse(parameter.Children, currentPath);
break;
default:
throw new InvalidParameterException(parameter, path);
}
}
return result;
}
}
}

View File

@ -1,47 +1,19 @@
using System;
using System.Collections.Generic;
using NLog;
using WatchFace.Models;
using WatchFace.Utils;
namespace WatchFace.Elements.DateElements
{
public class MonthAndDay
{
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
[RawParameter(Id = 1)]
public SeparateMonthAndDay Separate { get; set; }
[RawParameter(Id = 2)]
public OneLineMonthAndDay OneLine { get; set; }
[RawParameter(Id = 3)]
public long Unknown3 { get; set; }
[RawParameter(Id = 4)]
public long Unknown4 { get; set; }
public static MonthAndDay Parse(List<Parameter> descriptor, string path)
{
Logger.Trace("Reading {0}", path);
if (descriptor == null)
throw new ArgumentNullException(nameof(descriptor));
var result = new MonthAndDay();
foreach (var parameter in descriptor)
{
var currentPath = string.Concat(path, '.', parameter.Id.ToString());
switch (parameter.Id)
{
case 1:
result.Separate = SeparateMonthAndDay.Parse(parameter.Children, currentPath);
break;
case 2:
result.OneLine = OneLineMonthAndDay.Parse(parameter.Children, currentPath);
break;
case 3:
result.Unknown3 = parameter.Value;
break;
case 4:
result.Unknown4 = parameter.Value;
break;
default:
throw new InvalidParameterException(parameter, path);
}
}
return result;
}
}
}

View File

@ -1,40 +1,14 @@
using System;
using System.Collections.Generic;
using NLog;
using WatchFace.Elements.BasicElements;
using WatchFace.Models;
using WatchFace.Elements.BasicElements;
using WatchFace.Utils;
namespace WatchFace.Elements.DateElements
{
public class OneLineMonthAndDay
{
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
[RawParameter(Id = 1)]
public Number Number { get; set; }
[RawParameter(Id = 2)]
public long DelimiterImageIndex { get; set; }
public static OneLineMonthAndDay Parse(List<Parameter> descriptor, string path)
{
Logger.Trace("Reading {0}", path);
if (descriptor == null)
throw new ArgumentNullException(nameof(descriptor));
var result = new OneLineMonthAndDay();
foreach (var parameter in descriptor)
{
var currentPath = string.Concat(path, '.', parameter.Id.ToString());
switch (parameter.Id)
{
case 1:
result.Number = Number.Parse(parameter.Children, currentPath);
break;
case 2:
result.DelimiterImageIndex = parameter.Value;
break;
default:
throw new InvalidParameterException(parameter, path);
}
}
return result;
}
}
}

View File

@ -1,40 +1,14 @@
using System;
using System.Collections.Generic;
using NLog;
using WatchFace.Elements.BasicElements;
using WatchFace.Models;
using WatchFace.Elements.BasicElements;
using WatchFace.Utils;
namespace WatchFace.Elements.DateElements
{
public class SeparateMonthAndDay
{
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
[RawParameter(Id = 1)]
public Number Month { get; set; }
[RawParameter(Id = 3)]
public Number Day { get; set; }
public static SeparateMonthAndDay Parse(List<Parameter> descriptor, string path)
{
Logger.Trace("Reading {0}", path);
if (descriptor == null)
throw new ArgumentNullException(nameof(descriptor));
var result = new SeparateMonthAndDay();
foreach (var parameter in descriptor)
{
var currentPath = string.Concat(path, '.', parameter.Id.ToString());
switch (parameter.Id)
{
case 1:
result.Month = Number.Parse(parameter.Children, currentPath);
break;
case 3:
result.Day = Number.Parse(parameter.Children, currentPath);
break;
default:
throw new InvalidParameterException(parameter, path);
}
}
return result;
}
}
}

View File

@ -1,40 +1,14 @@
using System;
using System.Collections.Generic;
using NLog;
using WatchFace.Elements.BasicElements;
using WatchFace.Models;
using WatchFace.Elements.BasicElements;
using WatchFace.Utils;
namespace WatchFace.Elements
{
public class Scales
{
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
[RawParameter(Id = 2)]
public Scale LinearSteps { get; set; }
[RawParameter(Id = 3)]
public CircleScale CircleSteps { get; set; }
public static Scales Parse(List<Parameter> descriptor, string path)
{
Logger.Trace("Reading {0}", path);
if (descriptor == null)
throw new ArgumentNullException(nameof(descriptor));
var result = new Scales();
foreach (var parameter in descriptor)
{
var currentPath = string.Concat(path, '.', parameter.Id.ToString());
switch (parameter.Id)
{
case 2:
result.LinearSteps = Scale.Parse(parameter.Children, currentPath);
break;
case 3:
result.CircleSteps = CircleScale.Parse(parameter.Children, currentPath);
break;
default:
throw new InvalidParameterException(parameter, path);
}
}
return result;
}
}
}

View File

@ -1,48 +1,20 @@
using System;
using System.Collections.Generic;
using NLog;
using WatchFace.Elements.StatusElements;
using WatchFace.Models;
using WatchFace.Elements.StatusElements;
using WatchFace.Utils;
namespace WatchFace.Elements
{
public class Status
{
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
[RawParameter(Id = 1)]
public Switch Bluetooth { get; set; }
[RawParameter(Id = 2)]
public Flag Alarm { get; set; }
[RawParameter(Id = 3)]
public Flag Lock { get; set; }
[RawParameter(Id = 4)]
public Flag DoNotDisturb { get; set; }
public static Status Parse(List<Parameter> descriptor, string path)
{
Logger.Trace("Reading {0}", path);
if (descriptor == null)
throw new ArgumentNullException(nameof(descriptor));
var result = new Status();
foreach (var parameter in descriptor)
{
var currentPath = string.Concat(path, '.', parameter.Id.ToString());
switch (parameter.Id)
{
case 1:
result.Bluetooth = Switch.Parse(parameter.Children, currentPath);
break;
case 2:
result.Alarm = Flag.Parse(parameter.Children, currentPath);
break;
case 3:
result.Lock = Flag.Parse(parameter.Children, currentPath);
break;
case 4:
result.DoNotDisturb = Flag.Parse(parameter.Children, currentPath);
break;
default:
throw new InvalidParameterException(parameter, path);
}
}
return result;
}
}
}

View File

@ -1,40 +1,14 @@
using System;
using System.Collections.Generic;
using NLog;
using WatchFace.Elements.BasicElements;
using WatchFace.Models;
using WatchFace.Elements.BasicElements;
using WatchFace.Utils;
namespace WatchFace.Elements.StatusElements
{
public class Flag
{
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
[RawParameter(Id = 1)]
public Coordinates Coordinates { get; set; }
[RawParameter(Id = 2)]
public long ImageIndex { get; set; }
public static Flag Parse(List<Parameter> descriptor, string path)
{
Logger.Trace("Reading {0}", path);
if (descriptor == null)
throw new ArgumentNullException(nameof(descriptor));
var result = new Flag();
foreach (var parameter in descriptor)
{
var currentPath = string.Concat(path, '.', parameter.Id.ToString());
switch (parameter.Id)
{
case 1:
result.Coordinates = Coordinates.Parse(parameter.Children, currentPath);
break;
case 2:
result.ImageIndex = parameter.Value;
break;
default:
throw new InvalidParameterException(parameter, path);
}
}
return result;
}
}
}

View File

@ -1,44 +1,17 @@
using System;
using System.Collections.Generic;
using NLog;
using WatchFace.Elements.BasicElements;
using WatchFace.Models;
using WatchFace.Elements.BasicElements;
using WatchFace.Utils;
namespace WatchFace.Elements.StatusElements
{
public class Switch
{
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
[RawParameter(Id = 1)]
public Coordinates Coordinates { get; set; }
[RawParameter(Id = 2)]
public long ImageIndexOn { get; set; }
[RawParameter(Id = 3)]
public long ImageIndexOff { get; set; }
public static Switch Parse(List<Parameter> descriptor, string path)
{
Logger.Trace("Reading {0}", path);
if (descriptor == null)
throw new ArgumentNullException(nameof(descriptor));
var result = new Switch();
foreach (var parameter in descriptor)
{
var currentPath = string.Concat(path, '.', parameter.Id.ToString());
switch (parameter.Id)
{
case 1:
result.Coordinates = Coordinates.Parse(parameter.Children, currentPath);
break;
case 2:
result.ImageIndexOn = parameter.Value;
break;
case 3:
result.ImageIndexOff = parameter.Value;
break;
default:
throw new InvalidParameterException(parameter, path);
}
}
return result;
}
}
}

View File

@ -1,49 +1,21 @@
using System;
using System.Collections.Generic;
using NLog;
using WatchFace.Elements.BasicElements;
using WatchFace.Elements.BasicElements;
using WatchFace.Elements.TimeElements;
using WatchFace.Models;
using WatchFace.Utils;
namespace WatchFace.Elements
{
public class Time
{
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
[RawParameter(Id = 1)]
public TwoDigits Hours { get; set; }
[RawParameter(Id = 2)]
public TwoDigits Minutes { get; set; }
[RawParameter(Id = 3)]
public TwoDigits Seconds { get; set; }
[RawParameter(Id = 4)]
public AmPm AmPm { get; set; }
public static Time Parse(List<Parameter> descriptor, string path)
{
Logger.Trace("Reading {0}", path);
if (descriptor == null)
throw new ArgumentNullException(nameof(descriptor));
var result = new Time();
foreach (var parameter in descriptor)
{
var currentPath = string.Concat(path, '.', parameter.Id.ToString());
switch (parameter.Id)
{
case 1:
result.Hours = TwoDigits.Parse(parameter.Children, currentPath);
break;
case 2:
result.Minutes = TwoDigits.Parse(parameter.Children, currentPath);
break;
case 3:
result.Seconds = TwoDigits.Parse(parameter.Children, currentPath);
break;
case 4:
result.AmPm = AmPm.Parse(parameter.Children, currentPath);
break;
default:
throw new InvalidParameterException(parameter, path);
}
}
return result;
}
}
}

View File

@ -1,44 +1,19 @@
using System;
using System.Collections.Generic;
using NLog;
using WatchFace.Models;
using WatchFace.Utils;
namespace WatchFace.Elements.TimeElements
{
public class AmPm
{
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
[RawParameter(Id = 4)]
public long ImageIndexPm { get; set; }
[RawParameter(Id = 3)]
public long ImageIndexAm { get; set; }
[RawParameter(Id = 1)]
public long X { get; set; }
[RawParameter(Id = 2)]
public long Y { get; set; }
public static AmPm Parse(List<Parameter> descriptor, string path)
{
Logger.Trace("Reading {0}", path);
if (descriptor == null)
throw new ArgumentNullException(nameof(descriptor));
var result = new AmPm();
foreach (var parameter in descriptor)
switch (parameter.Id)
{
case 1:
result.X = parameter.Value;
break;
case 2:
result.Y = parameter.Value;
break;
case 3:
result.ImageIndexAm = parameter.Value;
break;
case 4:
result.ImageIndexPm = parameter.Value;
break;
default:
throw new InvalidParameterException(parameter, path);
}
return result;
}
}
}

View File

@ -0,0 +1,13 @@
using WatchFace.Utils;
namespace WatchFace.Elements.BasicElements
{
public class TwoDigits
{
[RawParameter(Id = 1)]
public ImageSet Tens { get; set; }
[RawParameter(Id = 2)]
public ImageSet Ones { get; set; }
}
}

View File

@ -1,44 +1,17 @@
using System;
using System.Collections.Generic;
using NLog;
using WatchFace.Elements.WeatherElements;
using WatchFace.Models;
using WatchFace.Elements.WeatherElements;
using WatchFace.Utils;
namespace WatchFace.Elements
{
public class Weather
{
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
[RawParameter(Id = 1)]
public WeatherIcon Icon { get; set; }
[RawParameter(Id = 2)]
public Temperature Temperature { get; set; }
[RawParameter(Id = 3)]
public AirPollution AirPollution { get; set; }
public static Weather Parse(List<Parameter> descriptor, string path)
{
Logger.Trace("Reading {0}", path);
if (descriptor == null)
throw new ArgumentNullException(nameof(descriptor));
var result = new Weather();
foreach (var parameter in descriptor)
{
var currentPath = string.Concat(path, '.', parameter.Id.ToString());
switch (parameter.Id)
{
case 1:
result.Icon = WeatherIcon.Parse(parameter.Children, currentPath);
break;
case 2:
result.Temperature = Temperature.Parse(parameter.Children, currentPath);
break;
case 3:
result.AirPollution = AirPollution.Parse(parameter.Children, currentPath);
break;
default:
throw new InvalidParameterException(parameter, path);
}
}
return result;
}
}
}

View File

@ -1,36 +1,11 @@
using System;
using System.Collections.Generic;
using NLog;
using WatchFace.Elements.BasicElements;
using WatchFace.Models;
using WatchFace.Elements.BasicElements;
using WatchFace.Utils;
namespace WatchFace.Elements.WeatherElements
{
public class AirPollution
{
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
[RawParameter(Id = 2)]
public ImageSet Icon { get; set; }
public static AirPollution Parse(List<Parameter> descriptor, string path)
{
Logger.Trace("Reading {0}", path);
if (descriptor == null)
throw new ArgumentNullException(nameof(descriptor));
var result = new AirPollution();
foreach (var parameter in descriptor)
{
var currentPath = string.Concat(path, '.', parameter.Id.ToString());
switch (parameter.Id)
{
case 2:
result.Icon = ImageSet.Parse(parameter.Children, currentPath);
break;
default:
throw new InvalidParameterException(parameter, path);
}
}
return result;
}
}
}

View File

@ -1,52 +1,23 @@
using System;
using System.Collections.Generic;
using NLog;
using WatchFace.Elements.BasicElements;
using WatchFace.Models;
using WatchFace.Elements.BasicElements;
using WatchFace.Utils;
namespace WatchFace.Elements.WeatherElements
{
public class OneLineTemperature
{
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
[RawParameter(Id = 1)]
public Number Number { get; set; }
[RawParameter(Id = 2)]
public long MinusSignImageIndex { get; set; }
[RawParameter(Id = 3)]
public long DelimiterImageIndex { get; set; }
[RawParameter(Id = 4)]
public long Unknown4 { get; set; }
[RawParameter(Id = 5)]
public long DegreesImageIndex { get; set; }
public static OneLineTemperature Parse(List<Parameter> descriptor, string path)
{
Logger.Trace("Reading {0}", path);
if (descriptor == null)
throw new ArgumentNullException(nameof(descriptor));
var result = new OneLineTemperature();
foreach (var parameter in descriptor)
{
var currentPath = string.Concat(path, '.', parameter.Id.ToString());
switch (parameter.Id)
{
case 1:
result.Number = Number.Parse(parameter.Children, currentPath);
break;
case 2:
result.MinusSignImageIndex = parameter.Value;
break;
case 3:
result.DelimiterImageIndex = parameter.Value;
break;
case 4:
result.Unknown4 = parameter.Value;
break;
case 5:
result.DegreesImageIndex = parameter.Value;
break;
default:
throw new InvalidParameterException(parameter, path);
}
}
return result;
}
}
}

View File

@ -1,48 +1,20 @@
using System;
using System.Collections.Generic;
using NLog;
using WatchFace.Elements.BasicElements;
using WatchFace.Models;
using WatchFace.Elements.BasicElements;
using WatchFace.Utils;
namespace WatchFace.Elements.WeatherElements
{
public class SeparateTemperature
{
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
[RawParameter(Id = 1)]
public TemperatureNumber Day { get; set; }
[RawParameter(Id = 2)]
public TemperatureNumber Night { get; set; }
[RawParameter(Id = 3)]
public Coordinates Unknown3 { get; set; }
[RawParameter(Id = 4)]
public Coordinates Unknown4 { get; set; }
public static SeparateTemperature Parse(List<Parameter> descriptor, string path)
{
Logger.Trace("Reading {0}", path);
if (descriptor == null)
throw new ArgumentNullException(nameof(descriptor));
var result = new SeparateTemperature();
foreach (var parameter in descriptor)
{
var currentPath = string.Concat(path, '.', parameter.Id.ToString());
switch (parameter.Id)
{
case 1:
result.Day = TemperatureNumber.Parse(parameter.Children, currentPath);
break;
case 2:
result.Night = TemperatureNumber.Parse(parameter.Children, currentPath);
break;
case 3:
result.Unknown3 = Coordinates.Parse(parameter.Children, currentPath);
break;
case 4:
result.Unknown4 = Coordinates.Parse(parameter.Children, currentPath);
break;
default:
throw new InvalidParameterException(parameter, path);
}
}
return result;
}
}
}

View File

@ -1,39 +1,13 @@
using System;
using System.Collections.Generic;
using NLog;
using WatchFace.Models;
using WatchFace.Utils;
namespace WatchFace.Elements.WeatherElements
{
public class Temperature
{
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
[RawParameter(Id = 1)]
public TemperatureNumber Current { get; set; }
[RawParameter(Id = 2)]
public TodayTemperature Today { get; set; }
public static Temperature Parse(List<Parameter> descriptor, string path)
{
Logger.Trace("Reading {0}", path);
if (descriptor == null)
throw new ArgumentNullException(nameof(descriptor));
var result = new Temperature();
foreach (var parameter in descriptor)
{
var currentPath = string.Concat(path, '.', parameter.Id.ToString());
switch (parameter.Id)
{
case 1:
result.Current = TemperatureNumber.Parse(parameter.Children, currentPath);
break;
case 2:
result.Today = TodayTemperature.Parse(parameter.Children, currentPath);
break;
default:
throw new InvalidParameterException(parameter, path);
}
}
return result;
}
}
}

View File

@ -1,44 +1,17 @@
using System;
using System.Collections.Generic;
using NLog;
using WatchFace.Elements.BasicElements;
using WatchFace.Models;
using WatchFace.Elements.BasicElements;
using WatchFace.Utils;
namespace WatchFace.Elements.WeatherElements
{
public class TemperatureNumber
{
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
[RawParameter(Id = 1)]
public Number Number { get; set; }
[RawParameter(Id = 2)]
public long MinusImageIndex { get; set; }
[RawParameter(Id = 3)]
public long DegreesImageIndex { get; set; }
public static TemperatureNumber Parse(List<Parameter> descriptor, string path)
{
Logger.Trace("Reading {0}", path);
if (descriptor == null)
throw new ArgumentNullException(nameof(descriptor));
var result = new TemperatureNumber();
foreach (var parameter in descriptor)
{
var currentPath = string.Concat(path, '.', parameter.Id.ToString());
switch (parameter.Id)
{
case 1:
result.Number = Number.Parse(parameter.Children, currentPath);
break;
case 2:
result.MinusImageIndex = parameter.Value;
break;
case 3:
result.DegreesImageIndex = parameter.Value;
break;
default:
throw new InvalidParameterException(parameter, path);
}
}
return result;
}
}
}

View File

@ -1,39 +1,13 @@
using System;
using System.Collections.Generic;
using NLog;
using WatchFace.Models;
using WatchFace.Utils;
namespace WatchFace.Elements.WeatherElements
{
public class TodayTemperature
{
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
[RawParameter(Id = 1)]
public SeparateTemperature Separate { get; set; }
[RawParameter(Id = 2)]
public OneLineTemperature OneLine { get; set; }
public static TodayTemperature Parse(List<Parameter> descriptor, string path)
{
Logger.Trace("Reading {0}", path);
if (descriptor == null)
throw new ArgumentNullException(nameof(descriptor));
var result = new TodayTemperature();
foreach (var parameter in descriptor)
{
var currentPath = string.Concat(path, '.', parameter.Id.ToString());
switch (parameter.Id)
{
case 1:
result.Separate = SeparateTemperature.Parse(parameter.Children, currentPath);
break;
case 2:
result.OneLine = OneLineTemperature.Parse(parameter.Children, currentPath);
break;
default:
throw new InvalidParameterException(parameter, path);
}
}
return result;
}
}
}

View File

@ -1,44 +1,17 @@
using System;
using System.Collections.Generic;
using NLog;
using WatchFace.Elements.BasicElements;
using WatchFace.Models;
using WatchFace.Elements.BasicElements;
using WatchFace.Utils;
namespace WatchFace.Elements.WeatherElements
{
public class WeatherIcon
{
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
[RawParameter(Id = 1)]
public Coordinates Coordinates { get; set; }
[RawParameter(Id = 3)]
public Coordinates Unknown3 { get; set; }
[RawParameter(Id = 4)]
public Coordinates Unknown4 { get; set; }
public static WeatherIcon Parse(List<Parameter> descriptor, string path)
{
Logger.Trace("Reading {0}", path);
if (descriptor == null)
throw new ArgumentNullException(nameof(descriptor));
var result = new WeatherIcon();
foreach (var parameter in descriptor)
{
var currentPath = string.Concat(path, '.', parameter.Id.ToString());
switch (parameter.Id)
{
case 1:
result.Coordinates = Coordinates.Parse(parameter.Children, currentPath);
break;
case 3:
result.Unknown3 = Coordinates.Parse(parameter.Children, currentPath);
break;
case 4:
result.Unknown4 = Coordinates.Parse(parameter.Children, currentPath);
break;
default:
throw new InvalidParameterException(parameter, path);
}
}
return result;
}
}
}

View File

@ -2,6 +2,7 @@
using System.IO;
using System.Text;
using NLog;
using NLog.Internal;
namespace WatchFace.Models
{
@ -24,7 +25,54 @@ namespace WatchFace.Models
public byte Id { get; }
public long Value { get; }
public List<Parameter> Children { get; }
public bool IsComplex => Children != null;
public bool HasChildren => Children != null;
public long Write(Stream stream, int traceOffset = 0)
{
var size = (long) 0;
var flags = HasChildren ? ParameterFlags.HasChildren : 0;
var rawId = (byte) ((Id << 3) + flags);
stream.WriteByte(rawId);
size += 1;
if (HasChildren)
{
size += WriteList(stream, traceOffset +1);
Logger.Trace(() => TraceWithOffset($"{Id} ({rawId:X2}): {size} bytes", traceOffset));
return size;
}
size += WriteValue(stream, Value, traceOffset);
Logger.Trace(() => TraceWithOffset($"{Id} ({rawId:X2}): {Value} ({Value:X2})", traceOffset));
return size;
}
public long WriteList(Stream stream, int traceOffset)
{
var temporaryStream = new MemoryStream();
foreach (var parameter in Children) parameter.Write(temporaryStream, traceOffset);
var size = WriteValue(stream, temporaryStream.Length, traceOffset);
temporaryStream.Seek(0, SeekOrigin.Begin);
temporaryStream.Copy(stream);
size += temporaryStream.Length;
return size;
}
public long WriteValue(Stream stream, long value, int traceOffset)
{
var size = 0;
byte currentByte;
while (value >= 0x80)
{
currentByte = (byte) ((value & 0x7f) | 0x80);
stream.WriteByte(currentByte);
size += 1;
value = value >> 7;
}
currentByte = (byte) (value & 0x7f);
stream.WriteByte(currentByte);
size += 1;
return size;
}
public static List<Parameter> ReadList(Stream stream, int traceOffset = 0)
{
@ -44,9 +92,9 @@ namespace WatchFace.Models
var flags = (ParameterFlags) (rawId & 0x7);
var value = ReadValue(fileStream);
if (flags.HasFlag(ParameterFlags.hasChildren))
if (flags.HasFlag(ParameterFlags.HasChildren))
{
Logger.Trace(()=> TraceWithOffset($"{id} ({rawId:X2}): {value} bytes", traceOffset));
Logger.Trace(() => TraceWithOffset($"{id} ({rawId:X2}): {value} bytes", traceOffset));
var buffer = new byte[value];
fileStream.Read(buffer, 0, (int) value);
var stream = new MemoryStream(buffer);
@ -54,7 +102,7 @@ namespace WatchFace.Models
var list = ReadList(stream, traceOffset + 1);
return new Parameter(id, list);
}
Logger.Trace(()=> TraceWithOffset($"{id} ({rawId:X2}): {value} ({value:X2})", traceOffset));
Logger.Trace(() => TraceWithOffset($"{id} ({rawId:X2}): {value} ({value:X2})", traceOffset));
return new Parameter(id, value);
}

View File

@ -6,7 +6,7 @@ namespace WatchFace.Models
public enum ParameterFlags
{
Unknown = 1,
hasChildren = 2,
HasChildren = 2,
Unknown2 = 4
}
}

View File

@ -0,0 +1,68 @@
using System;
using System.IO;
namespace WatchFace.Utils
{
public class BitWriter
{
private readonly byte[] _masks = {128, 192, 224, 240, 248, 252, 254, 255};
private readonly Stream _stream;
private int _currentBit;
private byte _currentByte;
public BitWriter(Stream stream)
{
_stream = stream;
}
public void Write(byte value)
{
WriteBits(value, 8);
}
public void Write(bool value)
{
WriteBits((uint) (value ? 1 : 0), 1);
}
public void WriteBits(string binaryString)
{
var length = binaryString.Length;
var data = Convert.ToUInt32(binaryString, 2);
WriteBits(data, length);
}
public void WriteBits(ulong data, int length)
{
while (length > 0)
{
var freeBits = 8 - _currentBit;
var dataLength = Math.Min(freeBits, length);
ulong currentByteData;
if (length > 8)
currentByteData = data >> (length - 8);
else
currentByteData = data << (8 - length);
var appendData = (currentByteData & _masks[dataLength - 1]) >> _currentBit;
_currentByte = (byte) (_currentByte | appendData);
_currentBit += dataLength;
length -= dataLength;
if (_currentBit != 8) continue;
_stream.WriteByte(_currentByte);
_currentBit = 0;
_currentByte = 0;
}
}
public void Flush()
{
if (_currentBit > 0)
_stream.WriteByte(_currentByte);
}
}
}

View File

@ -0,0 +1,101 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using NLog;
using WatchFace.Models;
namespace WatchFace.Utils
{
public class ParametersConverter
{
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
public static List<Parameter> Build<T>(T serializable)
{
var result = new List<Parameter>();
foreach (var kv in SortedPropertiesDictionary<T>())
{
var id = kv.Key;
var propertyInfo = kv.Value;
var propertyType = propertyInfo.PropertyType;
dynamic propertyValue = propertyInfo.GetValue(serializable, null);
if (propertyType == typeof(long))
result.Add(new Parameter(id, (long) propertyValue));
else if (propertyType.IsGenericType && propertyType.GetGenericTypeDefinition() == typeof(List<>))
throw new NotImplementedException();
else
result.Add(new Parameter(id, Build(propertyValue)));
}
return result;
}
public static T Parse<T>(List<Parameter> descriptor, string path = "") where T : new()
{
var properties = SortedPropertiesDictionary<T>();
var result = new T();
Logger.Trace("Reading {0} {1}", typeof(T).Name, path);
foreach (var parameter in descriptor)
{
var currentPath = string.Concat(path, '.', parameter.Id.ToString());
var propertyInfo = properties[parameter.Id];
if (propertyInfo == null)
throw new InvalidParameterException(parameter, path);
var propertyType = propertyInfo.PropertyType;
if (propertyType == typeof(long))
{
propertyInfo.SetValue(result, parameter.Value);
}
else if (propertyType.IsGenericType && propertyType.GetGenericTypeDefinition() == typeof(List<>))
{
dynamic propertyValue = propertyInfo.GetValue(result);
if (propertyValue == null)
{
propertyValue = Activator.CreateInstance(propertyType);
propertyInfo.SetValue(result, propertyValue);
}
var method = typeof(ParametersConverter).GetMethod(nameof(Parse));
var itemType = propertyType.GetGenericArguments()[0];
var generic = method.MakeGenericMethod(itemType);
dynamic parsedValue = generic.Invoke(null, new dynamic[] {parameter.Children, currentPath});
propertyValue.Add(parsedValue);
}
else
{
var method = typeof(ParametersConverter).GetMethod(nameof(Parse));
var generic = method.MakeGenericMethod(propertyType);
dynamic parsedValue = generic.Invoke(null, new dynamic[] {parameter.Children, currentPath});
propertyInfo.SetValue(result, parsedValue);
}
}
return result;
}
private static Dictionary<byte, PropertyInfo> SortedPropertiesDictionary<T>()
{
var typeInfo = typeof(T).GetTypeInfo();
var properties = new Dictionary<byte, PropertyInfo>();
foreach (var propertyInfo in typeInfo.DeclaredProperties)
{
var rawParameterAttribute =
(RawParameterAttribute) propertyInfo.GetCustomAttribute(typeof(RawParameterAttribute));
if (rawParameterAttribute == null)
throw new ArgumentException(
$"Class {typeInfo.Name} doesn't have RawParameterAttribute on property {propertyInfo.Name}"
);
if (properties.ContainsKey(rawParameterAttribute.Id))
throw new ArgumentException(
$"Class {typeInfo.Name} already has RawParameterAttribute with Id {rawParameterAttribute.Id}"
);
properties[rawParameterAttribute.Id] = propertyInfo;
}
return properties.OrderBy(kv => kv.Key).ToDictionary(kv => kv.Key, kv => kv.Value);
}
}
}

View File

@ -0,0 +1,10 @@
using System;
namespace WatchFace.Utils
{
[AttributeUsage(AttributeTargets.Property)]
public class RawParameterAttribute : Attribute
{
public byte Id { get; set; }
}
}

View File

@ -1,69 +1,35 @@
using System;
using System.Collections.Generic;
using NLog;
using WatchFace.Elements;
using WatchFace.Models;
using WatchFace.Elements;
using WatchFace.Utils;
namespace WatchFace
{
public class WatchFace
{
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
[RawParameter(Id = 2)]
public Background Background { get; set; }
[RawParameter(Id = 3)]
public Time Time { get; set; }
public Date Date { get; set; }
public Weather Weather { get; set; }
[RawParameter(Id = 4)]
public Activity Activity { get; set; }
[RawParameter(Id = 5)]
public Date Date { get; set; }
[RawParameter(Id = 6)]
public Weather Weather { get; set; }
[RawParameter(Id = 7)]
public Scales Scales { get; set; }
[RawParameter(Id = 8)]
public Status Status { get; set; }
[RawParameter(Id = 9)]
public Battery Battery { get; set; }
[RawParameter(Id = 10)]
public AnalogDialFace AnalogDialFace { get; set; }
public static WatchFace Parse(List<Parameter> descriptor)
{
Logger.Trace("Rading root");
if (descriptor == null)
throw new ArgumentNullException(nameof(descriptor));
var result = new WatchFace();
foreach (var resource in descriptor)
{
var currentPath = resource.Id.ToString();
switch (resource.Id)
{
case 2:
result.Background = Background.Parse(resource.Children, currentPath);
break;
case 3:
result.Time = Time.Parse(resource.Children, currentPath);
break;
case 4:
result.Activity = Activity.Parse(resource.Children, currentPath);
break;
case 5:
result.Date = Date.Parse(resource.Children, currentPath);
break;
case 6:
result.Weather = Weather.Parse(resource.Children, currentPath);
break;
case 7:
result.Scales = Scales.Parse(resource.Children, currentPath);
break;
case 8:
result.Status = Status.Parse(resource.Children, currentPath);
break;
case 9:
result.Battery = Battery.Parse(resource.Children, currentPath);
break;
case 10:
result.AnalogDialFace = AnalogDialFace.Parse(resource.Children, currentPath);
break;
default:
throw new InvalidParameterException(resource, "");
}
}
return result;
}
}
}

View File

@ -0,0 +1,24 @@
using System.IO;
using NLog;
using WatchFace.Utils;
namespace WatchFace
{
public class Writer
{
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
private readonly FileStream _fileStream;
public Writer(FileStream streamReader)
{
_fileStream = streamReader;
}
public void Write(WatchFace watchFace)
{
var descriptor = ParametersConverter.Build(watchFace);
foreach (var parameter in descriptor) parameter.Write(_fileStream);
}
}
}

View File

@ -5,6 +5,7 @@ using NLog;
using NLog.Config;
using NLog.Targets;
using SixLabors.ImageSharp;
using WatchFace.Utils;
namespace WatchFace
{
@ -30,13 +31,19 @@ namespace WatchFace
return;
}
if (Path.GetExtension(inputFileName) == "json")
if (Path.GetExtension(inputFileName) == ".json")
PackWatchFace(inputFileName);
else
UnpackWatchFace(inputFileName);
}
private static void PackWatchFace(string inputFileName) { }
private static void PackWatchFace(string inputFileName)
{
var watchFace = ReadConfig(inputFileName);
var outputFileName = Path.ChangeExtension(inputFileName, "bin");
SetupLogger(Path.ChangeExtension(outputFileName, ".log"));
WriteWatchFace(outputFileName, watchFace);
}
private static void UnpackWatchFace(string inputFileName)
{
@ -55,6 +62,24 @@ namespace WatchFace
ExportConfig(watchFace, Path.Combine(outputDirectory, $"{baseName}.json"));
}
private static void WriteWatchFace(string outputFileName, WatchFace watchFace)
{
Logger.Debug("Writing watch face to '{0}'", outputFileName);
try
{
using (var fileStream = File.OpenWrite(outputFileName))
{
var writer = new Writer(fileStream);
writer.Write(watchFace);
fileStream.Flush();
}
}
catch (Exception e)
{
Logger.Fatal(e);
}
}
private static Reader ReadWatchFace(string inputFileName)
{
Logger.Debug("Opening watch face '{0}'", inputFileName);
@ -80,7 +105,7 @@ namespace WatchFace
Logger.Debug("Parsing parameters...");
try
{
return WatchFace.Parse(reader.Resources);
return ParametersConverter.Parse<WatchFace>(reader.Resources);
}
catch (Exception e)
{
@ -116,6 +141,24 @@ namespace WatchFace
}
}
private static WatchFace ReadConfig(string jsonFileName)
{
Logger.Debug("Reading config...");
try
{
using (var fileStream = File.OpenRead(jsonFileName))
using (var reader = new StreamReader(fileStream))
{
return JsonConvert.DeserializeObject<WatchFace>(reader.ReadToEnd());
}
}
catch (Exception e)
{
Logger.Fatal(e);
return null;
}
}
private static void ExportConfig(WatchFace watchFace, string jsonFileName)
{
Logger.Debug("Exporting config...");