Skip to content

Commit

Permalink
Release version 4.4.0
Browse files Browse the repository at this point in the history
  • Loading branch information
matco committed May 14, 2024
2 parents cc09d27 + db4d659 commit d113294
Show file tree
Hide file tree
Showing 14 changed files with 84 additions and 70 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Test application
id: run_tests
uses: matco/action-connectiq-tester@v1
Expand Down
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
# Changelog

## 4.4.0
- Add support for Descent Mk3 series

## 4.3.1
- Fix and update custom fields in the Garmin Activity to allow much higher total scores
- Fix duplicated scores in the last lap of the Garmin Activity in endless mode
Expand Down
2 changes: 2 additions & 0 deletions manifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
<iq:products>
<iq:product id="descentmk2"/>
<iq:product id="descentmk2s"/>
<iq:product id="descentmk343mm"/>
<iq:product id="descentmk351mm"/>
<iq:product id="epix2"/>
<iq:product id="epix2pro42mm"/>
<iq:product id="epix2pro47mm"/>
Expand Down
3 changes: 3 additions & 0 deletions monkey.jungle
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,6 @@ fr265.resourcePath = resources;icons/60x60
fr265s.resourcePath = resources;icons/60x60

fr965.resourcePath = resources;icons/65x65

descentmk343mm.resourcePath = resources;icons/60x60
descentmk351mm.resourcePath = resources;icons/60x60
2 changes: 1 addition & 1 deletion source/BadmintonApp.mc
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ class BadmintonApp extends Application.AppBase {
}

function getInitialView() {
return [new InitialView(), new InitialViewDelegate()] as Array<InputDelegate or View>;
return [new InitialView(), new InitialViewDelegate()];
}

