Warning: opendir(/var/www/html/wp-content/mu-plugins): Failed to open directory: Permission denied in /var/www/html/wp-includes/load.php on line 981 thread – sewonist.com https://sewonist.com sewonist = sewon + artist Fri, 10 Apr 2020 03:41:18 +0000 en-US hourly 1 https://wordpress.org/?v=6.9.4 https://sewonist.com/wp-content/uploads/2015/08/cropped-sewonist-32x32.png thread – sewonist.com https://sewonist.com 32 32 Non blocking loop – homework https://sewonist.com/non-blocking-loop-homework/ https://sewonist.com/non-blocking-loop-homework/#comments Sun, 13 Feb 2011 10:12:15 +0000 https://sewonist.com/?p=1915 Read More »Non blocking loop – homework]]> 추가합니다. 소스를 대거(?) 수정해서 다시 올립니다. 클래스도 하나 더 늘어나고 코드양도 길어져서 그냥 프로젝트파일 전부를 압축해서 올립니다.

클래스명도 제 마음대로 Process 에 Thread 라고 막 갔다 붙혔습니다. ㅋㅋㅋ 뭐 대충 비스무리한 기능을 하니까요. 그렇다고 정말 Thread 로 오해 하시면 안됩니다. ㅎㅎㅎ그리고 클래스를 늘리면서 몇몇 기능들을 추가해봤습니다. 보통 이런것들에 있는 sleep 과 kill 입니다. 단어는 거창하지만 그냥 ENTER_FRAME 에서 함수를 실행 여부만 결정합니다. Thread 클래스에 각 runner 와 total, limit 들을 넣을까 말까 고민하다 그냥 안넣었습니다. runner 와 limit 는 그닥 알 필요가 없을 것 같고 total 은 ThreadEvent 에서 전달해 주기 때문 입니다.

소스받아서 확인해보기 귀잖은 분을 위해 데모 갑니다.

thread_a 에는 start, complete 이벤트만 걸려 있습니다. complete 되면 총 작동시간을 볼 수 있습니다. thread_b 에는 progress, interrupt 이벤트가 걸려 있습니다. thread_b 는 count가 3이면 2초간 sleep 했다가 다시 count 가 8 일때 kill 됩니다. 작동시간이 다른건 두 쓰레드의 limit 가 다르기 때문입니다. TEST 버튼을 막 눌러보시면 쓰레드들이 잘도 작동 하는 것을 확인 할 수 있습니다. 더욱 관심있으신 분은 소스를 받아서 보셔도 좋을 것 같습니다.

오랜만에 완전 재밌는 연구를 해봤습니다. 솔직히 IEventDispatcher 구현도 첨 해봤다는;;;;ㅋㅋㅋ 으흐흐~ 이제 이걸 어디다 써먹을지 고민해 봐야겠네요. 아래 이전 소스는 기억을 위해 그냥 남겨 둡니다.

Download : nonbrocking

이벤트와 콜백에 관한 재미난 글이 있어 추가합니다. 본문도 좋지만 덧글에 남겨진 의견들도 매우 흥미롭네요.
http://www.ddongkang.com/124

—————– ♕ ———————

hika님이 작성하신 Non blocking loop 의 과제를 해봤습니다. 역시 눈으로 보고 이해하는 것과 손으로 직접 써보는 건 하늘과 땅 차이! 그냥 볼때는 그리 어렵지 않게 느껴졌는데 막상 해보니 쉽지 않네요. 특히 가장 핵심이되는 loop 함수의 경우 변수scope 를 제대로 이해하지 않고 있으면 매우 난해한 부분이 될 수도 있습니다. 저 역시 그냥 대충 이해하고 있는 터라 참 헷갈리네요. ㅎㅎ

