From 6b9e31a7aea12562a4169d0fbebf2b3aae128694 Mon Sep 17 00:00:00 2001 From: ruihan00 Date: Wed, 20 Mar 2024 23:32:34 +0800 Subject: [PATCH 1/5] skeletal persistence implementation --- star-dash/star-dash.xcodeproj/project.pbxproj | 33 ++++++++ .../xcshareddata/swiftpm/Package.resolved | 9 +++ .../star-dash/Persistence/Database.swift | 79 +++++++++++++++++++ .../Persistence/StorageManager.swift | 12 +++ 4 files changed, 133 insertions(+) create mode 100644 star-dash/star-dash/Persistence/Database.swift create mode 100644 star-dash/star-dash/Persistence/StorageManager.swift diff --git a/star-dash/star-dash.xcodeproj/project.pbxproj b/star-dash/star-dash.xcodeproj/project.pbxproj index d3eacdaa..d365284e 100644 --- a/star-dash/star-dash.xcodeproj/project.pbxproj +++ b/star-dash/star-dash.xcodeproj/project.pbxproj @@ -53,6 +53,9 @@ 4E3458E92BA75E7C00E817C6 /* SpriteComponentTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E3458E82BA75E7C00E817C6 /* SpriteComponentTests.swift */; }; 4E3458EB2BA75E8B00E817C6 /* PhysicsComponentTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E3458EA2BA75E8B00E817C6 /* PhysicsComponentTests.swift */; }; 4E3458ED2BA75F1200E817C6 /* Util.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E3458EC2BA75F1200E817C6 /* Util.swift */; }; + 4E59E2512BAB2EAE007B3FA7 /* StorageManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E59E2502BAB2EAE007B3FA7 /* StorageManager.swift */; }; + 4E59E2532BAB3061007B3FA7 /* Database.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E59E2522BAB3061007B3FA7 /* Database.swift */; }; + 4E59E2562BAB33EC007B3FA7 /* SQLite in Frameworks */ = {isa = PBXBuildFile; productRef = 4E59E2552BAB33EC007B3FA7 /* SQLite */; }; 4E630EF62B9F7E070008F887 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E630EF52B9F7E070008F887 /* AppDelegate.swift */; }; 4E630EF82B9F7E070008F887 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E630EF72B9F7E070008F887 /* SceneDelegate.swift */; }; 4E630EFA2B9F7E070008F887 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E630EF92B9F7E070008F887 /* ViewController.swift */; }; @@ -169,6 +172,8 @@ 4E3458E82BA75E7C00E817C6 /* SpriteComponentTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SpriteComponentTests.swift; sourceTree = ""; }; 4E3458EA2BA75E8B00E817C6 /* PhysicsComponentTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PhysicsComponentTests.swift; sourceTree = ""; }; 4E3458EC2BA75F1200E817C6 /* Util.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Util.swift; sourceTree = ""; }; + 4E59E2502BAB2EAE007B3FA7 /* StorageManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StorageManager.swift; sourceTree = ""; }; + 4E59E2522BAB3061007B3FA7 /* Database.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Database.swift; sourceTree = ""; }; 4E630EF22B9F7E070008F887 /* star-dash.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "star-dash.app"; sourceTree = BUILT_PRODUCTS_DIR; }; 4E630EF52B9F7E070008F887 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 4E630EF72B9F7E070008F887 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; }; @@ -217,6 +222,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 4E59E2562BAB33EC007B3FA7 /* SQLite in Frameworks */, 14E247932BA2CA920071FFC0 /* DequeModule in Frameworks */, E6E4B8302BA6C8D4005ABAB1 /* SDPhysicsEngine in Frameworks */, ); @@ -371,6 +377,15 @@ path = Components; sourceTree = ""; }; + 4E59E24F2BAB2DBB007B3FA7 /* Persistence */ = { + isa = PBXGroup; + children = ( + 4E59E2502BAB2EAE007B3FA7 /* StorageManager.swift */, + 4E59E2522BAB3061007B3FA7 /* Database.swift */, + ); + path = Persistence; + sourceTree = ""; + }; 4E630EE92B9F7E070008F887 = { isa = PBXGroup; children = ( @@ -397,6 +412,7 @@ 4E630EF42B9F7E070008F887 /* star-dash */ = { isa = PBXGroup; children = ( + 4E59E24F2BAB2DBB007B3FA7 /* Persistence */, E6A011152BA5D111006904D9 /* GameBridge */, 46B8C0982BA328BF00498705 /* GameEngine */, E6A745102BA057040080C1BE /* Rendering */, @@ -561,6 +577,7 @@ packageProductDependencies = ( 14E247922BA2CA920071FFC0 /* DequeModule */, E6E4B82F2BA6C8D4005ABAB1 /* SDPhysicsEngine */, + 4E59E2552BAB33EC007B3FA7 /* SQLite */, ); productName = "star-dash"; productReference = 4E630EF22B9F7E070008F887 /* star-dash.app */; @@ -636,6 +653,7 @@ mainGroup = 4E630EE92B9F7E070008F887; packageReferences = ( 14E247912BA2CA920071FFC0 /* XCRemoteSwiftPackageReference "swift-collections" */, + 4E59E2542BAB33EC007B3FA7 /* XCRemoteSwiftPackageReference "SQLite.swift" */, ); productRefGroup = 4E630EF32B9F7E070008F887 /* Products */; projectDirPath = ""; @@ -720,11 +738,13 @@ 46D4181A2BA5CDBD0091A38B /* CollisionHandler.swift in Sources */, 4E86605F2BA095E30035530D /* Collectible.swift in Sources */, E64361122BA4C2CD003850FD /* ObjectModule.swift in Sources */, + 4E59E2532BAB3061007B3FA7 /* Database.swift in Sources */, 4E8660662BA097D40035530D /* PhysicsConstants.swift in Sources */, 143AA3952BA4DF1C009C28E7 /* MonsterAttackPlayerEvent.swift in Sources */, 143AA3932BA4DBE7009C28E7 /* PlayerMonsterContactEvent.swift in Sources */, 46D418162BA5CBD60091A38B /* Collidable.swift in Sources */, 461148912BA1CDBF0073E7E1 /* SystemManager.swift in Sources */, + 4E59E2512BAB2EAE007B3FA7 /* StorageManager.swift in Sources */, 145F2C842BA22CA300457549 /* EventModifiable.swift in Sources */, 4E630EFA2B9F7E070008F887 /* ViewController.swift in Sources */, E6A011172BA5F4AD006904D9 /* EntitySyncInterface.swift in Sources */, @@ -1151,6 +1171,14 @@ minimumVersion = 1.1.0; }; }; + 4E59E2542BAB33EC007B3FA7 /* XCRemoteSwiftPackageReference "SQLite.swift" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/stephencelis/SQLite.swift.git"; + requirement = { + kind = upToNextMajorVersion; + minimumVersion = 0.15.0; + }; + }; /* End XCRemoteSwiftPackageReference section */ /* Begin XCSwiftPackageProductDependency section */ @@ -1159,6 +1187,11 @@ package = 14E247912BA2CA920071FFC0 /* XCRemoteSwiftPackageReference "swift-collections" */; productName = DequeModule; }; + 4E59E2552BAB33EC007B3FA7 /* SQLite */ = { + isa = XCSwiftPackageProductDependency; + package = 4E59E2542BAB33EC007B3FA7 /* XCRemoteSwiftPackageReference "SQLite.swift" */; + productName = SQLite; + }; E6B1DC8E2BA3459600473563 /* SDPhysicsEngine */ = { isa = XCSwiftPackageProductDependency; productName = SDPhysicsEngine; diff --git a/star-dash/star-dash.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/star-dash/star-dash.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index 1a0f4251..3fdf1830 100644 --- a/star-dash/star-dash.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/star-dash/star-dash.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -1,5 +1,14 @@ { "pins" : [ + { + "identity" : "sqlite.swift", + "kind" : "remoteSourceControl", + "location" : "https://github.com/stephencelis/SQLite.swift.git", + "state" : { + "revision" : "e78ae0220e17525a15ac68c697a155eb7a672a8e", + "version" : "0.15.0" + } + }, { "identity" : "swift-collections", "kind" : "remoteSourceControl", diff --git a/star-dash/star-dash/Persistence/Database.swift b/star-dash/star-dash/Persistence/Database.swift new file mode 100644 index 00000000..d23c5eb8 --- /dev/null +++ b/star-dash/star-dash/Persistence/Database.swift @@ -0,0 +1,79 @@ +// +// AppDatabase.swift +// star-dash +// +// Created by Lau Rui han on 20/3/24. +// + +import Foundation +import os.log +import SQLite + +struct Database { + static let DIR_DB = "StarDashDB" + static let DB_NAME = "stardash.sqlite3" + private let levelTable = Table("level") + private var db: Connection? + + private init() { + if let docDir = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first { + let dirPath = docDir.appendingPathComponent(Self.DIR_DB) + + do { + try FileManager.default.createDirectory( + atPath: dirPath.path, + withIntermediateDirectories: true, + attributes: nil) + let dbPath = dirPath.appendingPathComponent(Self.DB_NAME).path + self.db = try Connection(dbPath) + print("SQLiteDataStore init successfully at: \(dbPath) ") + } catch { + db = nil + print("SQLiteDataStore init error: \(error)") + } + } else { + db = nil + } + } + + private func dropAllTables() { + guard let db = db else { + return + } + do { + try db.run(levelTable.drop()) + } catch {} + + } + + private func createAllTables() { + createLevelTable() + + } + + private func createLevelTable() { + guard let db = db else { + return + } + let id = Expression("id") + let name = Expression("name") + do { + try db.run( levelTable.create { table in + table.column(id) + table.column(name) + } + ) + print("Level table created") + } catch { + print("Error creating table \(error)") + } + } + + + func addLevel() { + + } +} + + + diff --git a/star-dash/star-dash/Persistence/StorageManager.swift b/star-dash/star-dash/Persistence/StorageManager.swift new file mode 100644 index 00000000..822fbdb8 --- /dev/null +++ b/star-dash/star-dash/Persistence/StorageManager.swift @@ -0,0 +1,12 @@ +// +// StorageManager.swift +// star-dash +// +// Created by Lau Rui han on 20/3/24. +// + +import Foundation + +struct StorageManager { + +} From 51a16d7ac69e14b25459e5a1556b2d5f2addbfe2 Mon Sep 17 00:00:00 2001 From: ruihan00 Date: Thu, 21 Mar 2024 13:53:33 +0800 Subject: [PATCH 2/5] table creation --- star-dash/star-dash.xcodeproj/project.pbxproj | 28 +++++++++++++++ star-dash/star-dash/Enums/EntityType.swift | 14 ++++++++ star-dash/star-dash/Model/Level.swift | 15 ++++++++ .../star-dash/Persistence/Database.swift | 23 +++++------- .../Persistence/EntityPersistable.swift | 35 +++++++++++++++++++ .../Persistence/LevelPersistable.swift | 17 +++++++++ .../Persistence/StorageManager.swift | 2 +- star-dash/star-dash/Persistence/data.json | 6 ++++ 8 files changed, 125 insertions(+), 15 deletions(-) create mode 100644 star-dash/star-dash/Enums/EntityType.swift create mode 100644 star-dash/star-dash/Model/Level.swift create mode 100644 star-dash/star-dash/Persistence/EntityPersistable.swift create mode 100644 star-dash/star-dash/Persistence/LevelPersistable.swift create mode 100644 star-dash/star-dash/Persistence/data.json diff --git a/star-dash/star-dash.xcodeproj/project.pbxproj b/star-dash/star-dash.xcodeproj/project.pbxproj index 4b02cbdc..1ac7c30b 100644 --- a/star-dash/star-dash.xcodeproj/project.pbxproj +++ b/star-dash/star-dash.xcodeproj/project.pbxproj @@ -56,6 +56,11 @@ 4E59E2512BAB2EAE007B3FA7 /* StorageManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E59E2502BAB2EAE007B3FA7 /* StorageManager.swift */; }; 4E59E2532BAB3061007B3FA7 /* Database.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E59E2522BAB3061007B3FA7 /* Database.swift */; }; 4E59E2562BAB33EC007B3FA7 /* SQLite in Frameworks */ = {isa = PBXBuildFile; productRef = 4E59E2552BAB33EC007B3FA7 /* SQLite */; }; + 4E59E2582BAB3B5B007B3FA7 /* data.json in Resources */ = {isa = PBXBuildFile; fileRef = 4E59E2572BAB3B5B007B3FA7 /* data.json */; }; + 4E59E25B2BAB3FDB007B3FA7 /* Level.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E59E25A2BAB3FDB007B3FA7 /* Level.swift */; }; + 4E59E25D2BAB405A007B3FA7 /* EntityPersistable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E59E25C2BAB405A007B3FA7 /* EntityPersistable.swift */; }; + 4E59E25F2BAB4134007B3FA7 /* EntityType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E59E25E2BAB4134007B3FA7 /* EntityType.swift */; }; + 4E59E2612BAB42FD007B3FA7 /* LevelPersistable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E59E2602BAB42FD007B3FA7 /* LevelPersistable.swift */; }; 4E630EF62B9F7E070008F887 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E630EF52B9F7E070008F887 /* AppDelegate.swift */; }; 4E630EF82B9F7E070008F887 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E630EF72B9F7E070008F887 /* SceneDelegate.swift */; }; 4E630EFA2B9F7E070008F887 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E630EF92B9F7E070008F887 /* ViewController.swift */; }; @@ -178,6 +183,11 @@ 4E3458EC2BA75F1200E817C6 /* Util.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Util.swift; sourceTree = ""; }; 4E59E2502BAB2EAE007B3FA7 /* StorageManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StorageManager.swift; sourceTree = ""; }; 4E59E2522BAB3061007B3FA7 /* Database.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Database.swift; sourceTree = ""; }; + 4E59E2572BAB3B5B007B3FA7 /* data.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = data.json; sourceTree = ""; }; + 4E59E25A2BAB3FDB007B3FA7 /* Level.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Level.swift; sourceTree = ""; }; + 4E59E25C2BAB405A007B3FA7 /* EntityPersistable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EntityPersistable.swift; sourceTree = ""; }; + 4E59E25E2BAB4134007B3FA7 /* EntityType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EntityType.swift; sourceTree = ""; }; + 4E59E2602BAB42FD007B3FA7 /* LevelPersistable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LevelPersistable.swift; sourceTree = ""; }; 4E630EF22B9F7E070008F887 /* star-dash.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "star-dash.app"; sourceTree = BUILT_PRODUCTS_DIR; }; 4E630EF52B9F7E070008F887 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 4E630EF72B9F7E070008F887 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; }; @@ -391,10 +401,21 @@ children = ( 4E59E2502BAB2EAE007B3FA7 /* StorageManager.swift */, 4E59E2522BAB3061007B3FA7 /* Database.swift */, + 4E59E2572BAB3B5B007B3FA7 /* data.json */, + 4E59E25C2BAB405A007B3FA7 /* EntityPersistable.swift */, + 4E59E2602BAB42FD007B3FA7 /* LevelPersistable.swift */, ); path = Persistence; sourceTree = ""; }; + 4E59E2592BAB3FC9007B3FA7 /* Model */ = { + isa = PBXGroup; + children = ( + 4E59E25A2BAB3FDB007B3FA7 /* Level.swift */, + ); + path = Model; + sourceTree = ""; + }; 4E630EE92B9F7E070008F887 = { isa = PBXGroup; children = ( @@ -421,6 +442,7 @@ 4E630EF42B9F7E070008F887 /* star-dash */ = { isa = PBXGroup; children = ( + 4E59E2592BAB3FC9007B3FA7 /* Model */, 4E59E24F2BAB2DBB007B3FA7 /* Persistence */, E6A011152BA5D111006904D9 /* GameBridge */, 46B8C0982BA328BF00498705 /* GameEngine */, @@ -488,6 +510,7 @@ isa = PBXGroup; children = ( 4E630F362B9F91DE0008F887 /* PlayerSprite.swift */, + 4E59E25E2BAB4134007B3FA7 /* EntityType.swift */, ); path = Enums; sourceTree = ""; @@ -687,6 +710,7 @@ 4E630F022B9F7E090008F887 /* LaunchScreen.storyboard in Resources */, 4E630EFF2B9F7E090008F887 /* Assets.xcassets in Resources */, 4E630EFD2B9F7E070008F887 /* Main.storyboard in Resources */, + 4E59E2582BAB3B5B007B3FA7 /* data.json in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -733,6 +757,7 @@ buildActionMask = 2147483647; files = ( 46D418182BA5CD840091A38B /* Player+Collidable.swift in Sources */, + 4E59E25B2BAB3FDB007B3FA7 /* Level.swift in Sources */, 46D4181E2BA5D2620091A38B /* Monster+Collidable.swift in Sources */, E6B1DC902BA34A4800473563 /* SDPhysicsEngine in Sources */, 4E630F272B9F7E770008F887 /* Entity.swift in Sources */, @@ -764,6 +789,7 @@ E6B0AAD52BAAE4EC009CB939 /* PlayerFloorContactEvent.swift in Sources */, E64361132BA4C2CD003850FD /* PhysicsModule.swift in Sources */, 4E630F322B9F887C0008F887 /* PhysicsComponent.swift in Sources */, + 4E59E25D2BAB405A007B3FA7 /* EntityPersistable.swift in Sources */, 1471B0AD2BA6AE4E00878B14 /* UseGrappleHookEvent.swift in Sources */, 4E630EF62B9F7E070008F887 /* AppDelegate.swift in Sources */, 461148962BA1D53D0073E7E1 /* PositionSystem.swift in Sources */, @@ -785,8 +811,10 @@ 143AA3972BA4E0D9009C28E7 /* PickupCollectibleEvent.swift in Sources */, 46D418242BA5D5280091A38B /* Tool+Collidable.swift in Sources */, E64361142BA4C2CD003850FD /* CreationModule.swift in Sources */, + 4E59E2612BAB42FD007B3FA7 /* LevelPersistable.swift in Sources */, E6A745162BA057040080C1BE /* MTKRenderer.swift in Sources */, E6A745182BA057040080C1BE /* Renderer.swift in Sources */, + 4E59E25F2BAB4134007B3FA7 /* EntityType.swift in Sources */, E6A745172BA057040080C1BE /* ControlView.swift in Sources */, 14970F562BA8177B00CC1E8A /* GameConstants.swift in Sources */, 1471B0A42BA6AAF200878B14 /* PlayerDeathEvent.swift in Sources */, diff --git a/star-dash/star-dash/Enums/EntityType.swift b/star-dash/star-dash/Enums/EntityType.swift new file mode 100644 index 00000000..8df48447 --- /dev/null +++ b/star-dash/star-dash/Enums/EntityType.swift @@ -0,0 +1,14 @@ +// +// EntityType.swift +// star-dash +// +// Created by Lau Rui han on 21/3/24. +// + +import Foundation +enum EntityType: String, Encodable, Decodable { + case Monster = "monster" + case Collectible = "collectible" + case Obstacle = "obstacle" + case Tool = "tool" +} diff --git a/star-dash/star-dash/Model/Level.swift b/star-dash/star-dash/Model/Level.swift new file mode 100644 index 00000000..2bab400e --- /dev/null +++ b/star-dash/star-dash/Model/Level.swift @@ -0,0 +1,15 @@ +// +// Level.swift +// star-dash +// +// Created by Lau Rui han on 21/3/24. +// + +import Foundation +struct Level { + var name: String + + init(name: String, entities: [Entity]) { + self.name = name + } +} diff --git a/star-dash/star-dash/Persistence/Database.swift b/star-dash/star-dash/Persistence/Database.swift index d23c5eb8..a6c91502 100644 --- a/star-dash/star-dash/Persistence/Database.swift +++ b/star-dash/star-dash/Persistence/Database.swift @@ -13,6 +13,7 @@ struct Database { static let DIR_DB = "StarDashDB" static let DB_NAME = "stardash.sqlite3" private let levelTable = Table("level") + private let entityTable = Table("entity") private var db: Connection? private init() { @@ -35,7 +36,7 @@ struct Database { db = nil } } - + private func dropAllTables() { guard let db = db else { return @@ -43,37 +44,31 @@ struct Database { do { try db.run(levelTable.drop()) } catch {} - + } - + private func createAllTables() { createLevelTable() - } - + private func createLevelTable() { guard let db = db else { return } - let id = Expression("id") + let id = Expression("id") let name = Expression("name") do { try db.run( levelTable.create { table in - table.column(id) + table.column(id, primaryKey: .autoincrement) table.column(name) - } - ) + }) print("Level table created") } catch { print("Error creating table \(error)") } } - - + func addLevel() { } } - - - diff --git a/star-dash/star-dash/Persistence/EntityPersistable.swift b/star-dash/star-dash/Persistence/EntityPersistable.swift new file mode 100644 index 00000000..e194114b --- /dev/null +++ b/star-dash/star-dash/Persistence/EntityPersistable.swift @@ -0,0 +1,35 @@ +// +// EntityPersistable.swift +// star-dash +// +// Created by Lau Rui han on 21/3/24. +// + +import Foundation + +struct EntityPersistable: Encodable, Decodable { + var id: Int64 + var levelId: Int64 + var entityType: EntityType + var position: CGPoint + + init(id: Int64, levelId: Int64, entityType: EntityType, position: CGPoint) { + self.id = id + self.levelId = levelId + self.entityType = entityType + self.position = position + } + + func toEntity() -> Entity { + switch entityType { + case .Monster: + return Monster(position: self.position) + case .Collectible: + return Collectible(position: self.position) + case .Obstacle: + return Obstacle(position: self.position) + case .Tool: + return Tool(position: self.position) + } + } +} diff --git a/star-dash/star-dash/Persistence/LevelPersistable.swift b/star-dash/star-dash/Persistence/LevelPersistable.swift new file mode 100644 index 00000000..7760e9f4 --- /dev/null +++ b/star-dash/star-dash/Persistence/LevelPersistable.swift @@ -0,0 +1,17 @@ +// +// LevelPersistable.swift +// star-dash +// +// Created by Lau Rui han on 21/3/24. +// + +import Foundation +struct LevelPersistable: Encodable, Decodable { + var id: Int64 + var name: String + init(id: Int64, name: String) { + self.id = id + self.name = name + } + +} diff --git a/star-dash/star-dash/Persistence/StorageManager.swift b/star-dash/star-dash/Persistence/StorageManager.swift index 822fbdb8..a6e799c7 100644 --- a/star-dash/star-dash/Persistence/StorageManager.swift +++ b/star-dash/star-dash/Persistence/StorageManager.swift @@ -7,6 +7,6 @@ import Foundation -struct StorageManager { +class StorageManager { } diff --git a/star-dash/star-dash/Persistence/data.json b/star-dash/star-dash/Persistence/data.json new file mode 100644 index 00000000..2820aa11 --- /dev/null +++ b/star-dash/star-dash/Persistence/data.json @@ -0,0 +1,6 @@ +{ + "name": "1", + "obstacles": [], + "collectibles": [], + "monster": [] +} From 82c478f9a8a5c66d161f3fae29dcbd0bebfa7753 Mon Sep 17 00:00:00 2001 From: ruihan00 Date: Fri, 22 Mar 2024 03:34:21 +0800 Subject: [PATCH 3/5] add json file and loading level --- star-dash/star-dash.xcodeproj/project.pbxproj | 4 + .../GameEngine/Entities/EntityManager.swift | 1 - star-dash/star-dash/Model/Level.swift | 8 +- .../star-dash/Persistence/Database.swift | 131 +++++++++++++++++- .../Persistence/EntityPersistable.swift | 8 +- .../star-dash/Persistence/LevelData.swift | 21 +++ .../Persistence/LevelPersistable.swift | 1 + .../Persistence/StorageManager.swift | 12 ++ star-dash/star-dash/Persistence/data.json | 16 ++- star-dash/star-dash/ViewController.swift | 12 +- 10 files changed, 198 insertions(+), 16 deletions(-) create mode 100644 star-dash/star-dash/Persistence/LevelData.swift diff --git a/star-dash/star-dash.xcodeproj/project.pbxproj b/star-dash/star-dash.xcodeproj/project.pbxproj index c3d35adf..911bdf14 100644 --- a/star-dash/star-dash.xcodeproj/project.pbxproj +++ b/star-dash/star-dash.xcodeproj/project.pbxproj @@ -61,6 +61,7 @@ 4E59E25D2BAB405A007B3FA7 /* EntityPersistable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E59E25C2BAB405A007B3FA7 /* EntityPersistable.swift */; }; 4E59E25F2BAB4134007B3FA7 /* EntityType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E59E25E2BAB4134007B3FA7 /* EntityType.swift */; }; 4E59E2612BAB42FD007B3FA7 /* LevelPersistable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E59E2602BAB42FD007B3FA7 /* LevelPersistable.swift */; }; + 4E59E2632BACB9E2007B3FA7 /* LevelData.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E59E2622BACB9E2007B3FA7 /* LevelData.swift */; }; 4E630EF62B9F7E070008F887 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E630EF52B9F7E070008F887 /* AppDelegate.swift */; }; 4E630EF82B9F7E070008F887 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E630EF72B9F7E070008F887 /* SceneDelegate.swift */; }; 4E630EFA2B9F7E070008F887 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E630EF92B9F7E070008F887 /* ViewController.swift */; }; @@ -189,6 +190,7 @@ 4E59E25C2BAB405A007B3FA7 /* EntityPersistable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EntityPersistable.swift; sourceTree = ""; }; 4E59E25E2BAB4134007B3FA7 /* EntityType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EntityType.swift; sourceTree = ""; }; 4E59E2602BAB42FD007B3FA7 /* LevelPersistable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LevelPersistable.swift; sourceTree = ""; }; + 4E59E2622BACB9E2007B3FA7 /* LevelData.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LevelData.swift; sourceTree = ""; }; 4E630EF22B9F7E070008F887 /* star-dash.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "star-dash.app"; sourceTree = BUILT_PRODUCTS_DIR; }; 4E630EF52B9F7E070008F887 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 4E630EF72B9F7E070008F887 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; }; @@ -407,6 +409,7 @@ 4E59E2572BAB3B5B007B3FA7 /* data.json */, 4E59E25C2BAB405A007B3FA7 /* EntityPersistable.swift */, 4E59E2602BAB42FD007B3FA7 /* LevelPersistable.swift */, + 4E59E2622BACB9E2007B3FA7 /* LevelData.swift */, ); path = Persistence; sourceTree = ""; @@ -837,6 +840,7 @@ 461148982BA1E41F0073E7E1 /* PhysicsSystem.swift in Sources */, 4E630F2E2B9F81850008F887 /* HealthComponent.swift in Sources */, 4E86605C2BA095460035530D /* Monster.swift in Sources */, + 4E59E2632BACB9E2007B3FA7 /* LevelData.swift in Sources */, 145F2C802BA203B400457549 /* Event.swift in Sources */, 1471B0A22BA6AA2200878B14 /* RespawnEvent.swift in Sources */, 46D418112BA5C88B0091A38B /* Wall.swift in Sources */, diff --git a/star-dash/star-dash/GameEngine/Entities/EntityManager.swift b/star-dash/star-dash/GameEngine/Entities/EntityManager.swift index 5df5b00e..8b3686cd 100644 --- a/star-dash/star-dash/GameEngine/Entities/EntityManager.swift +++ b/star-dash/star-dash/GameEngine/Entities/EntityManager.swift @@ -16,7 +16,6 @@ class EntityManager { var componentMap: ComponentMap var entityMap: EntityMap var entityComponentMap: EntityComponentMap - init(componentMap: ComponentMap, entityMap: EntityMap, entityComponentMap: EntityComponentMap) { self.componentMap = componentMap self.entityMap = entityMap diff --git a/star-dash/star-dash/Model/Level.swift b/star-dash/star-dash/Model/Level.swift index 2bab400e..fd0e4910 100644 --- a/star-dash/star-dash/Model/Level.swift +++ b/star-dash/star-dash/Model/Level.swift @@ -8,8 +8,14 @@ import Foundation struct Level { var name: String - + var entities: [Entity] init(name: String, entities: [Entity]) { self.name = name + self.entities = entities + } + + init(levelPersistable: LevelPersistable, entityPersistables: [EntityPersistable]) { + let entities = entityPersistables.map { $0.toEntity() } + self.init(name: levelPersistable.name, entities: entities) } } diff --git a/star-dash/star-dash/Persistence/Database.swift b/star-dash/star-dash/Persistence/Database.swift index a6c91502..c07dd72a 100644 --- a/star-dash/star-dash/Persistence/Database.swift +++ b/star-dash/star-dash/Persistence/Database.swift @@ -16,7 +16,7 @@ struct Database { private let entityTable = Table("entity") private var db: Connection? - private init() { + init() { if let docDir = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first { let dirPath = docDir.appendingPathComponent(Self.DIR_DB) @@ -27,6 +27,9 @@ struct Database { attributes: nil) let dbPath = dirPath.appendingPathComponent(Self.DB_NAME).path self.db = try Connection(dbPath) + dropAllTables() + createAllTables() + insertJsonData() print("SQLiteDataStore init successfully at: \(dbPath) ") } catch { db = nil @@ -43,12 +46,14 @@ struct Database { } do { try db.run(levelTable.drop()) + try db.run(entityTable.drop()) } catch {} } private func createAllTables() { createLevelTable() + createEntityTable() } private func createLevelTable() { @@ -59,7 +64,7 @@ struct Database { let name = Expression("name") do { try db.run( levelTable.create { table in - table.column(id, primaryKey: .autoincrement) + table.column(id, primaryKey: true) table.column(name) }) print("Level table created") @@ -67,8 +72,126 @@ struct Database { print("Error creating table \(error)") } } + + private func createEntityTable() { + guard let db = db else { + return + } + let id = Expression("id") + let levelId = Expression("levelId") + let name = Expression("entityType") + let position = Expression("position") + do { + try db.run( entityTable.create { table in + table.column(id, primaryKey: .autoincrement) + table.column(levelId) + table.column(name) + table.column(position) - func addLevel() { - + }) + print("Entity table created") + } catch { + print("Error creating table \(error)") + } } + + + func insertLevelPersistable(levelPersistable: LevelPersistable) { + guard let database = db else { + return + } + + do { + let insert = try self.levelTable.insert(levelPersistable) + try database.run(insert) + } catch { + print("Error saving level \(error)") + } + } + + func insertEntityPersistable(entityPersistable: EntityPersistable) { + guard let database = db else { + return + } + + do { + let insert = try self.entityTable.insert(entityPersistable) + try database.run(insert) + } catch { + print("Error saving entity \(error)") + } + } +} + +extension Database { + func insertJsonData() { + do { + if let fileURL = Bundle.main.url(forResource: "data", withExtension: "json") { + // Read JSON data from the file + do { + let jsonData = try Data(contentsOf: fileURL) + // Decode JSON data into LevelData + let levelData = try JSONDecoder().decode(LevelData.self, from: jsonData) + let levelPersistable = LevelPersistable(id: levelData.id, name: levelData.name) + insertLevelPersistable(levelPersistable: levelPersistable) + for entityPersistable in levelData.entities { + insertEntityPersistable(entityPersistable: entityPersistable) + } + } catch { + print("Error reading or decoding JSON: \(error)") + } + } else { + print("JSON file not found.") + } + } catch { + print(error) + } + } + + func getLevelPersistable(id: Int64) -> LevelPersistable? { + guard let database = db else { + return nil + } + let idColumn = Expression("id") + + do { + let loadedLevel: [LevelPersistable] = + try database.prepare(levelTable.filter(id == idColumn)).map { row in + let persistable: LevelPersistable = try row.decode() + return persistable + + } + if loadedLevel.isEmpty{ + return nil + } + return loadedLevel[0] + + } catch { + print("Error fetching levels \(error)") + return nil + } + } + + func getEntityPersistables(levelId: Int64) -> [EntityPersistable] { + guard let database = db else { + return [] + } + let idColumn = Expression("levelId") + + do { + let loadedEntity: [EntityPersistable] = + try database.prepare(entityTable.filter(levelId == idColumn)).map { row in + let persistable: EntityPersistable = try row.decode() + return persistable + + } + + return loadedEntity + + } catch { + print("Error fetching entity \(error)") + return [] + } + } + } diff --git a/star-dash/star-dash/Persistence/EntityPersistable.swift b/star-dash/star-dash/Persistence/EntityPersistable.swift index e194114b..a64f1d7a 100644 --- a/star-dash/star-dash/Persistence/EntityPersistable.swift +++ b/star-dash/star-dash/Persistence/EntityPersistable.swift @@ -8,18 +8,16 @@ import Foundation struct EntityPersistable: Encodable, Decodable { - var id: Int64 var levelId: Int64 var entityType: EntityType var position: CGPoint - - init(id: Int64, levelId: Int64, entityType: EntityType, position: CGPoint) { - self.id = id + + init(levelId: Int64, entityType: EntityType, position: CGPoint) { self.levelId = levelId self.entityType = entityType self.position = position } - + func toEntity() -> Entity { switch entityType { case .Monster: diff --git a/star-dash/star-dash/Persistence/LevelData.swift b/star-dash/star-dash/Persistence/LevelData.swift new file mode 100644 index 00000000..bda9ed11 --- /dev/null +++ b/star-dash/star-dash/Persistence/LevelData.swift @@ -0,0 +1,21 @@ +// +// LevelData.swift +// star-dash +// +// Created by Lau Rui han on 22/3/24. +// + +import Foundation + +struct LevelData: Encodable, Decodable { + var id: Int64 + var name: String + var entities: [EntityPersistable] + + init(id: Int64, name: String, entities: [EntityPersistable]) { + self.id = id + self.name = name + self.entities = entities + } + +} diff --git a/star-dash/star-dash/Persistence/LevelPersistable.swift b/star-dash/star-dash/Persistence/LevelPersistable.swift index 7760e9f4..e71d0e63 100644 --- a/star-dash/star-dash/Persistence/LevelPersistable.swift +++ b/star-dash/star-dash/Persistence/LevelPersistable.swift @@ -9,6 +9,7 @@ import Foundation struct LevelPersistable: Encodable, Decodable { var id: Int64 var name: String + init(id: Int64, name: String) { self.id = id self.name = name diff --git a/star-dash/star-dash/Persistence/StorageManager.swift b/star-dash/star-dash/Persistence/StorageManager.swift index a6e799c7..baaa994b 100644 --- a/star-dash/star-dash/Persistence/StorageManager.swift +++ b/star-dash/star-dash/Persistence/StorageManager.swift @@ -8,5 +8,17 @@ import Foundation class StorageManager { + let database: Database + init() { + database = Database() + } + + func getLevel(id: Int64) -> Level? { + if let levelPersistable = self.database.getLevelPersistable(id: id) { + let entityPersistabls = self.database.getEntityPersistables(levelId: id) + return Level(levelPersistable: levelPersistable, entityPersistables: entityPersistabls) + } + return nil + } } diff --git a/star-dash/star-dash/Persistence/data.json b/star-dash/star-dash/Persistence/data.json index 2820aa11..12ea3c86 100644 --- a/star-dash/star-dash/Persistence/data.json +++ b/star-dash/star-dash/Persistence/data.json @@ -1,6 +1,16 @@ { +"id": 0, "name": "1", - "obstacles": [], - "collectibles": [], - "monster": [] + "entities": [ + { + "levelId": 0, + "entityType": "obstacle", + "position": [100, 100] + }, + { + "levelId": 0, + "entityType": "obstacle", + "position": [200, 200] + } + ] } diff --git a/star-dash/star-dash/ViewController.swift b/star-dash/star-dash/ViewController.swift index cb24472b..3a6fb4c5 100644 --- a/star-dash/star-dash/ViewController.swift +++ b/star-dash/star-dash/ViewController.swift @@ -14,7 +14,7 @@ class ViewController: UIViewController { var renderer: Renderer? var gameBridge: GameBridge? var gameEngine: GameEngine? - + var storageManager: StorageManager? override func viewDidLoad() { super.viewDidLoad() @@ -25,7 +25,7 @@ class ViewController: UIViewController { let gameEngine = GameEngine() self.gameEngine = gameEngine self.gameBridge = GameBridge(entityManager: gameEngine, scene: scene) - + self.storageManager = StorageManager() setupGameEntities() guard let renderer = MTKRenderer(scene: scene) else { @@ -57,6 +57,14 @@ class ViewController: UIViewController { let floor = Floor(position: CGPoint(x: scene.size.width / 2, y: scene.size.height / 2 - 400)) floor.setUpAndAdd(to: entityManager) + + if let level = self.storageManager?.getLevel(id: 0) { + for entity in level.entities { + entity.setUpAndAdd(to: entityManager) + } + } else { + print("level not found") + } } } From 13f0e4007af9be603e429ba2cf70d49018d86e86 Mon Sep 17 00:00:00 2001 From: ruihan00 Date: Fri, 22 Mar 2024 19:02:33 +0800 Subject: [PATCH 4/5] add size to level, some optimisation --- star-dash/star-dash.xcodeproj/project.pbxproj | 12 ++++++-- star-dash/star-dash/Model/Level.swift | 4 +-- .../Persistence/Data/LevelData.swift | 16 ++++++++++ .../Persistence/{ => Data}/data.json | 1 + .../star-dash/Persistence/Database.swift | 4 ++- .../Persistence/EntityPersistable.swift | 30 +++++++++---------- .../star-dash/Persistence/LevelData.swift | 21 ------------- .../Persistence/LevelPersistable.swift | 8 ++--- 8 files changed, 48 insertions(+), 48 deletions(-) create mode 100644 star-dash/star-dash/Persistence/Data/LevelData.swift rename star-dash/star-dash/Persistence/{ => Data}/data.json (91%) delete mode 100644 star-dash/star-dash/Persistence/LevelData.swift diff --git a/star-dash/star-dash.xcodeproj/project.pbxproj b/star-dash/star-dash.xcodeproj/project.pbxproj index 911bdf14..49f2d6f0 100644 --- a/star-dash/star-dash.xcodeproj/project.pbxproj +++ b/star-dash/star-dash.xcodeproj/project.pbxproj @@ -404,12 +404,11 @@ 4E59E24F2BAB2DBB007B3FA7 /* Persistence */ = { isa = PBXGroup; children = ( + 4E59E2642BAD9A06007B3FA7 /* Data */, 4E59E2502BAB2EAE007B3FA7 /* StorageManager.swift */, 4E59E2522BAB3061007B3FA7 /* Database.swift */, - 4E59E2572BAB3B5B007B3FA7 /* data.json */, 4E59E25C2BAB405A007B3FA7 /* EntityPersistable.swift */, 4E59E2602BAB42FD007B3FA7 /* LevelPersistable.swift */, - 4E59E2622BACB9E2007B3FA7 /* LevelData.swift */, ); path = Persistence; sourceTree = ""; @@ -422,6 +421,15 @@ path = Model; sourceTree = ""; }; + 4E59E2642BAD9A06007B3FA7 /* Data */ = { + isa = PBXGroup; + children = ( + 4E59E2572BAB3B5B007B3FA7 /* data.json */, + 4E59E2622BACB9E2007B3FA7 /* LevelData.swift */, + ); + path = Data; + sourceTree = ""; + }; 4E630EE92B9F7E070008F887 = { isa = PBXGroup; children = ( diff --git a/star-dash/star-dash/Model/Level.swift b/star-dash/star-dash/Model/Level.swift index fd0e4910..db8e47de 100644 --- a/star-dash/star-dash/Model/Level.swift +++ b/star-dash/star-dash/Model/Level.swift @@ -13,9 +13,9 @@ struct Level { self.name = name self.entities = entities } - + init(levelPersistable: LevelPersistable, entityPersistables: [EntityPersistable]) { - let entities = entityPersistables.map { $0.toEntity() } + let entities = entityPersistables.compactMap { $0.toEntity() } self.init(name: levelPersistable.name, entities: entities) } } diff --git a/star-dash/star-dash/Persistence/Data/LevelData.swift b/star-dash/star-dash/Persistence/Data/LevelData.swift new file mode 100644 index 00000000..07c3a3c8 --- /dev/null +++ b/star-dash/star-dash/Persistence/Data/LevelData.swift @@ -0,0 +1,16 @@ +// +// LevelData.swift +// star-dash +// +// Created by Lau Rui han on 22/3/24. +// + +import Foundation + +struct LevelData: Codable { + var id: Int64 + var name: String + var entities: [EntityPersistable] + var size: CGSize + +} diff --git a/star-dash/star-dash/Persistence/data.json b/star-dash/star-dash/Persistence/Data/data.json similarity index 91% rename from star-dash/star-dash/Persistence/data.json rename to star-dash/star-dash/Persistence/Data/data.json index 12ea3c86..e6b72eb0 100644 --- a/star-dash/star-dash/Persistence/data.json +++ b/star-dash/star-dash/Persistence/Data/data.json @@ -1,6 +1,7 @@ { "id": 0, "name": "1", + "size": [1000, 200], "entities": [ { "levelId": 0, diff --git a/star-dash/star-dash/Persistence/Database.swift b/star-dash/star-dash/Persistence/Database.swift index c07dd72a..08d586e2 100644 --- a/star-dash/star-dash/Persistence/Database.swift +++ b/star-dash/star-dash/Persistence/Database.swift @@ -62,10 +62,12 @@ struct Database { } let id = Expression("id") let name = Expression("name") + let size = Expression("size") do { try db.run( levelTable.create { table in table.column(id, primaryKey: true) table.column(name) + table.column(size) }) print("Level table created") } catch { @@ -132,7 +134,7 @@ extension Database { let jsonData = try Data(contentsOf: fileURL) // Decode JSON data into LevelData let levelData = try JSONDecoder().decode(LevelData.self, from: jsonData) - let levelPersistable = LevelPersistable(id: levelData.id, name: levelData.name) + let levelPersistable = LevelPersistable(id: levelData.id, name: levelData.name, size: levelData.size) insertLevelPersistable(levelPersistable: levelPersistable) for entityPersistable in levelData.entities { insertEntityPersistable(entityPersistable: entityPersistable) diff --git a/star-dash/star-dash/Persistence/EntityPersistable.swift b/star-dash/star-dash/Persistence/EntityPersistable.swift index a64f1d7a..35455fe4 100644 --- a/star-dash/star-dash/Persistence/EntityPersistable.swift +++ b/star-dash/star-dash/Persistence/EntityPersistable.swift @@ -7,27 +7,25 @@ import Foundation -struct EntityPersistable: Encodable, Decodable { +struct EntityPersistable: Codable { var levelId: Int64 var entityType: EntityType var position: CGPoint - init(levelId: Int64, entityType: EntityType, position: CGPoint) { - self.levelId = levelId - self.entityType = entityType - self.position = position - } - func toEntity() -> Entity { - switch entityType { - case .Monster: - return Monster(position: self.position) - case .Collectible: - return Collectible(position: self.position) - case .Obstacle: - return Obstacle(position: self.position) - case .Tool: - return Tool(position: self.position) + func toEntity() -> Entity? { + // Define a map to store the creation functions for each entity type + var entityMap: [EntityType: () -> Entity] = [:] + + // Populate the map with creation functions for each entity type + entityMap[.Monster] = { Monster(position: self.position) } + entityMap[.Collectible] = { Collectible(position: self.position) } + entityMap[.Obstacle] = { Obstacle(position: self.position) } + entityMap[.Tool] = { Tool(position: self.position) } + + guard let entity = entityMap[self.entityType] else { + return nil } + return entity() } } diff --git a/star-dash/star-dash/Persistence/LevelData.swift b/star-dash/star-dash/Persistence/LevelData.swift deleted file mode 100644 index bda9ed11..00000000 --- a/star-dash/star-dash/Persistence/LevelData.swift +++ /dev/null @@ -1,21 +0,0 @@ -// -// LevelData.swift -// star-dash -// -// Created by Lau Rui han on 22/3/24. -// - -import Foundation - -struct LevelData: Encodable, Decodable { - var id: Int64 - var name: String - var entities: [EntityPersistable] - - init(id: Int64, name: String, entities: [EntityPersistable]) { - self.id = id - self.name = name - self.entities = entities - } - -} diff --git a/star-dash/star-dash/Persistence/LevelPersistable.swift b/star-dash/star-dash/Persistence/LevelPersistable.swift index e71d0e63..ff629912 100644 --- a/star-dash/star-dash/Persistence/LevelPersistable.swift +++ b/star-dash/star-dash/Persistence/LevelPersistable.swift @@ -6,13 +6,9 @@ // import Foundation -struct LevelPersistable: Encodable, Decodable { +struct LevelPersistable: Codable { var id: Int64 var name: String - - init(id: Int64, name: String) { - self.id = id - self.name = name - } + var size: CGSize } From 1029931e3135afd34c80e113987a28f804759269 Mon Sep 17 00:00:00 2001 From: ruihan00 Date: Fri, 22 Mar 2024 19:26:43 +0800 Subject: [PATCH 5/5] change entity map to static --- .../Persistence/EntityPersistable.swift | 19 ++++++++----------- .../Persistence/StorageManager.swift | 8 ++++---- 2 files changed, 12 insertions(+), 15 deletions(-) diff --git a/star-dash/star-dash/Persistence/EntityPersistable.swift b/star-dash/star-dash/Persistence/EntityPersistable.swift index 35455fe4..a53aff57 100644 --- a/star-dash/star-dash/Persistence/EntityPersistable.swift +++ b/star-dash/star-dash/Persistence/EntityPersistable.swift @@ -11,21 +11,18 @@ struct EntityPersistable: Codable { var levelId: Int64 var entityType: EntityType var position: CGPoint - + static var entityMap: [EntityType: (CGPoint) -> Entity] = [ + .Monster: { position in Monster(position: position) }, + .Collectible: { position in Collectible(position: position) }, + .Obstacle: { position in Obstacle(position: position) }, + .Tool: { position in Tool(position: position) } + ] func toEntity() -> Entity? { - // Define a map to store the creation functions for each entity type - var entityMap: [EntityType: () -> Entity] = [:] - // Populate the map with creation functions for each entity type - entityMap[.Monster] = { Monster(position: self.position) } - entityMap[.Collectible] = { Collectible(position: self.position) } - entityMap[.Obstacle] = { Obstacle(position: self.position) } - entityMap[.Tool] = { Tool(position: self.position) } - - guard let entity = entityMap[self.entityType] else { + guard let entity = EntityPersistable.entityMap[self.entityType] else { return nil } - return entity() + return entity(self.position) } } diff --git a/star-dash/star-dash/Persistence/StorageManager.swift b/star-dash/star-dash/Persistence/StorageManager.swift index baaa994b..1786f722 100644 --- a/star-dash/star-dash/Persistence/StorageManager.swift +++ b/star-dash/star-dash/Persistence/StorageManager.swift @@ -9,15 +9,15 @@ import Foundation class StorageManager { let database: Database - + init() { database = Database() } - + func getLevel(id: Int64) -> Level? { if let levelPersistable = self.database.getLevelPersistable(id: id) { - let entityPersistabls = self.database.getEntityPersistables(levelId: id) - return Level(levelPersistable: levelPersistable, entityPersistables: entityPersistabls) + let entityPersistables = self.database.getEntityPersistables(levelId: id) + return Level(levelPersistable: levelPersistable, entityPersistables: entityPersistables) } return nil }