FPOne
【没ライブラリ】
同じPC上に同じSWFが二つ起動しないようにするためのやつ。
一つのPCに同じSWFは一つまでをローカルで。
本物の龍は一匹でええ。的なやつ。
【試し方】
このSWFを二つ開いてください、先に開いたほうが止まります。
FPOne.setup("mojamoja", FPOne.NEXT);
とかやると、後に開いたほうが止まります。
何で没になったのかは思い出せません。
@author jc at bk-zen.com
/**
* Copyright bkzen ( http://wonderfl.net/user/bkzen )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/fPDO
*/
package {
import com.bit101.components.Window;
import com.bit101.components.Label;
import flash.display.Sprite;
import flash.events.Event;
import flash.display.Shape;
import flash.display.Graphics;
import org.libspark.betweenas3.BetweenAS3;
import org.libspark.betweenas3.core.easing.BackEaseInOut;
import org.libspark.betweenas3.tweens.ITween;
/**
* 【没ライブラリ】
* 同じPC上に同じSWFが二つ起動しないようにするためのやつ。
* 一つのPCに同じSWFは一つまでをローカルで。
* 本物の龍は一匹でええ。的なやつ。
* 【試し方】
* このSWFを二つ開いてください、先に開いたほうが止まります。
* FPOne.setup("mojamoja", FPOne.NEXT);
* とかやると、後に開いたほうが止まります。
* 何で没になったのかは思い出せません。
* @author jc at bk-zen.com
*/
public class FlashTest extends Sprite {
private var shape: Shape;
private var itween: ITween;
public function FlashTest() {
// write as3 code here..
if (stage) init();
else addEventListener(Event.ADDED_TO_STAGE, init);
}
private function init(e:Event = null): void
{
removeEventListener(Event.ADDED_TO_STAGE, init);
//
addChild(shape = new Shape());
var g:Graphics = shape.graphics;
g.beginFill(0x336699);
g.drawCircle(0, 0, 50);
itween = BetweenAS3.to(shape, {x: Math.random() * stage.stageWidth, y: Math.random() * stage.stageHeight}, 2, new BackEaseInOut());
itween.onComplete = next;
itween.play();
FPOne.setup("mojamoja", FPOne.PREV);
FPOne.dispatcher.addEventListener(Event.CLOSE, onClose);
FPOne.retryMax = 100;
FPOne.check();
}
private function next():void
{
itween = BetweenAS3.to(shape, {x: Math.random() * stage.stageWidth, y: Math.random() * stage.stageHeight}, 2, new BackEaseInOut());
itween.onComplete = next;
itween.play();
}
/// 動きを止める処理を書く
private function onClose(e:Event):void
{
if (itween) itween.stop();
var g:Graphics = shape.graphics;
g.clear();
g.beginFill(0xCC0000);
g.drawCircle(0, 0, 50);
var modalSp:Sprite = new Sprite();
g = modalSp.graphics;
g.beginFill(0xCCCCCC, 0.5);
g.drawRect(0, 0, stage.stageWidth, stage.stageHeight);
addChild(modalSp);
var window: Window = new Window(this);
window.draggable = false;
var label:Label = new Label(window.content, 5, 5, "Closed");
window.x = (stage.stageWidth - window.width) / 2;
window.y = (stage.stageHeight - window.height) / 2;
}
}
}
class FPOne
{
import flash.events.Event;
import flash.events.EventDispatcher;
import flash.events.StatusEvent;
import flash.net.LocalConnection;
import flash.utils.setTimeout;
public static const NEXT: int = 1;
public static const PREV: int = 2;
private static var _dispatcher: EventDispatcher;
private static var _id: String = null;
private static var _whichClose: int = 1;
private static var sConn: LocalConnection, cConn: LocalConnection;
private static var _isConnect: Boolean;
private static var _isClosed: Boolean;
private static var domain: String = "";
private static var retryCount: int = 0;
public static var retryMax: int = 5;
/**
* 準備
* @param id : 同じIDをもつものを対象とする。
* @param whichClose : 先に開いたほうを閉じるのか、後に開いたほうを閉じるのかの設定。(NEXT, PREV, NEXT | PREV)
*/
public static function setup(id: String, whichClose: int = 1): EventDispatcher
{
if (_id == null)
{
_id = "_" + id, _whichClose = whichClose;
sConn = new LocalConnection(), cConn = new LocalConnection();
cConn.client = new FPOneClient(_close);
cConn.allowDomain("*"), sConn.allowDomain("*");
sConn.addEventListener(StatusEvent.STATUS, onState);
}
return dispatcher;
}
private static function onState(e:StatusEvent):void { }
/**
* 他に同じSWFが立ち上がっているかチェックを開始する。
*/
public static function check(): void
{
if (_id == null)
{
throw new Error("setup が済んでいません。");
return;
}
// FF はりロードするとConnectionが残ってるときがあるからちょい待つ
setTimeout(_check, 1000);
}
private static function _check():void
{
try
{
cConn.connect(_id);
_isConnect = true;
}
catch (err:Error)
{
_isConnect = false;
}
_check2();
}
private static function _check2():void
{
var b: Boolean;
if ((_whichClose & NEXT) > 0)
{
if ( !_isConnect ) close();
}
if ((_whichClose & PREV) > 0)
{
if ( !_isConnect )
{
try
{
sConn.send(domain + _id, "kill");
b = true;
setTimeout(retry, 100);
}
catch (err:Error)
{
if (b) _isConnect = false;
if (domain == "")
{
domain = "localhost";
setTimeout(_check2, 1);
return;
}
}
}
}
if (!_isClosed) dispatcher.dispatchEvent(new Event(Event.COMPLETE));
}
private static function retry():void
{
try
{
cConn.connect(_id);
_isConnect = true;
}
catch (err:Error)
{
_isConnect = false;
if (retryMax > retryCount ++) setTimeout(retry, 100);
}
}
public static function close(): void
{
if (_isClosed) return;
_isClosed = true;
_isConnect = false;
try { cConn.close(); }
catch (err:Error) { }
dispatcher.dispatchEvent(new Event(Event.CLOSE));
}
private static function _close(): void
{
setTimeout(close, 1);
}
public static function get dispatcher():EventDispatcher { return _dispatcher ||= new EventDispatcher(); }
public static function get isClosed():Boolean { return _isClosed; }
}
internal class FPOneClient
{
private var _handler: Function;
function FPOneClient(closeHandler: Function) { _handler = closeHandler; }
public function kill(): void { _handler(); }
}