Skip to content

Commit 208313b

Browse files
authored
Introduce FrameCachingStrategy enum (#195)
* Rename frame buffer property * Introduce caching strategy * Add memory usage to demo * Format and clean up code
1 parent 639e40d commit 208313b

24 files changed

+479
-328
lines changed

.github/workflows/test.yml

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,22 @@
11
name: Test
22

3-
on:
3+
on:
44
push:
55
branches:
6-
- master
6+
- master
77
pull_request:
88
branches:
9-
- master
9+
- master
1010

1111
jobs:
1212
build:
13-
runs-on: macOS-latest
13+
runs-on: macOS-13
14+
env:
15+
DEVELOPER_DIR: /Applications/Xcode_15.0.1.app/Contents/Developer
1416

1517
steps:
16-
- uses: actions/checkout@v1
17-
- name: Run iOS tests
18-
run: make test-ios
19-
- name: Run tvOS tests
20-
run: make test-tvos
18+
- uses: actions/checkout@v1
19+
- name: Run iOS tests
20+
run: make test-ios
21+
- name: Run tvOS tests
22+
run: make test-tvos

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,3 +39,4 @@ Gifu.framework.zip
3939
*.xcscmblueprint
4040

4141
.swiftpm/
42+
buildServer.json

Demo/Demo-iOS/AppDelegate.swift

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,12 @@ import UIKit
22

33
@UIApplicationMain
44
class AppDelegate: UIResponder, UIApplicationDelegate {
5-
65
var window: UIWindow?
76

8-
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
7+
func application(
8+
_ application: UIApplication,
9+
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
10+
) -> Bool {
911
return true
1012
}
1113
}

Demo/Demo-iOS/EmptyViewController.swift

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
1-
import UIKit
21
import Gifu
2+
import UIKit
33

44
class EmptyViewController: UIViewController {
55
let imageView = GIFImageView(image: #imageLiteral(resourceName: "mugen.gif"))
66

77
lazy var customImageView: CustomAnimatedView = {
8-
return CustomAnimatedView(frame: CGRect(x: 0, y: self.view.frame.height - 200, width: 360, height: 200))
8+
return CustomAnimatedView(
9+
frame: CGRect(x: 0, y: self.view.frame.height - 200, width: 360, height: 200))
910
}()
1011

1112
override func viewDidLoad() {

Demo/Demo-iOS/UIImageViewExtension.swift

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import UIKit
21
import Gifu
2+
import UIKit
33

44
extension UIImageView: GIFAnimatable {
55
private struct AssociatedKeys {
@@ -12,7 +12,8 @@ extension UIImageView: GIFAnimatable {
1212

1313
public var animator: Animator? {
1414
get {
15-
guard let animator = objc_getAssociatedObject(self, &AssociatedKeys.AnimatorKey) as? Animator else {
15+
guard let animator = objc_getAssociatedObject(self, &AssociatedKeys.AnimatorKey) as? Animator
16+
else {
1617
let animator = Animator(withDelegate: self)
1718
self.animator = animator
1819
return animator
@@ -22,7 +23,9 @@ extension UIImageView: GIFAnimatable {
2223
}
2324

2425
set {
25-
objc_setAssociatedObject(self, &AssociatedKeys.AnimatorKey, newValue as Animator?, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
26+
objc_setAssociatedObject(
27+
self, &AssociatedKeys.AnimatorKey, newValue as Animator?, .OBJC_ASSOCIATION_RETAIN_NONATOMIC
28+
)
2629
}
2730
}
2831
}

Demo/Demo-iOS/ViewController.swift

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
import UIKit
21
import Gifu
2+
import UIKit
33

44
class ViewController: UIViewController {
55
@IBOutlet weak var imageView: GIFImageView!
66
@IBOutlet weak var imageDataLabel: UILabel!
77
@IBOutlet weak var memoryUsageLabel: UILabel!
8-
@IBAction func unwindToRootViewController(segue: UIStoryboardSegue) { }
8+
@IBAction func unwindToRootViewController(segue: UIStoryboardSegue) {}
99

1010
var currentGIFName: String = "earth" {
1111
didSet {
@@ -41,18 +41,26 @@ class ViewController: UIViewController {
4141
}
4242

4343
func animate() {
44-
imageView.animate(withGIFNamed: currentGIFName, preparationBlock: {
45-
DispatchQueue.main.async {
46-
self.imageDataLabel.text = self.currentGIFName.capitalized + " (\(self.imageView.frameCount) frames / \(String(format: "%.2f", self.imageView.gifLoopDuration))s)"
47-
}
48-
}, loopBlock: {
44+
imageView.setFrameBufferSize(1)
45+
46+
imageView.animate(
47+
withGIFNamed: currentGIFName,
48+
preparationBlock: {
49+
DispatchQueue.main.async {
50+
self.imageDataLabel.text =
51+
self.currentGIFName.capitalized
52+
+ " (\(self.imageView.frameCount) frames / \(String(format: "%.2f", self.imageView.gifLoopDuration))s)"
53+
}
54+
},
55+
loopBlock: {
4956
print("Loop finished")
50-
})
57+
})
5158

5259
if #available(iOS 15.0, *) {
5360
Timer.scheduledTimer(withTimeInterval: 1, repeats: true) { _ in
5461
DispatchQueue.main.async {
55-
self.memoryUsageLabel.text = "Memory usage: \(Memory.memoryFootprint()!.formatted(.byteCount(style: .memory)))"
62+
self.memoryUsageLabel.text =
63+
"Memory usage: \(Memory.memoryFootprint()!.formatted(.byteCount(style: .memory)))"
5664
}
5765
}
5866
}
@@ -62,8 +70,10 @@ class ViewController: UIViewController {
6270
class Memory: NSObject {
6371
// https://forums.developer.apple.com/thread/105088#357415
6472
class func memoryFootprint() -> Int? {
65-
let TASK_VM_INFO_COUNT = mach_msg_type_number_t(MemoryLayout<task_vm_info_data_t>.size / MemoryLayout<integer_t>.size)
66-
let TASK_VM_INFO_REV1_COUNT = mach_msg_type_number_t(MemoryLayout.offset(of: \task_vm_info_data_t.min_address)! / MemoryLayout<integer_t>.size)
73+
let TASK_VM_INFO_COUNT = mach_msg_type_number_t(
74+
MemoryLayout<task_vm_info_data_t>.size / MemoryLayout<integer_t>.size)
75+
let TASK_VM_INFO_REV1_COUNT = mach_msg_type_number_t(
76+
MemoryLayout.offset(of: \task_vm_info_data_t.min_address)! / MemoryLayout<integer_t>.size)
6777

6878
var info = task_vm_info_data_t()
6979
var count = TASK_VM_INFO_COUNT

Demo/Demo-tvOS/AppDelegate.swift

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,10 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
55

66
var window: UIWindow?
77

8-
9-
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
8+
func application(
9+
_ application: UIApplication,
10+
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
11+
) -> Bool {
1012
// Override point for customization after application launch.
1113
return true
1214
}
@@ -27,7 +29,4 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
2729
func applicationDidBecomeActive(_ application: UIApplication) {
2830
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
2931
}
30-
31-
3232
}
33-

Demo/Demo-tvOS/ViewController.swift

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,10 @@
1-
import UIKit
21
import Gifu
3-
2+
import UIKit
43

54
class ViewController: UIViewController {
65

76
@IBOutlet weak var imageView: GIFImageView!
87

9-
108
override func viewDidLoad() {
119
super.viewDidLoad()
1210
// Do any additional setup after loading the view.
@@ -20,4 +18,3 @@ class ViewController: UIViewController {
2018
imageView.animate(withGIFNamed: "mugen")
2119
}
2220
}
23-

Demo/Demo.xcodeproj/project.pbxproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -337,6 +337,7 @@
337337
DEVELOPMENT_TEAM = 5G38N4D8G2;
338338
GCC_C_LANGUAGE_STANDARD = gnu11;
339339
INFOPLIST_FILE = "$(SRCROOT)/Demo-tvOS/Info.plist";
340+
INFOPLIST_KEY_CFBundleDisplayName = Gifu;
340341
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
341342
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
342343
MTL_FAST_MATH = YES;
@@ -366,6 +367,7 @@
366367
DEVELOPMENT_TEAM = 5G38N4D8G2;
367368
GCC_C_LANGUAGE_STANDARD = gnu11;
368369
INFOPLIST_FILE = "$(SRCROOT)/Demo-tvOS/Info.plist";
370+
INFOPLIST_KEY_CFBundleDisplayName = Gifu;
369371
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
370372
MTL_FAST_MATH = YES;
371373
PRODUCT_BUNDLE_IDENTIFIER = "com.redalemeden.Gifu-tvOSDemo";
@@ -490,6 +492,7 @@
490492
DEVELOPMENT_TEAM = HCTW65QDC4;
491493
FRAMEWORK_SEARCH_PATHS = "$(inherited)";
492494
INFOPLIST_FILE = "$(SRCROOT)/Demo-iOS/Info.plist";
495+
INFOPLIST_KEY_CFBundleDisplayName = Gifu;
493496
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
494497
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
495498
OTHER_SWIFT_FLAGS = "";
@@ -509,6 +512,7 @@
509512
DEVELOPMENT_TEAM = HCTW65QDC4;
510513
FRAMEWORK_SEARCH_PATHS = "$(inherited)";
511514
INFOPLIST_FILE = "$(SRCROOT)/Demo-iOS/Info.plist";
515+
INFOPLIST_KEY_CFBundleDisplayName = Gifu;
512516
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
513517
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
514518
OTHER_SWIFT_FLAGS = "";

Gifu.xcodeproj/project.pbxproj

Lines changed: 41 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
archiveVersion = 1;
44
classes = {
55
};
6-
objectVersion = 46;
6+
objectVersion = 54;
77
objects = {
88

99
/* Begin PBXBuildFile section */
@@ -231,8 +231,9 @@
231231
00B8C7351A364DA400C188E7 /* Project object */ = {
232232
isa = PBXProject;
233233
attributes = {
234+
BuildIndependentTargetsInParallel = YES;
234235
LastSwiftUpdateCheck = 0920;
235-
LastUpgradeCheck = 1200;
236+
LastUpgradeCheck = 1540;
236237
ORGANIZATIONNAME = "Kaishin & Co";
237238
TargetAttributes = {
238239
009BD1351BBC7F6500FC982B = {
@@ -334,8 +335,12 @@
334335
DEVELOPMENT_TEAM = 5G38N4D8G2;
335336
GCC_NO_COMMON_BLOCKS = YES;
336337
INFOPLIST_FILE = Tests/Info.plist;
337-
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
338-
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
338+
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
339+
LD_RUNPATH_SEARCH_PATHS = (
340+
"$(inherited)",
341+
"@executable_path/Frameworks",
342+
"@loader_path/Frameworks",
343+
);
339344
PRODUCT_BUNDLE_IDENTIFIER = co.kaishin.GifuTests;
340345
PRODUCT_NAME = "$(TARGET_NAME)";
341346
PROVISIONING_PROFILE_SPECIFIER = "";
@@ -358,14 +363,19 @@
358363
DEVELOPMENT_TEAM = 5G38N4D8G2;
359364
GCC_NO_COMMON_BLOCKS = YES;
360365
INFOPLIST_FILE = Tests/Info.plist;
361-
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
362-
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
366+
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
367+
LD_RUNPATH_SEARCH_PATHS = (
368+
"$(inherited)",
369+
"@executable_path/Frameworks",
370+
"@loader_path/Frameworks",
371+
);
363372
PRODUCT_BUNDLE_IDENTIFIER = co.kaishin.GifuTests;
364373
PRODUCT_NAME = "$(TARGET_NAME)";
365374
PROVISIONING_PROFILE_SPECIFIER = "";
366375
"PROVISIONING_PROFILE_SPECIFIER[sdk=macosx*]" = "";
367376
SUPPORTED_PLATFORMS = "iphonesimulator iphoneos appletvos appletvsimulator";
368-
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
377+
SWIFT_COMPILATION_MODE = wholemodule;
378+
SWIFT_OPTIMIZATION_LEVEL = "-O";
369379
SWIFT_SWIFT3_OBJC_INFERENCE = Default;
370380
SWIFT_VERSION = 5.0;
371381
TARGETED_DEVICE_FAMILY = "1,2,3";
@@ -406,6 +416,7 @@
406416
CURRENT_PROJECT_VERSION = 1;
407417
ENABLE_STRICT_OBJC_MSGSEND = YES;
408418
ENABLE_TESTABILITY = YES;
419+
ENABLE_USER_SCRIPT_SANDBOXING = YES;
409420
GCC_C_LANGUAGE_STANDARD = gnu99;
410421
GCC_DYNAMIC_NO_PIC = NO;
411422
GCC_NO_COMMON_BLOCKS = YES;
@@ -421,7 +432,7 @@
421432
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
422433
GCC_WARN_UNUSED_FUNCTION = YES;
423434
GCC_WARN_UNUSED_VARIABLE = YES;
424-
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
435+
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
425436
MTL_ENABLE_DEBUG_INFO = YES;
426437
ONLY_ACTIVE_ARCH = YES;
427438
SDKROOT = iphoneos;
@@ -466,6 +477,7 @@
466477
CURRENT_PROJECT_VERSION = 1;
467478
ENABLE_NS_ASSERTIONS = NO;
468479
ENABLE_STRICT_OBJC_MSGSEND = YES;
480+
ENABLE_USER_SCRIPT_SANDBOXING = YES;
469481
GCC_C_LANGUAGE_STANDARD = gnu99;
470482
GCC_NO_COMMON_BLOCKS = YES;
471483
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
@@ -474,7 +486,7 @@
474486
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
475487
GCC_WARN_UNUSED_FUNCTION = YES;
476488
GCC_WARN_UNUSED_VARIABLE = YES;
477-
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
489+
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
478490
MTL_ENABLE_DEBUG_INFO = NO;
479491
SDKROOT = iphoneos;
480492
TARGETED_DEVICE_FAMILY = "1,2";
@@ -489,18 +501,24 @@
489501
buildSettings = {
490502
APPLICATION_EXTENSION_API_ONLY = YES;
491503
CLANG_ENABLE_MODULES = YES;
492-
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
504+
CODE_SIGN_IDENTITY = "";
493505
CURRENT_PROJECT_VERSION = 166;
494506
DEFINES_MODULE = YES;
495507
DYLIB_COMPATIBILITY_VERSION = 1;
496508
DYLIB_CURRENT_VERSION = 1;
497509
DYLIB_INSTALL_NAME_BASE = "@rpath";
510+
ENABLE_MODULE_VERIFIER = YES;
498511
FRAMEWORK_SEARCH_PATHS = "$(inherited)";
499512
INFOPLIST_FILE = "$(SRCROOT)/Supporting Files/Info.plist";
500513
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
501-
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
502-
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
514+
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
515+
LD_RUNPATH_SEARCH_PATHS = (
516+
"$(inherited)",
517+
"@executable_path/Frameworks",
518+
"@loader_path/Frameworks",
519+
);
503520
MARKETING_VERSION = 3.3;
521+
MODULE_VERIFIER_SUPPORTED_LANGUAGE_STANDARDS = "gnu99 gnu++11";
504522
ONLY_ACTIVE_ARCH = NO;
505523
PRODUCT_BUNDLE_IDENTIFIER = co.kaishin.gifu;
506524
PRODUCT_NAME = "$(TARGET_NAME)";
@@ -517,23 +535,30 @@
517535
buildSettings = {
518536
APPLICATION_EXTENSION_API_ONLY = YES;
519537
CLANG_ENABLE_MODULES = YES;
520-
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
538+
CODE_SIGN_IDENTITY = "";
521539
CURRENT_PROJECT_VERSION = 166;
522540
DEFINES_MODULE = YES;
523541
DYLIB_COMPATIBILITY_VERSION = 1;
524542
DYLIB_CURRENT_VERSION = 1;
525543
DYLIB_INSTALL_NAME_BASE = "@rpath";
544+
ENABLE_MODULE_VERIFIER = YES;
526545
FRAMEWORK_SEARCH_PATHS = "$(inherited)";
527546
INFOPLIST_FILE = "$(SRCROOT)/Supporting Files/Info.plist";
528547
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
529-
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
530-
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
548+
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
549+
LD_RUNPATH_SEARCH_PATHS = (
550+
"$(inherited)",
551+
"@executable_path/Frameworks",
552+
"@loader_path/Frameworks",
553+
);
531554
MARKETING_VERSION = 3.3;
555+
MODULE_VERIFIER_SUPPORTED_LANGUAGE_STANDARDS = "gnu99 gnu++11";
532556
PRODUCT_BUNDLE_IDENTIFIER = co.kaishin.gifu;
533557
PRODUCT_NAME = "$(TARGET_NAME)";
534558
SKIP_INSTALL = YES;
535559
SUPPORTED_PLATFORMS = "iphonesimulator iphoneos appletvsimulator appletvos";
536-
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
560+
SWIFT_COMPILATION_MODE = wholemodule;
561+
SWIFT_OPTIMIZATION_LEVEL = "-O";
537562
SWIFT_VERSION = 5.0;
538563
TARGETED_DEVICE_FAMILY = "1,2,3";
539564
};

0 commit comments

Comments
 (0)