In case Flash no longer exists; a copy of this site is included in the Flashpoint archive's "ultimate" collection.

Dead Code Preservation :: Archived AS3 works from wonderfl.net

forked from: Threadの割り込みがうまくいかないことがある

stageを連打してるとClickThreadのinterruptedが実行されないことがたまにある
一回目のクリックから3秒後にMainThreadからClickThreadにinterruptしてる
interrupt されてから実行されるまで EnterFrameThreadExecutor の場合だと
1 frame 間が空く。その間に event で設定したイベントが飛んでくると、
実行順序が意図している順番と逆になる場合がある。
その場合、意図した通りに割り込みされない。
1. Thread を event, interrupted を設定して WAITNG へ。
2. interrupt をコールして割り込む。
この時点で次の実行関数は interrupted で設定された関数になるものの、
_isInterrupted は false のままである。
3. event で設定したイベントがトリガーされる。
ここで next などで実行関数を登録した場合、次の実行関数が上書きされる。
4. 上書きされた実行関数が実行されるが、この時点で _isInterrupted は false なので、
割り込まれたのかどうか、判断する方法が無い。
@see http://www.libspark.org/ticket/104
Get Adobe Flash player
by soundkitchen 28 Aug 2009
    Embed
/**
 * Copyright soundkitchen ( http://wonderfl.net/user/soundkitchen )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/vCSr
 */

// forked from ll_koba_ll's Threadの割り込みがうまくいかないことがある
// stageを連打してるとClickThreadのinterruptedが実行されないことがたまにある
// 一回目のクリックから3秒後にMainThreadからClickThreadにinterruptしてる

// interrupt されてから実行されるまで EnterFrameThreadExecutor の場合だと
// 1 frame 間が空く。その間に event で設定したイベントが飛んでくると、
// 実行順序が意図している順番と逆になる場合がある。
// その場合、意図した通りに割り込みされない。
//
// 1. Thread を event, interrupted を設定して WAITNG へ。
// 2. interrupt をコールして割り込む。
//    この時点で次の実行関数は interrupted で設定された関数になるものの、
//    _isInterrupted は false のままである。
// 3. event で設定したイベントがトリガーされる。
//    ここで next などで実行関数を登録した場合、次の実行関数が上書きされる。
// 4. 上書きされた実行関数が実行されるが、この時点で _isInterrupted は false なので、
//    割り込まれたのかどうか、判断する方法が無い。
//
// @see http://www.libspark.org/ticket/104
//
package
{
    import flash.display.*;
    import org.libspark.thread.Thread;
    import org.libspark.thread.EnterFrameThreadExecutor;

    public class InterruptTest extends Sprite
    {
        public function InterruptTest()
        {
            Thread.initialize(new EnterFrameThreadExecutor())
            new MainThread(this).start();
        }
    }
}

import flash.display.Sprite;
import flash.events.MouseEvent;
import org.libspark.thread.Thread;

class MainThread extends Thread
{
    private var _clickThread:ClickThread;
    private var _target:Sprite
    public function MainThread(target:Sprite)
    {
        _target = target;
    }

    protected override function run():void
    {
        event(_target.stage, MouseEvent.CLICK, hoge);   
    }
    
    private function hoge(e:MouseEvent):void
    {
        sleep(3000);
        next(exit);
        _clickThread = new ClickThread(_target);
        _clickThread.start();
    }

    private function exit():void
    {
        _clickThread.interrupt();
        trace("MainThread exit"); 
    }
}

class ClickThread extends Thread
{
    private var _target:Sprite;
    public function ClickThread(target:Sprite)
    {
        _target = target;
    }

    protected override function run():void
    {
        if (checkInterrupted())
        {
            // WAITING 状態での割り込みの場合だと、
            //  _isInterrupted が true にならないため、
            // ここでも割り込まれてるのか判別出来ない :-(
            trace('iregular exit...');
            return;
        }
        
        event(_target.stage, MouseEvent.CLICK, click);
        interrupted(exit);
    }

    private function click(e:MouseEvent):void
    {
        trace("click");
        run();
    }

    private function exit():void
    {
        trace("exit!!!!!");
    }

}