Skip to content

Commit

Permalink
CATTY-446 Parse multiple scenes
Browse files Browse the repository at this point in the history
  • Loading branch information
afibian committed Feb 1, 2021
1 parent cfe05fe commit 573b183
Show file tree
Hide file tree
Showing 69 changed files with 493 additions and 330 deletions.
16 changes: 16 additions & 0 deletions src/Catty.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@

/* Begin PBXBuildFile section */
05501DE7255E106F00C64E58 /* color_change.dst in Resources */ = {isa = PBXBuildFile; fileRef = 05501DE4255E106F00C64E58 /* color_change.dst */; };
05744DF925C84328005455F9 /* XMLParseMultipleScenesTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 05744DF825C84328005455F9 /* XMLParseMultipleScenesTests.swift */; };
05744E0A25C8437C005455F9 /* MultipleScenes.xml in Resources */ = {isa = PBXBuildFile; fileRef = 05744E0925C8437C005455F9 /* MultipleScenes.xml */; };
05A3CE6D24F5164A0051DB39 /* CatrobatTableViewControllerExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 05A3CE6A24F516490051DB39 /* CatrobatTableViewControllerExtension.swift */; };
05A3D46824F517220051DB39 /* StoreProjectTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 05A3D46724F517220051DB39 /* StoreProjectTests.swift */; };
05A3D46A24F517350051DB39 /* CatrobatTableViewControllerExtensionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 05A3D46924F517350051DB39 /* CatrobatTableViewControllerExtensionTests.swift */; };
Expand Down Expand Up @@ -1853,6 +1855,8 @@
04A3B489CBF02EB8C919DC3B /* sr */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.strings; name = sr; path = sr.lproj/Localizable.strings; sourceTree = "<group>"; };
04FC473CDF0FCFB7BD890320 /* el */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.strings; name = el; path = el.lproj/Localizable.strings; sourceTree = "<group>"; };
05501DE4255E106F00C64E58 /* color_change.dst */ = {isa = PBXFileReference; lastKnownFileType = file; path = color_change.dst; sourceTree = "<group>"; };
05744DF825C84328005455F9 /* XMLParseMultipleScenesTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = XMLParseMultipleScenesTests.swift; sourceTree = "<group>"; };
05744E0925C8437C005455F9 /* MultipleScenes.xml */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = MultipleScenes.xml; sourceTree = "<group>"; };
05A3CE6A24F516490051DB39 /* CatrobatTableViewControllerExtension.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CatrobatTableViewControllerExtension.swift; sourceTree = "<group>"; };
05A3D46724F517220051DB39 /* StoreProjectTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StoreProjectTests.swift; sourceTree = "<group>"; };
05A3D46924F517350051DB39 /* CatrobatTableViewControllerExtensionTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CatrobatTableViewControllerExtensionTests.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -4298,6 +4302,14 @@
/* End PBXFrameworksBuildPhase section */

