Skip to content

Commit

Permalink
Merge pull request #13 from tylerszabo/zones
Browse files Browse the repository at this point in the history
Fix some zones not changing & set individual zones
  • Loading branch information
tylerszabo authored Apr 21, 2018
2 parents 351006a + 5cc7a50 commit dce2f7c
Show file tree
Hide file tree
Showing 4 changed files with 129 additions and 27 deletions.
63 changes: 41 additions & 22 deletions GLedApiDotNet/RGBFusionMotherboardImpl.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,30 +17,40 @@ public class RGBFusionMotherboard : IRGBFusionMotherboard
{
private class MotherboardLedLayoutImpl : IMotherboardLedLayout
{
private readonly LedType[] myLayout;
private readonly Lazy<LedType[]> myLayout;
private readonly int maxDivisions;

internal MotherboardLedLayoutImpl(byte[] rawLayout)
internal MotherboardLedLayoutImpl(Raw.GLedAPIv1_0_0Wrapper api, int maxDivisions)
{
myLayout = new LedType[rawLayout.Length];
for (int i = 0; i < myLayout.Length; i++)
{
myLayout[i] = (LedType)rawLayout[i];
}
this.maxDivisions = maxDivisions;
myLayout = new Lazy<LedType[]>(() => {
byte[] rawLayout = api.GetLedLayout(maxDivisions);
if (maxDivisions != rawLayout.Length)
{
throw new GLedAPIException(string.Format("GetLedLayout({0}) returned {1} divisions", maxDivisions, rawLayout.Length));
}
LedType[] layout = new LedType[rawLayout.Length];
for (int i = 0; i < layout.Length; i++)
{
layout[i] = (LedType)rawLayout[i];
}
return layout;
});
}

public LedType this[int i] => myLayout[i];
public LedType this[int i] => myLayout.Value[i];

public int Length => myLayout.Length;
public int Length => maxDivisions;

public IEnumerator<LedType> GetEnumerator()
{
foreach(LedType led in myLayout)
foreach(LedType led in myLayout.Value)
{
yield return led;
}
}

IEnumerator IEnumerable.GetEnumerator() => ((IEnumerable<LedType>)myLayout).GetEnumerator();
IEnumerator IEnumerable.GetEnumerator() => ((IEnumerable<LedType>)(myLayout.Value)).GetEnumerator();
}

private class MotherboardLedSettingsImpl : IMotherboardLedSettings
Expand All @@ -52,17 +62,25 @@ private class MotherboardLedSettingsImpl : IMotherboardLedSettings
internal void WriteToApi(Raw.GLedAPIv1_0_0Wrapper api)
{
if (dirty) {
// This is a workaround to avoid some zones/divisions not getting configured (issue #9).
// Calling SetLedData twice will actually allow all zones to be set.
api.SetLedData(this);
api.SetLedData(this);
dirty = false;
}
}

internal MotherboardLedSettingsImpl(int numSettings, LedSetting defaultSetting)
internal MotherboardLedSettingsImpl(IMotherboardLedLayout layout, LedSetting defaultSetting)
{
dirty = true;
ledSettings = new LedSetting[numSettings];
ledSettings = new LedSetting[layout.Length];
IEnumerator<LedType> e = layout.GetEnumerator();
for (int i = 0; i < ledSettings.Length; i++)
{
if(!e.MoveNext())
{
throw new GLedAPIException(string.Format("Number of layouts < length ({0})", ledSettings.Length));
}
ledSettings[i] = defaultSetting;
}
}
Expand Down Expand Up @@ -101,21 +119,21 @@ public int MaxDivisions
}
}

private MotherboardLedLayoutImpl layout;
private Lazy<MotherboardLedLayoutImpl> layout;
public IMotherboardLedLayout Layout
{
get
{
return layout;
return layout.Value;
}
}

private MotherboardLedSettingsImpl ledSettings;
private Lazy<MotherboardLedSettingsImpl> ledSettings;
public IMotherboardLedSettings LedSettings
{
get
{
return ledSettings;
return ledSettings.Value;
}
}

Expand All @@ -137,9 +155,10 @@ internal RGBFusionMotherboard(Raw.GLedAPIv1_0_0Wrapper wrapperAPI)
throw new GLedAPIException("No divisions");
}