function getBus() as Bus {
Expand Down
4 changes: 2 additions & 2 deletions source/UIHelpers.mc
Original file line number Diff line number Diff line change
Expand Up @@ -44,15 +44,15 @@ module UIHelpers {
return closest_drawable;
}

function drawPolygon(dc as Dc, points as Array<Array<Float>>) as Void {
function drawPolygon(dc as Dc, points as Array<Point2D>) as Void {
var counts = points.size();
for(var i = 0; i < counts; i++) {
var next_index = (i + 1) % counts;
dc.drawLine(points[i][0], points[i][1], points[next_index][0], points[next_index][1]);
}
}

function drawHighlightedNumber(dc as Dc, x as Float, y as Float, font as FontType, text as String, color as Number, vertical_padding as Number, horizontal_padding as Number) as Void {
function drawHighlightedNumber(dc as Dc, x as Numeric, y as Numeric, font as FontType, text as String, color as Number, vertical_padding as Number, horizontal_padding as Number) as Void {
var dimensions = dc.getTextDimensions(text, font);
//the font height includes a default top margin that is useless
var offset = dimensions[1] * 0.12;
Expand Down
2 changes: 1 addition & 1 deletion source/factories/BeginnerPickerFactory.mc
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ using Toybox.WatchUi;
class BeginnerPickerFactory extends WatchUi.PickerFactory {

private const BEGINNERS as Array<Player or Symbol> = [YOU, OPPONENT, :random] as Array<Player or Symbol>;
private const BEGINNERS_LABELS as Array<Symbol> = [Rez.Strings.beginner_you, Rez.Strings.beginner_opponent, Rez.Strings.beginner_random] as Array<Symbol>;
private const BEGINNERS_LABELS as Array<ResourceId> = [Rez.Strings.beginner_you, Rez.Strings.beginner_opponent, Rez.Strings.beginner_random] as Array<ResourceId>;

function initialize() {
PickerFactory.initialize();
Expand Down
2 changes: 1 addition & 1 deletion source/factories/ServerPickerFactory.mc
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ using Toybox.WatchUi;
class ServerPickerFactory extends WatchUi.PickerFactory {

private const SERVERS as Array<Boolean> = [true, false] as Array<Boolean>;
private const SERVERS_LABELS as Array<Symbol> = [Rez.Strings.server_you, Rez.Strings.server_teammate] as Array<Symbol>;
private const SERVERS_LABELS as Array<ResourceId> = [Rez.Strings.server_you, Rez.Strings.server_teammate] as Array<ResourceId>;

function initialize() {
PickerFactory.initialize();
Expand Down
2 changes: 1 addition & 1 deletion source/factories/SetPickerFactory.mc
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ using Toybox.WatchUi;
class SetPickerFactory extends WatchUi.PickerFactory {

private const SETS as Array<Number or Symbol> = [1, 3, 5, :endless] as Array<Number or Symbol>;
private const SETS_LABELS as Array<Symbol> = [Rez.Strings.set_1, Rez.Strings.set_3, Rez.Strings.set_5, Rez.Strings.set_endless] as Array<Symbol>;
private const SETS_LABELS as Array<ResourceId> = [Rez.Strings.set_1, Rez.Strings.set_3, Rez.Strings.set_5, Rez.Strings.set_endless] as Array<ResourceId>;

function initialize() {
PickerFactory.initialize();
Expand Down
2 changes: 1 addition & 1 deletion source/factories/TypePickerFactory.mc
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ using Toybox.WatchUi;
class TypePickerFactory extends WatchUi.PickerFactory {

private const TYPES as Array<MatchType> = [SINGLE, DOUBLE] as Array<MatchType>;
private const TYPES_LABELS as Array<Symbol> = [Rez.Strings.type_single, Rez.Strings.type_double] as Array<Symbol>;
private const TYPES_LABELS as Array<ResourceId> = [Rez.Strings.type_single, Rez.Strings.type_double] as Array<ResourceId>;

function initialize() {
PickerFactory.initialize();
Expand Down
8 changes: 4 additions & 4 deletions source/model/BetterMath.mc
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,19 @@ import Toybox.Math;

module BetterMath {

function min(number1 as Float, number2 as Float) as Float {
function min(number1 as Numeric, number2 as Numeric) as Numeric {
return number1 < number2 ? number1 : number2;
}

function max(number1 as Float, number2 as Float) as Float {
function max(number1 as Numeric, number2 as Numeric) as Numeric {
return number1 < number2 ? number2 : number1;
}

function mean(number1 as Float, number2 as Float) as Float {
function mean(number1 as Numeric, number2 as Numeric) as Numeric {
return weightedMean(number1, number2, 0.5);
}

function weightedMean(number1 as Float, number2 as Float, weight_ratio as Float) as Float {
function weightedMean(number1 as Numeric, number2 as Numeric, weight_ratio as Numeric) as Numeric {
return (number1 - number2).abs() * weight_ratio + min(number1, number2);
}

Expand Down
33 changes: 16 additions & 17 deletions source/model/Geometry.mc
Original file line number Diff line number Diff line change
Expand Up @@ -19,17 +19,17 @@ The axis system for Perspective is like the perpendicular symbol (⊥):
*/
class Perspective {

private var origin as Array<Float>;
private var height as Float;
private var frontWidth as Float;
private var backWidth as Float;
private var depth as Float?; //depth from the baseline to the perspective point
private var origin as Point2D;
private var height as Numeric;
private var frontWidth as Numeric;
private var backWidth as Numeric;
private var depth as Numeric?; //depth from the baseline to the perspective point

function initialize(front_left_corner as Array<Float>, back_left_corner as Array<Float>, front_right_corner as Array<Float>, back_right_corner as Array<Float>) {
function initialize(front_left_corner as Point2D, back_left_corner as Point2D, front_right_corner as Point2D, back_right_corner as Point2D) {
origin = [
BetterMath.mean(front_right_corner[0], front_left_corner[0]),
front_left_corner[1]
] as Array<Float>;
] as Point2D;
height = front_left_corner[1] - back_left_corner[1];
frontWidth = front_right_corner[0] - front_left_corner[0];
backWidth = back_right_corner[0] - back_left_corner[0];
Expand All @@ -43,7 +43,7 @@ class Perspective {
}
}

function transform(coordinate as Array<Float>) as Array<Float> {
function transform(coordinate as Point2D) as Point2D {
//y is in [0,1] and must be scaled to [0,height]
var adjusted_y = coordinate[1] * height as Float;
//x is in [-0.5,0.5] and must be scaled [-frontWidth / 2,frontWidth / 2]
Expand All @@ -53,11 +53,11 @@ class Perspective {
adjusted_x = adjusted_x - adjusted_y * adjusted_x / depth;
}
//finally, translate scaled coordinates in the watch coordinates
return [origin[0] + adjusted_x, origin[1] - adjusted_y] as Array<Float>;
return [origin[0] + adjusted_x, origin[1] - adjusted_y] as Point2D;
}

function transformArray(coordinates as Array<Array<Float>>) as Array<Array<Float>> {
var transformed_coordinates = new [coordinates.size()] as Array<Array<Float>>;
function transformArray(coordinates as Array<Point2D>) as Array<Point2D> {
var transformed_coordinates = new [coordinates.size()] as Array<Point2D>;
for(var i = 0; i < coordinates.size(); i++) {
transformed_coordinates[i] = transform(coordinates[i]);
}
Expand All @@ -69,19 +69,18 @@ class Perspective {
}

function drawPartialVanishingLine(dc as Dc, x as Float, y1 as Float, y2 as Float) as Void {
var beginning = transform([x, y1] as Array<Float>);
var end = transform([x, y2] as Array<Float>);
var beginning = transform([x, y1] as Point2D);
var end = transform([x, y2] as Point2D);
dc.drawLine(beginning[0], beginning[1], end[0], end[1]);
}

function drawTransversalLine(dc as Dc, y as Float) as Void {
var beginning = transform([-0.5, y] as Array<Float>);
var end = transform([0.5, y] as Array<Float>);
var beginning = transform([-0.5, y] as Point2D);
var end = transform([0.5, y] as Point2D);
dc.drawLine(beginning[0], beginning[1], end[0], end[1]);
}

function fillPolygon(dc as Dc, coordinates as Array<Array<Float>>) as Void {
function fillPolygon(dc as Dc, coordinates as Array<Point2D>) as Void {
dc.fillPolygon(transformArray(coordinates));
}

}
29 changes: 18 additions & 11 deletions source/test/IQTest.mc
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,12 @@ import Toybox.ActivityRecording;
module IQTest {

//this is more a documentation than a test
//this test can be run on the Fenix 5 (max API v3.1.0), the Fenix 6 (max API v3.4.0) or the Fenix 7 (max API v4.2.0)
//the goal is to show that the "has" keyword cannot be used to check if the new sports and sub sports are available
//remember that Activity.SPORT_RACKET and Activity.SUB_SPORT_BADMINTON are available only in v4.1.6+
//also remember that the sports and sub sports properties have been moved from ActivityRecording to Activity in v3.2.0+
//this test should be run on the Fenix 5 (max API v3.1.0), the Fenix 6 (max API v3.4.0) and the Fenix 7 (max API v5.0.0)
//with these devices, the test will pass because the asserts have been modified to accomodate the bugs in the simulator (see "BUG!" comments below)
//this test will fail properly when run on the Forerunner 945 (max API v3.3.1)
(:test)
function testActivity(logger as Logger) as Boolean {
var version = System.getDeviceSettings().monkeyVersion;
Expand All @@ -16,22 +21,23 @@ module IQTest {
System.println("Version: " + version);
System.println("Has new properties: " + v320 + " - Has new sports: " + v410);

//devices >= 3.2.0 have all the new properties in Activity, if checked with "has"
//v3.2.0+ devices have all the new properties in Activity, if checked with "has"
//even if they don't support the new sports, they are available
if(v320) {
//BetterTest.assertFalse(Activity has :SPORT_LEAP_FROG, "The new activity properties does not include leap frog"); disabled to satisfy the compiler
BetterTest.assertTrue(Activity has :SPORT_CYCLING, "The new activity properties includes cycling");
//the following assert should be valid only for devices >= 4.1.0
//BUG! the following assert should throw an exception on v4.1.0- devices
//it should be valid only for v4.1.0+ devices, however it also works on the Fenix 5 and 6
BetterTest.assertTrue(Activity has :SPORT_RACKET, "The new activity properties includes racket");
}
//devices < 3.2.0 don't have the new properties in Activity, if checked with "has"
//3.2.0- devices don't have the new properties in Activity, if checked with "has", as expected
else {
//BetterTest.assertFalse(Activity has :SPORT_LEAP_FROG, "The new activity properties does not include leap frog"); disabled to satisfy the compiler
BetterTest.assertFalse(Activity has :SPORT_CYCLING, "The new activity properties does not include cycling");
BetterTest.assertFalse(Activity has :SPORT_RACKET, "The new activity properties does not include racket");
}

//however, all devices have the new properties in Activity, if checked directly!
//however, all devices have the new properties in Activity, if checked directly (not using "has")!
BetterTest.assertEqual(Activity.SPORT_CYCLING, 2, "All devices have the new activity properties that includes cycling (stored as 2)");
BetterTest.assertEqual(Activity.SPORT_RACKET, 64, "All devices have the new activity properties that includes racket (stored as 64)");

Expand All @@ -40,31 +46,32 @@ module IQTest {
BetterTest.assertEqual(ActivityRecording.SPORT_CYCLING, 2, "All devices have the old activity recording properties that includes cycling (stored as 2)");
//BetterTest.assertFalse(ActivityRecording has :SPORT_RACKET, "The old activity recording properties does not include racket"); disabled to satisfy the compiler

//this means that "has" can not be used to decide if the new sports and sub sports can be used
//this means that the "has" keyword cannot be used to decide if the new sports and sub sports are available
//but the new enum can be used on all devices (and this removes the deprecation messages)
var sport = Activity has :SPORT_RACKET ? Activity.SPORT_RACKET : Activity.SPORT_GENERIC;
if(v410) {
BetterTest.assertEqual(sport, 64, "For devices >= 4.1.0, selected sport is racket");
BetterTest.assertEqual(sport, 64, "For v4.1.0+ devices, selected sport is racket");
}
else if(v320) {
BetterTest.assertEqual(sport, 64, "This assert should not be valid, devices < 4.1.0 should fallback to the generic sport");
//BUG! the following assert should throw an exception on v4.1.0- devices
BetterTest.assertEqual(sport, 64, "This assert should not be valid, v4.1.0- devices should fallback to the generic sport");
}
else {
BetterTest.assertEqual(sport, 0, "In old versions, fallback to the generic sport");
}

var sub_sport = Activity has :SUB_SPORT_BADMINTON ? Activity.SUB_SPORT_BADMINTON : Activity.SUB_SPORT_MATCH;
if(v410) {
BetterTest.assertEqual(sub_sport, 95, "For devices >= 4.1.0, selected sub sport is badminton");
BetterTest.assertEqual(sub_sport, 95, "For v4.1.0+ devices, selected sub sport is badminton");
}
else if(v320) {
BetterTest.assertEqual(sub_sport, 95, "This assert should not be valid, devices < 4.1.0 should fallback to match");
//BUG! the following assert should throw an exception on v4.1.0- devices
BetterTest.assertEqual(sub_sport, 95, "This assert should not be valid, v4.1.0- devices should fallback to match");
}
else {
BetterTest.assertEqual(sub_sport, 22, "In old versions, fallback to match");
}

//however, this looks like a bug of the simulator
//on a device, it's better to check the device version and to use the appropriate properties, even if this triggers deprecation messages
//var sport = v410 ? Activity.SPORT_RACKET : ActivityRecording.SPORT_GENERIC;
//var sub_sport = v410 ? Activity.SUB_SPORT_BADMINTON : ActivityRecording.SUB_SPORT_MATCH;
Expand Down
Loading

0 comments on commit d113294

Please sign in to comment.