diff --git a/app/assets/javascripts/player.js b/app/assets/javascripts/player.js index c23d482..74084bc 100644 --- a/app/assets/javascripts/player.js +++ b/app/assets/javascripts/player.js @@ -7,6 +7,7 @@ //= require_tree ./player/views/renderers //= require player/views/hud_view //= require player/data_unpacker +//= require player/player //= require player/views/player_view //= require player/workers/worker_object_proxy //= require player/workers/worker_proxy diff --git a/app/assets/javascripts/player/player.js.coffee b/app/assets/javascripts/player/player.js.coffee new file mode 100644 index 0000000..bbc0d0a --- /dev/null +++ b/app/assets/javascripts/player/player.js.coffee @@ -0,0 +1,84 @@ +class AsciiIo.Player + + constructor: (@options) -> + @model = @options.model + + @createWorkerProxy() + + @createView() + @createVT() + @createMovie() + + @fetchModel() + + createWorkerProxy: -> + @workerProxy = new AsciiIo.WorkerProxy(window.mainWorkerPath) + + createView: -> + @view = new AsciiIo.PlayerView + el: @options.el + model: @model + cols: @options.cols + lines: @options.lines + hud: @options.hud + rendererClass: @options.rendererClass + snapshot: @options.snapshot + + createVT: -> + @vt = @workerProxy.getObjectProxy 'vt' + + createMovie: -> + @movie = @workerProxy.getObjectProxy 'movie' + + fetchModel: -> + @model.fetch success: @onModelFetched + + onModelFetched: => + data = @model.get('escaped_stdout_data') + unpacker = new AsciiIo.DataUnpacker + unpacker.unpack data, @onModelDataUnpacked + + onModelDataUnpacked: (data) => + @model.set stdout_data: data + @onModelReady() + + onModelReady: -> + @initWorkerProxy() + @bindEvents() + @view.onModelReady() + + if @options.autoPlay + @movie.call 'play' + else + @view.showPlayOverlay() + + initWorkerProxy: -> + @workerProxy.init + timing: @model.get 'stdout_timing_data' + stdout_data: @model.get 'stdout_data' + duration: @model.get 'duration' + speed: @options.speed + benchmark: @options.benchmark + cols: @options.cols + lines: @options.lines + + bindEvents: -> + @view.on 'play-clicked', => @movie.call 'togglePlay' + @view.on 'seek-clicked', (percent) => @movie.call 'seek', percent + + @vt.on 'cursor-visibility', (show) => @view.showCursor show + + @movie.on 'started', => @view.onStateChanged 'playing' + @movie.on 'paused', => @view.onStateChanged 'paused' + @movie.on 'finished', => @view.onStateChanged 'finished' + @movie.on 'resumed', => @view.onStateChanged 'resumed' + @movie.on 'wakeup', => @view.restartCursorBlink() + @movie.on 'time', (time) => @view.updateTime time + @movie.on 'render', (state) => @view.renderState state + + if @options.benchmark + @movie.on 'started', => @startedAt = (new Date).getTime() + + @movie.on 'finished', => + now = (new Date).getTime() + console.log "finished in #{(now - @startedAt) / 1000.0}s" diff --git a/app/assets/javascripts/player/views/player_view.js.coffee b/app/assets/javascripts/player/views/player_view.js.coffee index 5caa26e..4925185 100644 --- a/app/assets/javascripts/player/views/player_view.js.coffee +++ b/app/assets/javascripts/player/views/player_view.js.coffee @@ -3,11 +3,9 @@ class AsciiIo.PlayerView extends Backbone.View 'click .start-prompt': 'onStartPromptClick' initialize: (options) -> - @createMainWorker() @createRendererView() - @showLoadingIndicator() @createHudView() if options.hud - @fetchModel() + @showLoadingOverlay() createRendererView: -> @rendererView = new @options.rendererClass( @@ -15,104 +13,70 @@ class AsciiIo.PlayerView extends Backbone.View lines: @options.lines ) - @$el.append(@rendererView.$el) + @$el.append @rendererView.$el @rendererView.afterInsertedToDom() @rendererView.renderSnapshot @options.snapshot createHudView: -> @hudView = new AsciiIo.HudView(cols: @options.cols) + + @hudView.on 'play-click', => @onPlayClicked() + @hudView.on 'seek-click', (percent) => @onSeekClicked() + @$el.append @hudView.$el - fetchModel: -> - @model.fetch success: => @onModelFetched() - - onModelFetched: -> - data = @model.get('escaped_stdout_data') - unpacker = new AsciiIo.DataUnpacker - unpacker.unpack data, @onDataUnpacked - - onDataUnpacked: (data) => - @model.set stdout_data: data - @onModelReady() - onModelReady: -> - @hideLoadingIndicator() - @hudView.setDuration @model.get('duration') if @options.hud - @setupMainWorker() - @bindEvents() - - if @options.autoPlay - @movie.call 'play' - else - @showToggleOverlay() - - createMainWorker: -> - @workerProxy = new AsciiIo.WorkerProxy(window.mainWorkerPath) - - setupMainWorker: -> - @workerProxy.init - timing: @model.get 'stdout_timing_data' - stdout_data: @model.get 'stdout_data' - duration: @model.get 'duration' - speed: @options.speed - benchmark: @options.benchmark - cols: @options.cols - lines: @options.lines - - @movie = @workerProxy.getObjectProxy 'movie' - @vt = @workerProxy.getObjectProxy 'vt' - - bindEvents: -> - @movie.on 'started', => @$el.addClass 'playing' - - @movie.on 'finished', => - @$el.removeClass 'playing' - @rendererView.stopCursorBlink() - - @movie.on 'paused', => - @$el.addClass 'paused' - @$el.removeClass 'playing' - @hudView.onPause() if @options.hud - - @movie.on 'resumed', => - @$el.addClass 'playing' - @$el.removeClass 'paused' - @hudView.onResume() if @options.hud - - @movie.on 'wakeup', => @rendererView.restartCursorBlink() - - if @options.hud - @movie.on 'time', (time) => @hudView.updateTime(time) - - @movie.on 'render', (state) => @rendererView.push state - - @vt.on 'cursor:show', => @rendererView.showCursor true - @vt.on 'cursor:hide', => @rendererView.showCursor false - - if @options.hud - @hudView.on 'play-click', => @movie.call 'togglePlay' - @hudView.on 'seek-click', (percent) => @movie.call 'seek', percent - - if @options.benchmark - @movie.on 'started', => - @startedAt = (new Date).getTime() - - @movie.on 'finished', => - now = (new Date).getTime() - console.log "finished in #{(now - @startedAt) / 1000.0}s" + @hideLoadingOverlay() + @hudView.setDuration @model.get('duration') if @hudView onStartPromptClick: -> - @hideToggleOverlay() - @movie.call 'togglePlay' + @hidePlayOverlay() + @onPlayClicked() - showLoadingIndicator: -> + onPlayClicked: -> + @trigger 'play-clicked' + + onSeekClicked: (percent) -> + @trigger 'seek-clicked', percent + + showLoadingOverlay: -> @$el.append('
') - hideLoadingIndicator: -> + hideLoadingOverlay: -> @$('.loading').remove() - showToggleOverlay: -> + showPlayOverlay: -> @$el.append('
') - hideToggleOverlay: -> + hidePlayOverlay: -> @$('.start-prompt').remove() + + onStateChanged: (state) -> + @$el.removeClass('playing paused') + + switch state + when 'playing' + @$el.addClass 'playing' + + when 'finished' + @rendererView.stopCursorBlink() + + when 'paused' + @$el.addClass 'paused' + @hudView.onPause() if @hudView + + when 'resumed' + @$el.addClass 'playing' + @hudView.onResume() if @hudView + + renderState: (state) -> + @rendererView.push state + + updateTime: (time) -> + @hudView.updateTime time if @hudView + + restartCursorBlink: -> + @rendererView.restartCursorBlink() + + showCursor: (show) -> + @rendererView.showCursor show diff --git a/app/assets/javascripts/player/vt/vt.js.coffee b/app/assets/javascripts/player/vt/vt.js.coffee index 10c9632..a6964f3 100644 --- a/app/assets/javascripts/player/vt/vt.js.coffee +++ b/app/assets/javascripts/player/vt/vt.js.coffee @@ -315,10 +315,10 @@ class AsciiIo.VT # ------ Cursor control showCursor: -> - @trigger 'cursor:show' + @trigger 'cursor-visibility', true hideCursor: -> - @trigger 'cursor:hide' + @trigger 'cursor-visibility', false # ----- Scroll control diff --git a/app/helpers/asciicasts_helper.rb b/app/helpers/asciicasts_helper.rb index 122d710..ebf5242 100644 --- a/app/helpers/asciicasts_helper.rb +++ b/app/helpers/asciicasts_helper.rb @@ -15,7 +15,7 @@ module AsciicastsHelper return < $(function() { - window.player = new AsciiIo.PlayerView({ + window.player = new AsciiIo.Player({ el: $('.player'), cols: #{asciicast.terminal_columns}, lines: #{asciicast.terminal_lines},