working SwiftUI mac example

This commit is contained in:
Selim Mustafaev 2025-10-05 14:27:35 +03:00
parent dffc91c5e0
commit 1ee3bdd159
8 changed files with 69 additions and 32 deletions

1
.gitignore vendored
View File

@ -5,4 +5,5 @@ out/
build/ build/
CMakeLists.txt.user CMakeLists.txt.user
**/.DS_Store **/.DS_Store
xcuserdata/
.swiftpm/ .swiftpm/

View File

@ -15,7 +15,7 @@ NS_ASSUME_NONNULL_BEGIN
@property CGImageRef frame; @property CGImageRef frame;
- (instancetype)init; - (instancetype)init;
- (void)runRom:(NSString*)path; - (void)runRom:(NSURL*)url;
- (void)stepToNextFrame; - (void)stepToNextFrame;
@end @end

View File

@ -30,7 +30,11 @@
} }
- (void)runRom:(NSURL*)url { - (void)runRom:(NSURL*)url {
[url startAccessingSecurityScopedResource];
_system->insertCartridge([url fileSystemRepresentation]); _system->insertCartridge([url fileSystemRepresentation]);
[url stopAccessingSecurityScopedResource];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
while(TRUE) { while(TRUE) {
[_condition lock]; [_condition lock];

View File

@ -10,14 +10,10 @@ import NesKitCpp
class NesSystemSwift { class NesSystemSwift {
var nesSystem: nes.System? // var nesSystem: nes.System?
//
init() { // init() {
//
let frameBufferSize = nes.Ppu.SCREEN_WIDTH * nes.Ppu.SCREEN_HEIGHT * MemoryLayout<nes.Pixel>.stride // let frameBufferSize = nes.Ppu.SCREEN_WIDTH * nes.Ppu.SCREEN_HEIGHT * MemoryLayout<nes.Pixel>.stride
// }
nesSystem?.setNewFrameCallback({ frameBuffer in
})
}
} }

View File

@ -6,16 +6,36 @@
// //
import SwiftUI import SwiftUI
import NesKit
import UniformTypeIdentifiers
struct ContentView: View { struct ContentView: View {
@State var system = NesSystem()
@State var showFileImporter = false
var body: some View { var body: some View {
VStack { NesView(system: system)
Image(systemName: "globe") .fileImporter(
.imageScale(.large) isPresented: $showFileImporter,
.foregroundStyle(.tint) allowedContentTypes: [.init(filenameExtension: "nes") ?? .data],
Text("Hello, world!") allowsMultipleSelection: false) { result in
} switch result {
.padding() case .success(let urls):
if let url = urls.first {
system.runRom(url)
}
case .failure(let error):
print("error: \(error)")
}
}
.toolbar {
Button {
showFileImporter = true
} label: {
Image(systemName: "document.badge.plus")
}
}
} }
} }

View File

@ -0,0 +1,23 @@
//
// NesSystemView.swift
// NesApp
//
// Created by Selim Mustafaev on 04.10.2025.
//
import AppKit
import NesKit
class NesSystemView: NSView {
init(system: NesSystem) {
super.init(frame: .zero)
self.layer = NesLayer(nesSystem: system)
self.wantsLayer = true
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}

View File

@ -5,27 +5,20 @@
// Created by Selim Mustafaev on 04.10.2025. // Created by Selim Mustafaev on 04.10.2025.
// //
import UIKit import AppKit
import SwiftUI
import NesKit import NesKit
class NesView: UIView { struct NesView: NSViewRepresentable {
let nesLayer: NesLayer @State var system: NesSystem
init(system: NesSystem) { func makeNSView(context: Context) -> NesSystemView {
self.nesLayer = NesLayer(nesSystem: system)
super.init(frame: .zero)
self.layer.addSublayer(self.nesLayer) NesSystemView(system: system)
} }
required init?(coder: NSCoder) { func updateNSView(_ nsView: NesSystemView, context: Context) {
fatalError("init(coder:) has not been implemented")
}
override func layoutSubviews() {
super.layoutSubviews()
self.nesLayer.frame = self.layer.frame
} }
} }