과제니까 일단 코드 부터 보겠습니다.
LoopShape.as
[as3]package
{
import flash.display.Shape;
import flash.events.Event;

public class LoopShape extends Shape
{
private var _this:LoopShape;
public function LoopShape()
{
_this = this;
}

public function loop( $counter:int, $limit:int, $runner:Function, …$param ):void{
var counter:int;
_this.addEventListener( Event.ENTER_FRAME, function( $e:Event ):void{
var i:int;
while( i++ < $limit ){
if( counter < $counter ){
if( $param.length ){
$runner.apply( null, $param );
}else{
$runner();
}
if (counter == 0) {
dispatchEvent(new LoopEvent(LoopEvent.START, $runner, counter, $counter));
}else{
dispatchEvent(new LoopEvent(LoopEvent.PROGRESS, $runner, counter, $counter));
}
++counter;
}else {
_this.removeEventListener( $e.type, arguments.callee );
dispatchEvent(new LoopEvent(LoopEvent.COMPLETE, $runner, counter, $counter));
i = $limit; // 일단 이 while 에 들어오면 $limit 까지 반복하므로 제한합니다.
}
}
});
}
}
}</pre>
<strong>LoopEvent.as</strong>
<pre class="brush: as3">package
{
import flash.events.Event;

public class LoopEvent extends Event
{
public static const START:String = "loopEventStart";
public static const PROGRESS:String = "loopEventProgress";
public static const COMPLETE:String = "loopEventComplete";

private var _func:Function;
private var _count:int;
private var _total:int;

public function LoopEvent($type:String, $func:Function, $count:int, $total:int)
{
_func = $func;
_count = $count;
_total = $total;
super($type);
}

public function get count():int { return _count; }

public function get func():Function { return _func; }

public function get total():int { return _total; }

override public function toString():String
{
return ‘[LoopEvent type="’+type+’" func="’+_func+’" count="’+_count+’" total="’+_total+’"’;
}
}

}</pre>
<strong>Main.as</strong>
<pre class="brush: as3">package
{
import flash.display.Sprite;
import flash.events.Event;

public class Main extends Sprite
{

public function Main():void
{
if (stage) init();
else addEventListener(Event.ADDED_TO_STAGE, init);
}

private function init(e:Event = null):void
{
removeEventListener(Event.ADDED_TO_STAGE, init);
// entry point

var looper:LoopShape = new LoopShape;
looper.loop( 100, 10, trace_start);
looper.loop( 100, 10, trace_progress);
looper.loop( 100, 10, trace_complete);

looper.addEventListener(LoopEvent.START, handleStart);
looper.addEventListener(LoopEvent.PROGRESS, handleProgress);
looper.addEventListener(LoopEvent.COMPLETE, handleComplete);
}

private function trace_start():void {
//trace("trace_start");
}

private function trace_progress():void {
//trace("trace_progress");
}

private function trace_complete():void {
//trace("trace_complete");
}

private function handleStart(e:LoopEvent):void
{
if (e.func == trace_start) {
trace(e);;
}
}

private function handleProgress(e:LoopEvent):void
{
if (e.func == trace_progress) {
trace(e);;
}
}

private function handleComplete(e:LoopEvent):void
{
if (e.func == trace_complete) {
trace(e);;
}
}
}
}[/as3]
과제의 요지는 본문의 nonBlockingLoop 클래스를 Shape 을 상속 하고 완료이벤트를 발생 할 수 있도록 하는 것 입니다. Shape 으로 간단히 상속해주고 ENTER_FRAME 이벤트를 등록합니다. 완료이벤트 발생을 위해 LoopEvent 라는 커스텀 이벤트를 하나 만들었습니다. 완료 이벤트는 단순히 Event.COMPLETE 를 쓸 수도 있겠습니다만 이럴 경우 어떤 함수에 대한 루프 이벤트 인지 판별 할 수 없기 때문에 해당 함수를 인자로 갖는 이벤트를 만들었습니다. 덤으로 count 와 total 도 넣어습니다. 이것으로 루프의 현재진행률도 알 수 있습니다.

이벤트를 매번 새로 생성하는건 상당한 자원 낭비라 LoopEvent 인스턴스를 하나 만들어 사용 할 까 했으나 그러기 위해서는 LoopEvent 의 func, count, total 속성에 쓰기를 허용해야 하므로 일단 매번 이벤트를 만드는 쪽으로 했습니다. 사실 어떤게 더 나은 방법인지는 아직도 잘 모르겠습니다.

]]>
https://sewonist.com/non-blocking-loop-homework/feed/ 11