/* Begin PBXGroup section */
05744DEF25C84234005455F9 /* MultipleScenes */ = {
isa = PBXGroup;
children = (
05744E0925C8437C005455F9 /* MultipleScenes.xml */,
);
path = MultipleScenes;
sourceTree = "<group>";
};
05E68011255B5DAA00D1E295 /* Embroidery */ = {
isa = PBXGroup;
children = (
Expand Down Expand Up @@ -4960,6 +4972,7 @@
2ED4175F241120AF00AFE2FD /* Custom */ = {
isa = PBXGroup;
children = (
05744DEF25C84234005455F9 /* MultipleScenes */,
9E384934256191DC002D8F28 /* SamplerBricks */,
D3EBE87C2488E6A90026F51A /* GoToBricks */,
D3AF5C1C243F81FC00B04BC6 /* DisabledBricks */,
Expand Down Expand Up @@ -5305,6 +5318,7 @@
4C2CBB3A25A5AA8400C1C143 /* CatrobatLanguage0.993 */,
4C2CBB0825A5AA8400C1C143 /* UserListXMLHandlerTests.m */,
4C2CBB0725A5AA8400C1C143 /* SceneXMLHandlerTest.m */,
05744DF825C84328005455F9 /* XMLParseMultipleScenesTests.swift */,
);
path = "Parser & Serialization";
sourceTree = "<group>";
Expand Down Expand Up @@ -11080,6 +11094,7 @@
2D7BE51E21441DE500F78A10 /* StoreProjectDownloader.searchProjects.success.json in Resources */,
4C55CCE924BF2AA700FB8393 /* Nyancat_1.0_0992.xml in Resources */,
4C55CD0F24BF2C0600FB8393 /* ReplaceItemInUserListBrick0992.xml in Resources */,
05744E0A25C8437C005455F9 /* MultipleScenes.xml in Resources */,
2DCB4928212EA477005E8E3D /* StoreProjectDownloader.fetchMostViewedProjects.fail.request.json in Resources */,
2ED41844241120B000AFE2FD /* Minions__093.xml in Resources */,
2ED41875241120B000AFE2FD /* LedFlashBrick0991.xml in Resources */,
Expand Down Expand Up @@ -11626,6 +11641,7 @@
5912C21623C4EAC700B3D9C0 /* FormulaTest.swift in Sources */,
9E2C2D8E23257387004B66C6 /* AbstractBrickTest.swift in Sources */,
4CD487761ED2C2A3001BB80A /* ChangeVariableBrickTests.swift in Sources */,
05744DF925C84328005455F9 /* XMLParseMultipleScenesTests.swift in Sources */,
E57E6D85254040B400E775DF /* ChangeVolumeByNBrickTests.swift in Sources */,
4C0A209824CEA46700CC9B04 /* PaintViewControllerMock.swift in Sources */,
4C82267B213FA7A400F3D750 /* BackgroundNumberSensorTest.swift in Sources */,
Expand Down
20 changes: 0 additions & 20 deletions src/Catty.xcodeproj/xcshareddata/xcschemes/Catty (DEBUG).xcscheme
Original file line number Diff line number Diff line change
Expand Up @@ -77,26 +77,6 @@
ReferencedContainer = "container:Catty.xcodeproj">
</BuildableReference>
</TestableReference>
<TestableReference
skipped = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "AAADA0031B9B29D500E0CA9A"
BuildableName = "Catty UITests.xctest"
BlueprintName = "Catty UITests"
ReferencedContainer = "container:Catty.xcodeproj">
</BuildableReference>
</TestableReference>
<TestableReference
skipped = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "92EC98A91BC3C32A0003A891"
BuildableName = "BluetoothHelperTests.xctest"
BlueprintName = "BluetoothHelperTests"
ReferencedContainer = "container:Catty/BluetoothHelper/BluetoothHelper.xcodeproj">
</BuildableReference>
</TestableReference>
</Testables>
</TestAction>
<LaunchAction
Expand Down
4 changes: 3 additions & 1 deletion src/Catty/DataModel/Project/Project.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,9 @@
@interface Project : NSObject

@property (nonatomic, strong, nonnull) Header *header;
@property (nonatomic, strong, nonnull) Scene *scene;
@property (nonatomic, strong, nonnull) NSMutableArray<Scene*> *scenes;
@property (nonatomic, strong, nonnull) Scene *scene DEPRECATED_ATTRIBUTE; //needed for compadability with "Old Parser"
@property (nonatomic, strong, nonnull) Scene *activeScene;
@property (nonatomic, strong, nonnull) UserDataContainer *userData;
@property (nonatomic, strong, nonnull) NSMutableSet<NSString*> *unsupportedElements;
@property (nonatomic) BOOL requiresBluetooth;
Expand Down
53 changes: 36 additions & 17 deletions src/Catty/DataModel/Project/Project.m
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ - (instancetype)init
{
_allBroadcastMessages = [[NSMutableOrderedSet alloc] init];
}
self.scenes = [[NSMutableArray alloc] init];
[self.scenes addObject: [[Scene alloc] init]];
return self;
}

Expand Down Expand Up @@ -153,7 +155,11 @@ - (void)renameToProjectName:(NSString*)projectName andProjectId:(NSString*)proje

- (NSArray<SpriteObject*>*)allObjects
{
return self.scene.objects;
NSMutableArray<SpriteObject*> *objects = [[NSMutableArray<SpriteObject*> alloc] init];
for (Scene* scene in self.scenes) {
[objects addObjectsFromArray: [scene objects]];
}
return objects;
}

- (void)setDescription:(NSString*)description
Expand All @@ -163,7 +169,9 @@ - (void)setDescription:(NSString*)description

- (void)removeReferences
{
[self.scene.objects makeObjectsPerformSelector:@selector(removeReferences)];
for (Scene* scene in self.scenes){
[scene.objects makeObjectsPerformSelector:@selector(removeReferences)];
}
}

- (BOOL)isEqualToProject:(Project*)project
Expand All @@ -172,14 +180,23 @@ - (BOOL)isEqualToProject:(Project*)project
return NO;
if (! [self.userData isEqual:project.userData])
return NO;
if (![self.scene isEqual:project.scene])
if ([self.scenes count] != [project.scenes count])
return NO;
for (int i = 0; i < [self.scenes count]; ++i) {
if (![[self.scenes objectAtIndex: i] isEqual: [project.scenes objectAtIndex: i]])
return NO;
}

return YES;
}

- (NSInteger)getRequiredResources
{
return [self.scene getRequiredResources];
NSInteger requiredResources = 0;
for (Scene* scene in self.scenes) {
requiredResources |= [scene getRequiredResources];
}
return requiredResources;
}
#pragma mark - helpers

Expand All @@ -204,7 +221,7 @@ - (NSString*)description
[ret appendFormat:@"Screen Height: %@\n", self.header.screenHeight];
[ret appendFormat:@"Screen Width: %@\n", self.header.screenWidth];
[ret appendFormat:@"Screen Mode: %@\n", self.header.screenMode];
[ret appendFormat:@"Scene: %@\n", self.scene];
[ret appendFormat:@"First Scene: %@\n", [self.scenes objectAtIndex:0]];
[ret appendFormat:@"URL: %@\n", self.header.url];
[ret appendFormat:@"User Handle: %@\n", self.header.userHandle];
[ret appendFormat:@"Variables: %@\n", self.userData];
Expand Down Expand Up @@ -401,19 +418,21 @@ + (void)removeProjectFromDiskWithProjectName:(NSString*)projectName projectID:(N

- (void)translateDefaultProject
{
NSUInteger index = 0;
for (SpriteObject *spriteObject in self.scene.objects) {
if (index == kBackgroundObjectIndex) {
spriteObject.name = kLocalizedBackground;
} else {
NSMutableString *spriteObjectName = [NSMutableString stringWithString:spriteObject.name];
[spriteObjectName replaceOccurrencesOfString:kDefaultProjectBundleOtherObjectsNamePrefix
withString:kLocalizedMole
options:NSCaseInsensitiveSearch
range:NSMakeRange(0, spriteObjectName.length)];
spriteObject.name = (NSString*)spriteObjectName;
for (Scene* scene in self.scenes) {
NSUInteger index = 0;
for (SpriteObject *spriteObject in scene.objects) {
if (index == kBackgroundObjectIndex) {
spriteObject.name = kLocalizedBackground;
} else {
NSMutableString *spriteObjectName = [NSMutableString stringWithString:spriteObject.name];
[spriteObjectName replaceOccurrencesOfString:kDefaultProjectBundleOtherObjectsNamePrefix
withString:kLocalizedMole
options:NSCaseInsensitiveSearch
range:NSMakeRange(0, spriteObjectName.length)];
spriteObject.name = (NSString*)spriteObjectName;
}
++index;
}
++index;
}
[self renameToProjectName:kLocalizedMyFirstProject andShowSaveNotification:NO]; // saves to disk!
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,10 @@ extension UIViewController {

@objc func openProject(_ project: Project) {
let storyboard = UIStoryboard.init(name: "iPhone", bundle: nil)
guard let viewController = storyboard.instantiateViewController(withIdentifier: "SceneTableViewController") as? SceneTableViewController else { return }
guard let viewController = storyboard.instantiateViewController(withIdentifier: "SceneTableViewController")
as? SceneTableViewController, let scene = project.scenes[0] as? Scene else { return }

viewController.scene = project.scene
viewController.scene = scene
project.setAsLastUsedProject()

self.navigationController?.pushViewController(viewController, animated: true)
Expand Down
14 changes: 8 additions & 6 deletions src/Catty/IO/ProjectManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -31,32 +31,34 @@

let project = Project()
let projectName = Util.uniqueName(name, existingNames: Project.allProjectNames())
project.scene = Scene(name: Util.defaultSceneName(forSceneNumber: 1))
project.scene.project = project
project.header = Header.default()
project.header.programName = projectName
project.header.programID = projectId

let scene = Scene(name: Util.defaultSceneName(forSceneNumber: 1))
scene.project = project

if fileManager.directoryExists(projectName) == false {
fileManager.createDirectory(project.projectPath())
}

let sceneDir = project.scene.path()
let sceneDir = scene.path()
if !fileManager.directoryExists(sceneDir) {
fileManager.createDirectory(sceneDir)
}

let imagesDirName = project.scene.imagesPath()
let imagesDirName = scene.imagesPath()
if fileManager.directoryExists(imagesDirName) == false {
fileManager.createDirectory(imagesDirName)
}

let soundDirName = project.scene.soundsPath()
let soundDirName = scene.soundsPath()
if fileManager.directoryExists(soundDirName) == false {
fileManager.createDirectory(soundDirName)
}

project.scene.addObject(withName: kLocalizedBackground)
scene.addObject(withName: kLocalizedBackground)
project.scenes[0] = scene

let filePath = project.projectPath() + kScreenshotAutoFilename
let projectIconNames = UIDefines.defaultScreenshots
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,25 +42,24 @@ + (instancetype)parseFromElement:(GDataXMLElement*)xmlElement withContext:(CBXML
[XMLError exceptionIfNode:xmlElement isNilOrNodeNameNotEquals:@"program"];
[XMLError exceptionIfNil:context message:@"No context given!"];
Project *project = [Project new];
[project.scenes removeAllObjects];
// IMPORTANT: DO NOT CHANGE ORDER HERE!!
project.header = [self parseAndCreateHeaderFromElement:xmlElement withContext:context];
project.userData = [self parseAndCreateVariablesFromElement:xmlElement withContext:context];
if ([xmlElement childWithElementName:@"scenes"]) {
Scene *scene = [self parseAndCreateSceneFromElement:xmlElement withContext:context];
scene.project = project;
project.scene = scene;
[self parseAndCreateSceneFromElement:xmlElement ofProject:project withContext:context];
} else {
project.scene = [[Scene alloc] initWithName: [Util defaultSceneNameForSceneNumber:1]];
project.scene.project = project;
Scene *scene = [[Scene alloc] initWithName: [Util defaultSceneNameForSceneNumber:1]];
project.scenes[0] = scene;
scene.project = project;
for (SpriteObject *object in [Scene parseAndCreateObjectsFromElement:xmlElement withContext:context]) {
//when project will contain [scenes] then object.scene will be equal to scene where the objects belongs to
object.scene = project.scene;
object.scene = scene;
object.scene.project = project;
//when project will contain [scenes] then object will be added to the scene where it belongs and add scene to [scene] of project
[project.scene addObject:object];
[scene addObject:object];
}
}

return project;
}

Expand Down Expand Up @@ -93,7 +92,8 @@ + (SpriteObject *)getSpriteObject:(NSString*)spriteName withContext:(CBXMLParser
return object;
}

+ (Scene *)parseAndCreateSceneFromElement:(GDataXMLElement*)projectElement withContext:(CBXMLParserContext*)context
+ (void)parseAndCreateSceneFromElement:(GDataXMLElement*)projectElement
ofProject: (Project*)project withContext:(CBXMLParserContext*)context
{
NSArray *scenesElements = [projectElement elementsForName:@"scenes"];
[XMLError exceptionIf:[scenesElements count] notEquals:1 message:@"No scenes given!"];
Expand All @@ -102,17 +102,23 @@ + (Scene *)parseAndCreateSceneFromElement:(GDataXMLElement*)projectElement withC
message:@"No scene in scenes, but there must exist "\
"at least 1 scene!!"];

GDataXMLElement *sceneElement = [sceneElements firstObject];
Scene *scene = [context parseFromElement:sceneElement withClass:[Scene class]];

return scene;
for (GDataXMLElement *sceneElement in sceneElements) {
Scene* scene = [context parseFromElement:sceneElement withClass:[Scene class]];
scene.project = project;
[project.scenes addObject: scene];
[context.spriteObjectList removeAllObjects];
[context.pointedSpriteObjectList removeAllObjects];
}
return;
}

#pragma mark - Serialization
- (GDataXMLElement*)xmlElementWithContext:(CBXMLSerializerContext*)context
{
Scene* scene = [self.scenes objectAtIndex:0];

// update context object
context.spriteObjectList = [[NSMutableArray alloc] initWithArray:self.scene.objects];
context.spriteObjectList = [[NSMutableArray alloc] initWithArray: scene.objects];

// generate xml element for program
GDataXMLElement *xmlElement = [GDataXMLElement elementWithName:@"program" context:context];
Expand All @@ -122,7 +128,7 @@ - (GDataXMLElement*)xmlElementWithContext:(CBXMLSerializerContext*)context
[xmlElement addChild:[GDataXMLElement elementWithName:@"settings" context:nil]];

GDataXMLElement *scenes = [GDataXMLElement elementWithName:@"scenes" context:context];
[scenes addChild:[self.scene xmlElementWithContext:context] context:context];
[scenes addChild:[scene xmlElementWithContext:context] context:context];
[xmlElement addChild:scenes context:context];

if (self.userData) {
Expand Down
1 change: 1 addition & 0 deletions src/Catty/Parser&Serialializer/Old Parser/ProjectParser.m
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ - (id)loadProject:(NSData*)xmlData {
@try {
NSInfo(@"Loading Project...");
project = [self parseNode:doc.rootElement withParent:nil];
project.scenes[0] = project.scene;
NSInfo(@"Loading done...");
} @catch(NSException* ex) {
NSError(@"Project could not be loaded! %@", [ex description]);
Expand Down
4 changes: 1 addition & 3 deletions src/Catty/PlayerEngine/Frontend/CBFrontend.swift
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,11 @@ final class CBFrontend: CBFrontendProtocol {

// MARK: - Properties
let logger: CBLogger
private(set) weak var project: Project?
private lazy var _sequenceFilters = [CBFrontendSequenceFilterProtocol]()

// MARK: - Initializers
init(logger: CBLogger, project: Project?) {
init(logger: CBLogger) {
self.logger = logger
self.project = project
}

// MARK: - Operations
Expand Down
3 changes: 0 additions & 3 deletions src/Catty/PlayerEngine/Protocols/CBFrontendProtocol.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,6 @@

protocol CBFrontendProtocol {

var project: Project? { get }

func computeSequenceListForScript(_ script: Script) -> CBScriptSequenceList
func addSequenceFilter(_ sequenceFilter: CBFrontendSequenceFilterProtocol)

}
4 changes: 2 additions & 2 deletions src/Catty/PlayerEngine/Sensors/Object/LayerSensor.swift
Original file line number Diff line number Diff line change
Expand Up @@ -61,11 +61,11 @@
}

static func defaultRawValue(for spriteObject: SpriteObject) -> Double {
guard let project = spriteObject.scene.project else {
guard let scene = spriteObject.scene else {
return defaultRawValue
}

let objectList = project.scene.objects()
let objectList = scene.objects()
var zPosition = defaultRawValue
for object in objectList {
if object == spriteObject {
Expand Down
Loading

0 comments on commit 573b183

Please sign in to comment.