2009년 10월 2일 금요일

State Patten을 C로 짜려면?

C에서는 상속을 사용하지 못하지만, 그렇다고 State Patten을 구현하지 못하는 것은 아니다. 아래와 같은 구현으로 C에서 State Patten의 장점을 사용할 수 있을 것 같다. C에서는 인터페이스나 상속이 지원되지 않으므로 function table을 사용하여 이벤트 발생시 각 상태별 실행 함수를 지정하도록 하였다. 사실상 이 function table이 구현의 핵심으로, 상태 변경을 발생시키는 이벤트가 추가 할 때마다, 모든 function table의 해당 함수에 대한 함수 포인터 혹은 null function pointer를 추가해야 한다. 바로 이 부분이 상속과 가상 함수를 지원하지 못하는 C에서 State Pattern을 구현할 때 발생하는 불편함이기는 하지만 여전히 State Pattern의 장점을 그대로 누릴 수 있다. 또한 (당연히) 동일 방법을 사용하여 Strategy Pattern 역시 구현 가능하다.

아래 예에서는 구현을 단순화하기 위해서 상태는 ON/OFF두가지 상태만을 가정하였고, 'n' 입력시 ON상태로, 'f' 입력시 OFF상태로 상태 천이를 하도록 하였다.



#include <stdio.h>

/**********************************************************************
*
* 1. Type defination for Power State management
*
**********************************************************************/

typedef enum {ON,OFF} PowerState;

typedef struct
{
  PowerState currPS;
  void (*on_received_fptr)(struct PwrState **ps );
  void (*off_received_fptr)(struct PwrState **ps );
}PwrState;

/**********************************************************************
*
* 2. Function table for each State.
*
**********************************************************************/
//Prefix ON/OFF means current status when these functions are called.
void ON_off_received(PwrState **ps );
void OFF_on_received(PwrState **ps );
void null_func(PwrState **ps);

//C에서는 가상 함수를 사용할 수 없기 때문에, 아래와 같은 각 상태별
//함수 테이블을 별도로 유지해야 한다.

PwrState psON= {ON,   null_func,      ON_off_received};
PwrState psOFF={OFF,  OFF_on_received,  null_func};


void ON_off_received(PwrState **ps)
{
  printf("Currnt State =%d : 0:ON 1:OFF \n",(int)(*ps)->currPS);
  printf("%s is called\n",__func__);

  printf("change curr power state from ON to OFF\n");
  *ps=&psOFF;
}

void OFF_on_received(PwrState **ps)
{
  printf("Currnt State =%d : 0:ON 1:OFF \n",(int)(*ps)->currPS);
  printf("%s is called\n",__func__);

  printf("change curr power state from OFF to ON\n");
  *ps=&psON;
}

void null_func(PwrState **ps){}

int main(void)
{
  char keyin;
  PwrState *ps=&psOFF;

  printf("Current power state is OFF\n");
  printf("type \'n\' to change power state to ON\n");
  printf("type \'f\' to change power state to OFF\n");

  while(1)
  {
    keyin = getchar();

    switch(keyin)
    {
      case 'n':// change state to ON
        ps->on_received_fptr(&ps);
        break;
      case 'f':// change state to OFF
        ps->off_received_fptr(&ps);
        break;
      default:
        break;
    }
  }
}

2009년 10월 1일 목요일

원하는 폴더에서 마우스 오른쪽 버튼으로 커맨드 창 열기

아래 내용을 filename.reg기울임꼴로 저장한 후 실행하면 레지스트리에 해당 내용이 추가되며, 추가된 이후 실행된 탐색기에서는 특정 폴더에서 마우스 오른쪽 버튼 클릭시 뜨는 팝업 메뉴에 "Dos Prompt(Z)"가 추가된다. &Z는 팝업메뉴에서의 단축키를 Z로 지정한 것이며, "Dos Prompt" 대신 원하는 문자열을 사용할 수 있다.

Windows Registry Editor Version 5.00

[HKEY_CLASSES_ROOT\Directory\shell\OpenNew]@="Dos Prompr t(&Z)"
[HKEY_CLASSES_ROOT\Directory\shell\OpenNew\Command]@="cmd.exe /k"


아래 블로그에서 관련 내용을 포함한 추가 정보를 얻을 수 있습니다.
http://youngsam.kr/