2011年1月19日水曜日

ソフトウェアIC化考案(3)

3.モジュール構造を考える(2)

たたき台のソースが出来たので貼り付けておく。

基本構造はこんな感じにビジネスロジックだけ書き入れるスタイルにしておいて、
外部モジュールのプロパティアクセスはシングルトンでGetInstance経由でポインタ取得する。
プログラムの構造化は、ビジネスロジックの下位モジュールを別で作成してドライバなり扱えるようにする。
上位ロジックはイベント間通信でやり取りする。
とりあえずこれでシリアル通信でバーコードリーダとやり取り出来るプログラムを作って
どのレベルまでできるか確認しておきたい。

/*
ソース説明
objbase.h   ... オブジェクト基底モジュール
objects.h   ... ツールで自動生成するオブジェクトヘッダファイル
event.def   ... ツールで自動生成するイベント一覧
main.c    ... メインループ

sample_obj1.c  ... サンプル用オブジェクト実体

sample_obj1.def  ... サンプル用オブジェクトヘッダファイル
sample_obj2.def  ... サンプル用オブジェクトヘッダファイル

使い方
まず
オブジェクト作成コマンドを実行。 
コマンドイメージ)オブジェクト生成して、イベントを追加する。
./manage.py create_object sample_obj1
./manage.py add_event sample_obj1 evt1_1 evt1_2

*/

//**********************************************************************
// objbase.h
//**********************************************************************
#ifndef __OBJBASE_H__
#define __OBJBASE_H__
//オブジェクト構造体定義
typedef unsigned int uint32;
typedef signed int sint32;


typedef void (*event)(int* sid);
typedef struct {
    uint32 req_flag;          // 要求した側が操作できるフラグ
    uint32 act_flag;          // メインループ側が操作できるフラグ
    uint32 sid[32];           // イベント別シーケンス番号
    event* events;            // イベントリスト
    void* property;           // 変数ポインタ(プロパティ)
} object;


//シーケンス関係
#define dSEQ_END  (-1)
#define dSEQ_START  (0)

//イベント関係
#define SetEvent(id) objects[id >> 16].req_flag |= (1 << (id & 0x1f));
#define ClrEvent(id) objects[id >> 16].req_flag &= (0xffffffff ^ (1 << (id & 0x1f)));
#define isEventStart(id) (0 != (objects[id >> 16].act_flag & (1 << (id & 0x1f))))
#define isEventFin(id)   (0 == (objects[id >> 16].act_flag & (1 << (id & 0x1f))))

//オブジェクト関係
#define get_instance(id) (objects[id >> 16].property);


#endif//__OBJBASE_H__






//**********************************************************************
// sample_obj1.c
//**********************************************************************
#include "objbase.h"
#include "obj_test.h"

void evt1_1(int* );
void evt1_2(int* );
#include "sample_obj1.def"
#include "event.def"

void smaple_obj1_init()
{
 sample_obj1_property = 0;
}

//シーケンス1
void evt1_1(int* sid){
 switch(sid){
  case 0:
   SetEvent(EVT_OBJ1_TEST2);
   *sid++;
   break;
  case 1:
   if(isEventStart(EVT_OBJ1_TEST2)){
    ClrEvent(EVT_OBJ1_TEST2);
    *sid++;
   }
   break;
  case 2:
   if(isEventFin(EVT_OBJ1_TEST2)){
    *sid++;
   }
   break;
  case 3:
   int* _inctance = (int*)get_instance(EVT_OBJ1_INST);
   if(_instance == 1) *sid = dSEQ_END;
   break;
 }
}

//シーケンス2
void evt1_2(int* sid){
 *sid++;
 if(10req_flag & chk_flag)
#define ACT_FLG (obj->act_flag & chk_flag)



int main(){
    object* obj;
    event* evt;
    int* sid;
    int chk_flag;

    init_object();                   // 全体初期化

    for(;;){                         // メインループ
        chkEvent();
        for(obj = objects; NULL != obj; obj++){
            for(evt=obj->events, sid=obj->sid, chk_flag=0x1; NULL!=evt; evt++, sid++, chk_flag<<=1){
                if(0 != ACT_FLAG){
                    if(0 <= obj->sid){
                        evt(obj->property, sid);              //2.イベント処理実行
                    }else if (0 == REQ_FLG){
                        obj->act_flag ^= chk_flag;            //3.イベント処理終了
                    }
                }else if(0 != REQ_FLG){
                    obj->sid = 0;
                    obj->act_flg |= chk_flag;                 //1.イベント処理開始
                    evt(obj->property, sid);
                }
            }
        }
    }
    
    final_object();                             //全体開放

 return -1;
}

0 件のコメント:

Androider