/**
* Copyright yd_niku ( http://wonderfl.net/user/yd_niku )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/wfHK
*/
// forked from yd_niku's MVCTest
/**
* http://moock.org/lectures/mvc/
*/
package {
import flash.display.Sprite;
public class FlashTest extends Sprite {
public function FlashTest() {
var m:ClockModel = new ClockModel();
var tool:ClockTool = new ClockTool(m);
var clock:ClockView = new ClockView(m);
// この紐付けはView内部でやってもよさそうな気がするけど?
m.addEventListener(ClockEvent.UPDATE, tool.update);
m.addEventListener(ClockEvent.UPDATE, clock.update);
m.setTime(10,0,0);
m.start();
tool.y = 100;
addChild(clock)
addChild(tool);
}
}
}
////////////////////////////////////////////////////////////////
import com.bit101.components.*;
import flash.events.*;
import flash.display.*;
interface Model extends IEventDispatcher{
}
interface View{
function get model():Model;
function set model(m:Model):void;
function get controller():Controller;
function set controller(c:Controller):void;
function defaultController(m:Model):Controller;
}
interface Controller{
function get model():Model;
function set model(m:Model):void;
function get view():View;
function set view(v:View):void;
}
class AbstructView extends Sprite implements View{
private var _model:Model;
private var _controller:Controller;
public function AbstructView(m:Model, c:Controller=null){
model = m;
if(c!=null) controller = c;
}
public function get model():Model{ return _model; }
public function set model(m:Model):void{ _model = m; }
public function get controller():Controller{
if(_controller==null){
controller = defaultController(model);
}
return _controller;
}
public function set controller(c:Controller):void{
_controller = c;
controller.view = this;
}
public function defaultController(m:Model):Controller{
return null;
}
//フレームワーク的にAbstructに定義しておくだけ
public function update(info:Event):void{
}
}
class AbstructCotnroller implements Controller {
private var _model:Model;
private var _view:View;
public function AbstructCotnroller(m:Model){
model = m;
}
public function get model():Model{ return _model; }
public function set model(m:Model):void{ _model = m; }
public function get view():View{ return _view; }
public function set view(v:View):void{ _view = v; }
}
//////////////////////////////////////////////////////////
import flash.utils.setInterval;
import flash.utils.clearInterval;
// Modelが発行するEventのサブクラス
class ClockEvent extends Event {
public static const UPDATE:String = 'ClockEvent.update';
public var hour:int;
public var minute:int;
public var second:int;
public var isRunning:Boolean;
public function ClockEvent( type:String, h:int,m:int,s:int,isRunning:Boolean){
super(type);
hour = h;
minute = m;
second = s;
this.isRunning = isRunning;
}
override public function clone():Event{
return new ClockEvent(type,hour,minute,second,isRunning);
}
}
// イベントを発行するModelの実装
class ClockModel extends EventDispatcher implements Model{
private var _hour:int;
private var _minute:int;
private var _second:int;
private var _tickInterval:int;
private var _isRunning:Boolean;
public function ClockModel(){
super();
var now:Date = new Date();
setTime(now.getHours(),now.getMinutes(),now.getSeconds());
}
public function setTime(h:int,m:int,s:int):void{
if( h != _hour && isValidHour(h) ) {
_hour = h;
//setChanged();
}
if( m != _minute && isValidMinute(m) ) {
_minute = m;
//setChanged();
}
if( s != _second && isValidSecond(s) ) {
_second = s;
//setChanged();
}
if(willTrigger(ClockEvent.UPDATE)){
var info:ClockEvent = new ClockEvent(ClockEvent.UPDATE, _hour,_minute,_second,_isRunning);
dispatchEvent(info);
}
}
public function start():void{
if( !_isRunning ) {
_isRunning = true;
_tickInterval = setInterval( tick, 1000);
var info:ClockEvent = new ClockEvent(ClockEvent.UPDATE, _hour,_minute,_second,_isRunning);
//setChanged();
dispatchEvent(info);
}
}
public function stop():void{
if( _isRunning ) {
_isRunning = false;
clearInterval(_tickInterval);
var info:ClockEvent = new ClockEvent(ClockEvent.UPDATE, _hour,_minute,_second,_isRunning);
//setChanged();
dispatchEvent(info);
}
}
private function isValidHour(value:int):Boolean{
return value >= 0 && value < 24;
}
private function isValidMinute(value:int):Boolean{
return value >= 0 && value < 60;
}
private function isValidSecond(value:int):Boolean{
return value >= 0 && value < 60;
}
private function tick():void{
var h:int = _hour;
var m:int = _minute;
var s:int = _second;
s += 1;
if (s > 59) {
s = 0;
m += 1;
if (m > 59) {
m = 0;
h += 1;
if (h > 23) {
h = 0;
}
}
}
setTime(h, m, s);
}
}
// Modelを操作し、Viewのサブクラスに操作されるControllerの実装
class ClockController extends AbstructCotnroller{
public function ClockController(m:Model){
super(m);
}
public function startClock():void{
ClockModel(model).start();
}
public function stopClock():void{
ClockModel(model).stop();
}
public function resetClock():void{
setTime(0,0,0);
}
public function setTime (h:int, m:int, s:int):void {
ClockModel(model).setTime(h, m, s);
}
}
import flash.text.TextField;
// 表示のみのViewの実装
class ClockView extends AbstructView{
public var textField:TextField;
public function ClockView(m:Model,c:Controller=null){
super(m,c);
addChild(textField = new TextField());
}
override public function update(info:Event):void{
var update:ClockEvent = info as ClockEvent;
if( update == null ) return;
textField.text = [ update.hour, update.minute, update.second ].join(':');
}
}
// Controllerを操作するUIをもったViewのサブクラス
class ClockTool extends AbstructView {
public var btnStart:PushButton;
public var btnStop:PushButton;
public var btnReset:PushButton;
public function ClockTool(m:Model,c:Controller=null){
super(m,c);
var ctrl:ClockController = ClockController(controller);
btnStart = new PushButton(this,0,0,'start',function():void{ctrl.startClock();});
btnStop = new PushButton(this,110,0,'stop',function():void{ctrl.stopClock();});
btnReset = new PushButton(this,220,0,'reset',function():void{ctrl.resetClock();});
}
override public function update(info:Event):void{
var update:ClockEvent = info as ClockEvent;
if(update.isRunning){
btnStart.mouseEnabled = false;
btnStop.mouseEnabled = true;
}
else {
btnStart.mouseEnabled = true;
btnStop.mouseEnabled = false;
}
}
override public function defaultController(m:Model):Controller{
return new ClockController(m);
}
}