Skip to content

Commit

Permalink
Merge pull request #655 from co-merge
Browse files Browse the repository at this point in the history
  • Loading branch information
release-train[bot] committed Oct 4, 2019
2 parents 30dbbe2 + 5ca0279 commit 2fc3241
Show file tree
Hide file tree
Showing 9 changed files with 348 additions and 448 deletions.
20 changes: 19 additions & 1 deletion packages/bemuse-notechart/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -204,14 +204,32 @@ export class Notechart {
return this._spacing.factor(beat)
}

/**
* Gets the keyMode from scratch
* @param scratch
* @returns {string}
*/
getKeyMode(scratch: string): string {
const usedColumns: { [column: string]: boolean } = {}
for (const note of this.notes) {
usedColumns[note.column] = true
}
if (scratch === 'off' && !usedColumns['1'] && !usedColumns['7']) return '5K'
if (scratch === 'left' && !usedColumns['6'] && !usedColumns['7'])
return '5K'
if (scratch === 'right' && !usedColumns['1'] && !usedColumns['2'])
return '5K'
return '7K'
}

_preTransform(
bmsNotes: BMS.BMSNote[],
playerOptions: Partial<PlayerOptions>
) {
let chain = _.chain(bmsNotes)
let keys = getKeys(bmsNotes)
if (playerOptions.scratch === 'off') {
chain = chain.map(note => {
chain = chain.map((note: BMS.BMSNote) => {
if (note.column && note.column === 'SC') {
return Object.assign({}, note, { column: null })
} else {
Expand Down
71 changes: 29 additions & 42 deletions packages/bemuse-tools/src/audio.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import Promise from 'bluebird'
import co from 'co'
import fs from 'fs'
import Throat from 'throat'
import { cpus } from 'os'
Expand Down Expand Up @@ -28,47 +27,35 @@ export class AudioConvertor {
_doConvert(path, type) {
return this._SoX(path, type)
}
// TODO [#621]: Convert the `_SoX` method to async function (instead of using `co`) in [bemuse-tools] src/audio.js
// See issue #575 for more details.
_SoX(path, type) {
return co(
function*() {
let typeArgs = []
try {
let fd = yield Promise.promisify(fs.open, fs)(path, 'r')
let buffer = Buffer.alloc(4)
let read = yield Promise.promisify(fs.read, fs)(
fd,
buffer,
0,
4,
null
)
yield Promise.promisify(fs.close, fs)(fd)
if (read === 0) {
console.error('[WARN] Empty keysound file.')
} else if (
buffer[0] === 0x49 &&
buffer[1] === 0x44 &&
buffer[2] === 0x33
) {
typeArgs = ['-t', 'mp3']
} else if (buffer[0] === 0xff && buffer[1] === 0xfb) {
typeArgs = ['-t', 'mp3']
} else if (
buffer[0] === 0x4f &&
buffer[1] === 0x67 &&
buffer[2] === 0x67 &&
buffer[3] === 0x53
) {
typeArgs = ['-t', 'ogg']
}
} catch (e) {
console.error('[WARN] Unable to detect file type!')
}
return yield this._doSoX(path, type, typeArgs)
}.bind(this)
)
async _SoX(path, type) {
let typeArgs = []
try {
let fd = await Promise.promisify(fs.open)(path, 'r')
let buffer = Buffer.alloc(4)
let read = await Promise.promisify(fs.read)(fd, buffer, 0, 4, null)
await Promise.promisify(fs.close)(fd)
if (read === 0) {
console.error('[WARN] Empty keysound file.')
} else if (
buffer[0] === 0x49 &&
buffer[1] === 0x44 &&
buffer[2] === 0x33
) {
typeArgs = ['-t', 'mp3']
} else if (buffer[0] === 0xff && buffer[1] === 0xfb) {
typeArgs = ['-t', 'mp3']
} else if (
buffer[0] === 0x4f &&
buffer[1] === 0x67 &&
buffer[2] === 0x67 &&
buffer[3] === 0x53
) {
typeArgs = ['-t', 'ogg']
}
} catch (e) {
console.error('[WARN] Unable to detect file type!')
}
return this._doSoX(path, type, typeArgs)
}
_doSoX(path, type, inputTypeArgs) {
return throat(
Expand Down
30 changes: 13 additions & 17 deletions src/auto-synchro/music/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import _ from 'lodash'
import co from 'co'
import context from 'bemuse/audio-context'
import download from 'bemuse/utils/download'
import SamplingMaster from 'bemuse/sampling-master'
Expand All @@ -17,24 +16,21 @@ let ASSET_URLS = {
/**
* Loads the files and create a music instance.
*/
export function load() {
// TODO [#626]: Convert the `load` function to async function (instead of using `co`) in src/auto-synchro/music.js
// See issue #575 for more details.
return co(function*() {
let master = new SamplingMaster(context)
let sample = name =>
download(ASSET_URLS[`${name}.ogg`])
.as('arraybuffer')
.then(buf => master.sample(buf))
let samples = _.fromPairs(
yield Promise.all(
['bgm', 'intro', 'kick', 'snare'].map(name =>
sample(name).then(sampleObj => [name, sampleObj])
)
export async function load() {
let master = new SamplingMaster(context)

let sample = name =>
download(ASSET_URLS[`${name}.ogg`])
.as('arraybuffer')
.then(buf => master.sample(buf))
let samples = _.fromPairs(
await Promise.all(
['bgm', 'intro', 'kick', 'snare'].map(name =>
sample(name).then(sampleObj => [name, sampleObj])
)
)
return music(master, samples)
})
)
return music(master, samples)
}

/**
Expand Down
21 changes: 5 additions & 16 deletions src/game/display/player-display.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,17 @@ import { getGauge } from './Gauge'

export class PlayerDisplay {
constructor(player, skinData) {
let notechart = player.notechart
this._currentSpeed = 1
this._player = player
this._noteArea = new NoteArea(notechart.notes, notechart.barLines)
this._noteArea = new NoteArea(
player.notechart.notes,
player.notechart.barLines
)
this._stateful = {}
this._defaultData = {
placement: player.options.placement,
scratch: player.options.scratch,
key_mode: getKeyMode(notechart, player.options.scratch),
key_mode: player.notechart.getKeyMode(player.options.scratch),
lane_lift: Math.max(0, -player.options.laneCover),
lane_press: Math.max(0, player.options.laneCover),
}
Expand Down Expand Up @@ -221,16 +223,3 @@ export class PlayerDisplay {
}

export default PlayerDisplay

// TODO [#629]: MOVE THIS (getKeyMode) TO bemuse-notechart
//
function getKeyMode(notechart, scratch) {
const usedColumns = {}
for (const note of notechart.notes) {
usedColumns[note.column] = true
}
if (scratch === 'off' && !usedColumns['1'] && !usedColumns['7']) return '5K'
if (scratch === 'left' && !usedColumns['6'] && !usedColumns['7']) return '5K'
if (scratch === 'right' && !usedColumns['1'] && !usedColumns['2']) return '5K'
return '7K'
}
39 changes: 16 additions & 23 deletions src/game/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import React from 'react'
import SCENE_MANAGER from 'bemuse/scene-manager'
import URLResource from 'bemuse/resources/url'
import audioContext from 'bemuse/audio-context'
import co from 'co'
import query from 'bemuse/utils/query'
import { resolveUrl } from 'url'
import { unmuteAudio } from 'bemuse/sampling-master'
Expand All @@ -13,7 +12,7 @@ import GameScene from './game-scene'
import GameShellScene from './ui/GameShellScene.jsx'
import LoadingScene from './ui/LoadingScene.jsx'

export function main() {
export async function main() {
// iOS
window.addEventListener('touchstart', function unmute() {
unmuteAudio(audioContext)
Expand All @@ -32,9 +31,7 @@ export function main() {
})
}

// TODO [#630]: Convert the `getSong` function to async function (instead of using `co.wrap`) in src/game/index.js
// See issue #575 for more details.
let getSong = co.wrap(function*() {
let getSong = async function() {
let kbm = (query.keyboard || '').split(',').map(x => +x)
let options = {
url: query.bms || '/music/[snack]dddd/dddd_sph.bme',
Expand Down Expand Up @@ -63,7 +60,7 @@ export function main() {
},
],
}
options = yield displayShell(options)
options = await displayShell(options)
let url = options.url
let assetsUrl = resolveUrl(url, 'assets/')
let metadata = {
Expand All @@ -73,27 +70,23 @@ export function main() {
genre: '',
subartists: [],
}
let loadSpec = {
return {
bms: options.resource || new URLResource(url),
assets: options.resources || new BemusePackageResources(assetsUrl),
metadata: metadata,
options: Object.assign({}, options.game, { players: options.players }),
}
return loadSpec
})
}

// TODO [#631]: Convert the `co` invocation to async function IIFE in src/game/index.js
co(function*() {
let loadSpec = yield getSong()
let { tasks, promise } = GameLoader.load(loadSpec)
yield SCENE_MANAGER.display(
React.createElement(LoadingScene, {
tasks: tasks,
song: loadSpec.metadata,
})
)
let controller = yield promise
yield SCENE_MANAGER.display(new GameScene(controller.display))
controller.start()
}).done()
let loadSpec = await getSong()
let { tasks, promise } = GameLoader.load(loadSpec)
await SCENE_MANAGER.display(
React.createElement(LoadingScene, {
tasks: tasks,
song: loadSpec.metadata,
})
)
let controller = await promise
await SCENE_MANAGER.display(new GameScene(controller.display))
controller.start()
}
57 changes: 25 additions & 32 deletions src/scene-manager/index.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import co from 'co'
import React from 'react'
import ReactDOM from 'react-dom'
import MAIN from 'bemuse/utils/main-element'
Expand Down Expand Up @@ -60,41 +59,35 @@ export class SceneManager {
})
}

// TODO [#635]: Convert the `_transitionTo` method to async function (instead of using `co`) in src/scene-manager/index.js
// See issue #575 for more details.
_transitionTo(getNextScene) {
return co(
function*() {
if (this._transitioning) throw new Error('Scene is transitioning!')
try {
this._transitioning = true
async _transitionTo(getNextScene) {
if (this._transitioning) throw new Error('Scene is transitioning!')
try {
this._transitioning = true

// detach the previous scene
if (this.currentSceneInstance) {
yield Promise.resolve(this.currentSceneInstance.teardown())
detach(this.currentElement)
}
// detach the previous scene
if (this.currentSceneInstance) {
await Promise.resolve(this.currentSceneInstance.teardown())
detach(this.currentElement)
}

// obtain the next scene
let scene = getNextScene()
// obtain the next scene
let scene = getNextScene()

// coerce react elements
if (typeof scene !== 'function') {
scene = new ReactScene(scene, this.ReactSceneContainer)
}
// coerce react elements
if (typeof scene !== 'function') {
scene = new ReactScene(scene, this.ReactSceneContainer)
}

// set up the next scene
var element = document.createElement('div')
element.className = 'scene-manager--scene'
MAIN.appendChild(element)
this.currentElement = element
this.currentScene = scene
this.currentSceneInstance = scene(element)
} finally {
this._transitioning = false
}
}.bind(this)
)
// set up the next scene
var element = document.createElement('div')
element.className = 'scene-manager--scene'
MAIN.appendChild(element)
this.currentElement = element
this.currentScene = scene
this.currentSceneInstance = scene(element)
} finally {
this._transitioning = false
}
}
}

Expand Down
Loading

0 comments on commit 2fc3241

Please sign in to comment.