-
Notifications
You must be signed in to change notification settings - Fork 108
GSoC 2018 Cadence Holmes
Schedule - CST (GMT -5)
Sun | Mon | Tue | Wed | Thu | Fri | Sat |
---|---|---|---|---|---|---|
Available | 10am - 5pm | 10am - 5pm | 10am - 5pm | Available | 10am - 5pm | 10am - 5pm |
I'm a music major. Well, I'm a PhD candidate in Experimental Music and Digital Media, but my degree will technically come from the School of Music. I've never taken a formal comp sci or coding class. I got into programming when learning Csound to compose electronic music, and it's been an up-and-down ride since then. Now I primarily do web and mobile development, most often for art and/or social justice/awareness/growth, and I'm always looking for new opportunities to learn.
I fancy myself a multi-media artist. My portfolio includes music, visual art, installations, as well as mobile and web apps. I'm really interested in subversive processes where common tools and techniques are used in uncommon ways to produce new kinds of art.
As a researcher, I tend towards user experience and interaction design, especially concerning technology for STEAM education and informal learning.
Out-of-Character Contextual Information for PowerUp!
- I've met and chatted with several people!
- I've taken this time to become more familiar with the PowerUp iOS codebase and database.
- In order to move forward with my proposal, it was necessary to map out the current Q&A database. It turned out to be a bit of a pain to do manually, so I created a web app that automatically parses the tables and lays out the records in a connected tree. It's been a huge help to me in planning my time tables, but I think it's also going to be a big help as we try to clean up and improve on the current scenario writing. https://github.com/justKD/Sqlite-GoJS-DB-Map
- When forming my original proposal, I knew the writing in the current app could be improved on, but I wasn't aware of how fragmented the database was going to be. A big part of what I want to contribute is not just code, but also resources to use in order to improve the outcomes we could expect from the app. I'm having to rethink what that contribution might look like!
- Not yet. But I've started looking into helping with the scenario writing in general.
- I'm mulling over how to best help with the scenario writing. It's a little overwhelming for a number of reasons, but I started another web app that might be able to help with designing scenarios more efficiently.
- I'm also finalizing my design plans for the classes I need to implement. I want to ensure the new functionality leaves a minimal footprint on existing code.
- I think things are on track. Coding officially starts Monday!
-
I shared a different take on the mapper tool. The Sqlite mapper is still useful for checking the current state of the database, but I also have been working on a tool to help create and edit scenarios. I shared it with the PowerUp team at our weekly meeting. It's already been useful to me in creating dummy data for testing, but I think it can be used as a general tool for building and maintaining branching scenarios. Detailed description in the readme. https://github.com/justKD/powerup-scenario-builder
-
I started writing classes to handle the out-of-context events I've proposed. I've finished a working initial version of the popup controller. Right now the scenario view controller is checking for and presenting the popups, but they could also be added to mini-games.
I'm trying to build the class to be as easy-to-use as possible, and especially trying to leave the smallest footprint on existing code as I can. By subclassing UIView and using a delegate method, the view can be added and released all from an instanced variable rather than creating a strong reference to a persistent view. Here's an example of launching a popup:
guard let popups = PopupEvents().scenarioPopups[scenarioID] else { return }
guard let model: PopupEvent = popups[popupID] else { return }
let event: PopupEventPlayer? = PopupEventPlayer(delegate: self, model: model)
guard let popup = event else { return }
self.view.addSubview(popup)
/* Line by line, this code:
- retrieves the collection of popups for the current scenario
- retrieves/initializes a model
- initializes a local instance of the PopupEventPlayerClass, assigning the presenting controller as the delegate
- checks to ensure a everything's worked so far
- adds the view to the controller - the class handles it's own geometry, animations, sound, and interactions
- (the model provides strings, badge image name, and checks for sound)
*/
- It times itself for automatic dismissal, or can be tapped to manually dismiss it. Then it calls the delegate method where it can be removed from the main view, and ARC handles the rest.
func popupDidFinish(sender: PopupEventPlayer) {
sender.removeFromSuperview()
}
-
You can check out the entire class here: PopupEventPlayer.swift on GitHub
-
I added a new field to the Answer table for popupID, and have a model file to hold a list of the popup models. Something like this:
let popupEvents = [
1: PopupEvent(mainText: "test model 1",
subText: "has sound",
image: "minesweeper_abstinence_heart",
useSound: true),
2: etc.
-
The only changes to existing code were:
- Change the answer model to include the popupID field
- Change the database accessor to include a constant for the new field and return it in the answer model
- Call the function to present the popup when an answer is selected
- Declare the view controller as the delegate and add the delegate method
-
After finishing this class, I created test data and have been trying to put the class through the paces. It should always gracefully exit any functions (or just ignore a field) if anything is wonky, but never cause a fatal error.
-
I also updated existing unit tests to ensure they still pass.
- Nothing serious. It's kind of a pain switching back and forth between javascript and swift. They are similar enough in syntax to cause muscle memory headaches.
- I was looking into creating UI tests for the class. Setting them up is a little different from unit test cases, so it wasn't as easy as just adding a test class to the existing test target.
- I'm getting there. I just need some more time getting back into the Swift groove.
- I'm going to try and get the target for UI tests set up this week.
- I'm going to work on getting the UI test environment ready and design tests for the PopupEventController class.
- And I'm going to start work on the intro and outro story sequence classes.
- My original plan is having to change a bit since the current scenario content is evolving. I'm on track to finish the code infrastructure by the end of the first coding period.
- I finished a first working version of the StorySequencePlayer class. It handles stepping through a collection of events that each describe a scene. Each step contains a left and right component that describes an image, text, and animations. Similar to the PopupEventPlayer class, StorySequencePlayer is designed to be as self-contained as possible.
guard let model = StorySequences().intros[scenarioID] else { return }
let sequenceView: StorySequencePlayer = StorySequencePlayer(delegate: self, model: model)
self.view.addSubview(sequenceView)
/*
- get the collection of scenario intros and retrieve the correct model if it exists
- create an instanced StorySequencePlayer passing the delegate and model
- add to top view
*/
- I also wrote a class to help create animations. It's based off of a concept that I've used in objective-c, but I think swift improves it greatly.
- I'm using this class to animate events in the story sequences, but it could be used elsewhere in the app
/*
- The Animate class attaches to any UIView and lets it be animated using a pseudo-sentence syntax
- You can chain together events that should happen simultaneously using .function()
- And you can chain together timed events using the optional callback function then: {}
- Animate includes functions for basic transforms, as well as some other pre-designed more complex animations
*/
Animate(view, duration).setOptions(.curveLinear).rotate(to: 90)
let view = Animate(view, duration)
view.setSpring(damping, velocity).translate(by: [50, 0], then: {
view.flip().shake(then: {
view.reset()
})
})
- I'm not used to actually working with other people in a git project. I'm usually free to be sloppy and make random edits and changes without explanation, and then merging a big chunk of well-worked code.
- I think so. I just have to be careful and actually think about how I'm structuring changes in branches and commits.
- Tests for the new OOC classes.
- Still on track to finish coding the main infrastructure to handle OOC events by the end of the first coding period.