Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Prototype for moving core functionality into a Swift framework #3573

Draft
wants to merge 8 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 4 additions & 0 deletions Hammerspoon Tests/HSmath.m
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@ - (void)testRandomFloat {
RUN_LUA_TEST()
}

- (void)testRandomFloatFromRange {
RUN_LUA_TEST()
}

- (void)testRandomFromRange {
RUN_LUA_TEST()
}
Expand Down
688 changes: 686 additions & 2 deletions Hammerspoon.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

66 changes: 66 additions & 0 deletions Hammerspoon.xcodeproj/xcshareddata/xcschemes/Hammertime.xcscheme
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1510"
version = "1.7">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "4F61CD862B32F58000407260"
BuildableName = "Hammertime.framework"
BlueprintName = "Hammertime"
ReferencedContainer = "container:Hammerspoon.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES"
shouldAutocreateTestPlan = "YES">
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "4F61CD862B32F58000407260"
BuildableName = "Hammertime.framework"
BlueprintName = "Hammertime"
ReferencedContainer = "container:Hammerspoon.xcodeproj">
</BuildableReference>
</MacroExpansion>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>
13 changes: 13 additions & 0 deletions Hammertime/Hammertime.docc/Hammertime.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# ``Hammertime``

<!--@START_MENU_TOKEN@-->Summary<!--@END_MENU_TOKEN@-->

## Overview

<!--@START_MENU_TOKEN@-->Text<!--@END_MENU_TOKEN@-->

## Topics

### <!--@START_MENU_TOKEN@-->Group<!--@END_MENU_TOKEN@-->

- <!--@START_MENU_TOKEN@-->``Symbol``<!--@END_MENU_TOKEN@-->
19 changes: 19 additions & 0 deletions Hammertime/Hammertime.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
//
// Hammertime.h
// Hammertime
//
// Created by Chris Jones on 20/12/2023.
// Copyright © 2023 Hammerspoon. All rights reserved.
//

#import <Foundation/Foundation.h>

//! Project version number for Hammertime.
FOUNDATION_EXPORT double HammertimeVersionNumber;

//! Project version string for Hammertime.
FOUNDATION_EXPORT const unsigned char HammertimeVersionString[];

// In this header, you should import all the public headers of your framework using statements like #import <Hammertime/PublicHeader.h>


69 changes: 69 additions & 0 deletions Hammertime/Math.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
//
// Math.swift
// Hammertime
//
// Created by Chris Jones on 20/12/2023.
// Copyright © 2023 Hammerspoon. All rights reserved.
//

import Foundation

@objc
public class Math : NSObject {
@objc
public func validateDoubleRange(start: Double, end: Double) -> Bool {
return start <= end
}

@objc
public func validateIntRange(start: Int, end: Int) -> Bool {
return start <= end
}

/// Returns a random Double between 0 and 1 (inclusive)
/// - Returns: Double
@objc
public func randomDouble() -> Double {
return self.randomDoubleInRange(start: 0, end: 1)
}

/// Returns a random Doubld within the supplied range (inclusive)
/// - Parameters:
/// - start: Lower bound of the range
/// - end: Upper bound of the range
/// - Returns: Double
@objc
public func randomDoubleInRange(start: Double, end: Double) -> Double {
if (!self.validateDoubleRange(start: start, end: end)) {
NSException.raise(.rangeException, format: "start must be <= end", arguments: getVaList([""]))
}
return Double.random(in: start...end)
}

/// Returns a random Float between 0 and 1 (inclusive)
/// - Returns: Float
@objc
public func randomFloat() -> Float {
return self.randomFloatInRange(start: 0, end: 1)
}

/// Returns a random Float within the supplied range (inclusive)
/// - Parameters:
/// - start: Lower bound of the range
/// - end: Upper bound of the range
/// - Returns: Float
@objc
public func randomFloatInRange(start: Float, end: Float) -> Float {
return Float.random(in: start...end)
}

/// Returns a random Int within the supplied range (inclusive)
/// - Parameters:
/// - start: Lower bound of the range
/// - end: Upper bound of the range
/// - Returns: Int
@objc
public func randomIntInRange(start: Int, end: Int) -> Int {
return Int.random(in: start...end)
}
}
37 changes: 37 additions & 0 deletions HammertimeTests/HammertimeTests.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
//
// HammertimeTests.swift
// HammertimeTests
//
// Created by Chris Jones on 20/12/2023.
// Copyright © 2023 Hammerspoon. All rights reserved.
//

import XCTest
@testable import Hammertime

final class HammertimeTests: XCTestCase {

override func setUpWithError() throws {
// Put setup code here. This method is called before the invocation of each test method in the class.
}

override func tearDownWithError() throws {
// Put teardown code here. This method is called after the invocation of each test method in the class.
}

func testExample() throws {
// This is an example of a functional test case.
// Use XCTAssert and related functions to verify your tests produce the correct results.
// Any test you write for XCTest can be annotated as throws and async.
// Mark your test throws to produce an unexpected failure when your test encounters an uncaught error.
// Mark your test async to allow awaiting for asynchronous code to complete. Check the results with assertions afterwards.
}

func testPerformanceExample() throws {
// This is an example of a performance test case.
self.measure {
// Put the code you want to measure the time of here.
}
}

}
53 changes: 43 additions & 10 deletions extensions/math/libmath.m
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
@import Cocoa ;
@import LuaSkin ;
@import Hammertime ;