layout = new MotherboardLedLayoutImpl(api.GetLedLayout(maxDivisions));
//layout = new Lazy<MotherboardLedLayoutImpl>(() => new MotherboardLedLayoutImpl(api.GetLedLayout(maxDivisions)));
layout = new Lazy<MotherboardLedLayoutImpl>(() => new MotherboardLedLayoutImpl(api, maxDivisions));

ledSettings = new MotherboardLedSettingsImpl(maxDivisions, new OffLedSetting());
ledSettings = new Lazy<MotherboardLedSettingsImpl>(() => new MotherboardLedSettingsImpl(layout.Value, new OffLedSetting()));
}

public RGBFusionMotherboard() : this(new Raw.GLedAPIv1_0_0Wrapper())
Expand All @@ -148,9 +167,9 @@ public RGBFusionMotherboard() : this(new Raw.GLedAPIv1_0_0Wrapper())

public void SetAll(LedSetting ledSetting)
{
for (int i = 0; i < ledSettings.Length; i++)
for (int i = 0; i < ledSettings.Value.Length; i++)
{
ledSettings[i] = ledSetting;
ledSettings.Value[i] = ledSetting;
}

Set();
Expand All @@ -168,7 +187,7 @@ public void Set(params int[] divisions)
applyDivs |= (1 << division);
}

ledSettings.WriteToApi(api);
ledSettings.Value.WriteToApi(api);

// Calling with no explicit divisions sets all
api.Apply(applyDivs == 0 ? -1 : applyDivs);
Expand Down
24 changes: 20 additions & 4 deletions GLedApiDotNetTests/TestHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -71,16 +71,32 @@ public static void AssertLedSettingsEqual(byte[] expected, byte[] actual)
Assert.AreEqual(expected[15], actual[15], "Offset 15, CtrlVal1");
}

public static void AssertAllLeds(GLedApiv1_0_0Mock mock, byte[] expected, int ledCount)
public static void AssertLedDivision(GLedApiv1_0_0Mock mock, byte[] expected, int ledCount, int division)
{
Assert.IsTrue(division < ledCount, "Expect division < ledCount");

Assert.AreEqual(ledCount * 16, mock.ConfiguredLeds.Length);

byte[] part = new byte[16];

for (int i = 0; i < ledCount; i++)
Array.Copy(mock.ConfiguredLeds, division * 16, part, 0, 16);
try
{
AssertLedSettingsEqual(expected, part);
}
catch (AssertFailedException e)
{
throw new AssertFailedException(string.Format("Division {0}: {1}", division, e.Message), e);
}
}

public static void AssertAllLeds(GLedApiv1_0_0Mock mock, byte[] expected, int ledCount)
{
Assert.AreEqual(ledCount * 16, mock.ConfiguredLeds.Length);

for (int division = 0; division < ledCount; division++)
{
Array.Copy(mock.ConfiguredLeds, i * 16, part, 0, 16);
TestHelper.AssertLedSettingsEqual(expected, part);
AssertLedDivision(mock, expected, ledCount, division);
}

Assert.AreEqual(-1, mock.LastApply, "Expect applied");
Expand Down
26 changes: 25 additions & 1 deletion RGBFusionTool/Application.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ public void Main(string[] args)
int opt_Verbose = 0;
string opt_Color = null;
string opt_ColorCycle = null;
string opt_Zone = null;
bool flag_DoCycle = false;
bool flag_Help = false;
bool flag_List = false;
Expand All @@ -53,6 +54,7 @@ public void Main(string[] args)
{"b|brightness=", "brightness (0-100)", v => opt_Brightness = v },

{"l|list", "list zones", v => flag_List = true },
{"z|zone=", "set zone", v => opt_Zone = v },

{"?|h|help", "show help and exit", v => flag_Help = true },

Expand All @@ -62,6 +64,7 @@ public void Main(string[] args)
try
{
byte brightness = 100;
int zone = -1;
LedSetting setting = null;

options.Parse(args);
Expand All @@ -86,6 +89,19 @@ public void Main(string[] args)
brightness = byte.Parse(opt_Brightness);
}

if (!string.IsNullOrWhiteSpace(opt_Zone))
{
zone = int.Parse(opt_Zone);
if (zone < 0)
{
throw new OptionException("Zone must be positive", "zone");
}
if (zone >= motherboardLEDs.Layout.Length)
{
throw new OptionException(string.Format("Zone is {0}, max supported is {1}", zone, motherboardLEDs.Layout.Length), "zone");
}
}

if (flag_DoCycle)
{
TimeSpan cycleTime = TimeSpan.FromSeconds(1);
Expand All @@ -110,7 +126,15 @@ public void Main(string[] args)

if (setting != null)
{
motherboardLEDs.SetAll(setting);
if (zone == -1)
{
motherboardLEDs.SetAll(setting);
}
else
{
motherboardLEDs.LedSettings[zone] = setting;
motherboardLEDs.Set(new int[] { zone });
}
}
}
catch (Exception e)
Expand Down
43 changes: 43 additions & 0 deletions RGBFusionToolTests/RGBFusionToolExeTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,9 @@ public void NoArgs()
[DataRow(new string[] { "--color=Red", "--brightness" }, DisplayName = "--color=Red --brightness")]
[DataRow(new string[] { "--color=Red", "--brightness=Invalid" }, DisplayName = "--color=Red --brightness=Invalid")]
[DataRow(new string[] { "--color=Red", "--brightness=101" }, DisplayName = "--color=Red --brightness=101")]
// Zone options
[DataRow(new string[] { "--zone=-1", "--color=DodgerBlue" }, DisplayName = "--zone=-1 --color=DodgerBlue")]
[DataRow(new string[] { "--zone=99", "--color=DodgerBlue" }, DisplayName = "--zone=99 --color=DodgerBlue")]
// Extra parameters
[DataRow(new string[] { "1" }, DisplayName = "1")]
[DataRow(new string[] { "0" }, DisplayName = "0")]
Expand Down Expand Up @@ -293,5 +296,45 @@ public void List(string[] args)

Assert.IsTrue(mock.IsInitialized, "Expect initialized");
}

