About this Blog

This Blog has English posts and Japanese posts. About Mac, iOS, Objective-C, and so on.

2013年3月24日日曜日

mruby on Objective-C -スクリプトの実行を中断-

正しい使い方かどうかは分かりませんが、一応公開します。


前提

mruby-master/include/mrbconf.hでdefine ENABLE_DEBUG.
mruby VMがメインスレッド以外で実行されていること。


方針

ユーザーのアクションで、実行中のmruby VMのcode_fetch_hookに関数を登録。
その関数の中でエラーをraiseしてスクリプトの実行を中断。


viewController.h
#import <Foundation/Foundation.h>
#include "mruby.h"
#include "mruby/string.h"
#include "mruby/compile.h"
#include "mruby/class.h"
#include "mruby/value.h"
#include "mruby/proc.h"
#include "mruby/variable.h"
#include "mruby/array.h"

mrb_value mrb_printstr(mrb_state*, mrb_value);//別エントリで解説しています。
void mrb_interrupt(mrb_state*, mrb_irep*, mrb_code*, mrb_value*);

@interface viewController : UIViewController{
    NSOperationQueue *_queue;
    NSBlockOperation *_operation;
    struct mrb_state *_mrb;
}
-(void)mrbInitPrint;//別エントリで解説しています。
-(void)mrbRun:(NSString *)code;//別エントリで解説しています。
-(IBAction)mrbQuit;
@end


viewController.m
必要なコードのみ書いてあります。
void mrb_interrupt(mrb_state *mrb, mrb_irep *irep, mrb_code *pc, mrb_value *regs){
    //code_fetch_hookにすぐにNULLを代入するので、この関数は1回だけ呼ばれます。
    //エラーをraiseするとスクリプトが中断するので意味はないですが、
    //他の処理を割りこませることもできます。
    mrb->code_fetch_hook = NULL;
    mrb_raise(mrb, E_RUNTIME_ERROR, "interrupted");
}

@implementation viewController
-(IBAction)mrbQuit{
    if(_mrb){ _mrb->code_fetch_hook = mrb_interrupt; }
}
@end
UIButtonのtouch up insideなどにOutletしてください。

0 件のコメント:

コメントを投稿