#import <stdlib.h>

Expand All @@ -16,10 +17,42 @@ static int math_randomFloat(lua_State* L) {
LuaSkin *skin = [LuaSkin sharedWithState:L];
[skin checkArgs:LS_TBREAK];

uint32_t rand = arc4random();
double val = ((double)rand / UINT32_MAX);
Math *math = [[Math alloc] init];
lua_pushnumber(L, [math randomDouble]);

lua_pushnumber(L, val);
return 1;
}

/// hs.math.randomFloatFromRange(start, end) -> number
/// Function
/// Returns a random floating point number in the supplied range
///
/// Parameters:
/// * start - Lower bound of the range
/// * end - Upper bound of the range
///
/// Returns:
/// * A random number
static int math_randomFloatFromRange(lua_State *L) {
LuaSkin *skin = [LuaSkin sharedWithState:L];
[skin checkArgs:LS_TNUMBER, LS_TNUMBER, LS_TBREAK];

Math *math = [[Math alloc] init];
// double start = lua_tonumber(L, 1);
// double end = lua_tonumber(L, 2);

// if (![math validateDoubleRangeWithStart:start end:end]) {
// [skin logError:@"hs.math.randomFloatFromRange: start must be <= end"];
// lua_pushnil(L);
// return 1;
// }

@try {
lua_pushnumber(L, [math randomDoubleInRangeWithStart:lua_tonumber(L, 1) end:lua_tonumber(L, 2)]);
} @catch (NSException *e){
[skin logError:e.reason];
lua_pushnil(L);
}
return 1;
}

Expand All @@ -28,33 +61,33 @@ static int math_randomFloat(lua_State* L) {
/// Returns a random integer between the start and end parameters
///
/// Parameters:
/// * start - A number to start the range, must be greater than or equal to zero
/// * end - A number to end the range, must be greater than zero and greater than `start`
/// * start - Lower bound of the range
/// * end - Upper bound of the range
///
/// Returns:
/// * A randomly chosen integer between `start` and `end`
static int math_randomFromRange(lua_State* L) {
LuaSkin *skin = [LuaSkin sharedWithState:L] ;
[skin checkArgs:LS_TNUMBER, LS_TNUMBER, LS_TBREAK] ;

Math *math = [[Math alloc] init];
int start = (int)lua_tointeger(L, 1);
int end = (int)lua_tointeger(L, 2);

if (start < 0 || end <= 0 || end <= start) {
[skin logError:[NSString stringWithFormat:@"Please check the docs for hs.math.randomForRange() - your range is not acceptable (%d -> %d)", start, end]];
if (![math validateIntRangeWithStart:start end:end]) {
[skin logError:@"hs.math.randomFromRange: start must be <= end"];
lua_pushnil(L);
return 1;
}

int result = arc4random_uniform(end - start + 1) + start;

lua_pushinteger(L, result);
lua_pushinteger(L, [math randomIntInRangeWithStart:lua_tointeger(L, 1) end:lua_tointeger(L, 2)]);
return 1;
}

// Functions for returned object when module loads
static const luaL_Reg mathLib[] = {
{"randomFloat", math_randomFloat},
{"randomFloatFromRange", math_randomFloatFromRange},
{"randomFromRange", math_randomFromRange},

{NULL, NULL}
Expand Down
27 changes: 25 additions & 2 deletions extensions/math/test_math.lua
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,39 @@ function testRandomFloat()
return success()
end

function testRandomFloatFromRange()
local i = 10
while i > 0 do
local rand = hs.math.randomFloatFromRange(0, 100)
assertTrue(rand >= 0)
assertTrue(rand <= 100)
i = i - 1
end

local rand1 = hs.math.randomFloatFromRange(-1, 100)
assertTrue(rand1 >= -1)
assertTrue(rand1 <= 100)

local rand2 = hs.math.randomFloatFromRange(1, 1)
assertTrue(rand2 == 1)

local rand3 = hs.math.randomFloatFromRange(100, 1)
assertIsNil(rand3)

return success()
end

function testRandomFromRange()
local rand1 = hs.math.randomFromRange(0, 100)
assertTrue(rand1 >= 0)
assertTrue(rand1 <= 100)

local rand2 = hs.math.randomFromRange(-1, 100)
assertIsNil(rand2)
assertTrue(rand2 >= -1)
assertTrue(rand2 <= 100)

local rand3 = hs.math.randomFromRange(1, 1)
assertIsNil(rand3)
assertTrue(rand3 == 1)

local rand4 = hs.math.randomFromRange(1, -1)
assertIsNil(rand4)
Expand Down