[DataRow(new string[] { "-z1", "--color=DodgerBlue" }, DisplayName = "-z1")]
[DataRow(new string[] { "-z", "1", "--color=DodgerBlue" }, DisplayName = "-z 1")]
[DataRow(new string[] { "-z 1", "--color=DodgerBlue" }, DisplayName = "-z 1 (OneWord)")]
[DataRow(new string[] { "--zone=1", "--color=DodgerBlue" }, DisplayName = "--zone 1")]
[DataRow(new string[] { "--zone", "1", "--color=DodgerBlue" }, DisplayName = "--zone 1")]
[DataTestMethod]
public void Zone1(string[] args)
{
rgbFusionTool.Main(args);

StringAssert.DoesNotMatch(stderr.ToString(), ANY, "Expect stderr is empty");
StringAssert.DoesNotMatch(stdout.ToString(), ANY, "Expect stdout is empty");

TestHelper.AssertLedDivision(mock, GLedApiDotNetTests.Tests.LedSettingTests.SettingByteArrays.StaticDodgerBlue, GLedApiv1_0_0Mock.DEFAULT_MAXDIVISIONS, 1);

Assert.AreEqual(2, mock.LastApply, "Expect applied division 1 only");

Assert.IsTrue(mock.IsInitialized, "Expect initialized");
}

[DataRow(new string[] { "--zone=0", "--color=Red", "--brightness=50" }, 0, DisplayName = "zone 0")]
[DataRow(new string[] { "--zone=1", "--color=Red", "--brightness=50" }, 1, DisplayName = "zone 1")]
[DataRow(new string[] { "--zone=2", "--color=Red", "--brightness=50" }, 2, DisplayName = "zone 2")]
[DataRow(new string[] { "--zone=3", "--color=Red", "--brightness=50" }, 3, DisplayName = "zone 3")]
[DataRow(new string[] { "--zone=4", "--color=Red", "--brightness=50" }, 4, DisplayName = "zone 4")]
[DataTestMethod]
public void ZoneN(string[] args, int zone)
{
rgbFusionTool.Main(args);

StringAssert.DoesNotMatch(stderr.ToString(), ANY, "Expect stderr is empty");
StringAssert.DoesNotMatch(stdout.ToString(), ANY, "Expect stdout is empty");

TestHelper.AssertLedDivision(mock, GLedApiDotNetTests.Tests.LedSettingTests.SettingByteArrays.StaticRed50, GLedApiv1_0_0Mock.DEFAULT_MAXDIVISIONS, zone);

Assert.AreEqual(0x1 << zone, mock.LastApply, string.Format("Expect applied division {0} only", zone));

Assert.IsTrue(mock.IsInitialized, "Expect initialized");
}
}
}

0 comments on commit dce2f7c

Please sign in to comment.