지난 시간에 이어 display - driver를 잇는 adapter 부분을 구현해 보도록 하겠습니다. 궁극적으로는 아래와 같은 구조가 될 것입니다.
display → adapter → driver
결국 adapter 패턴이 있어 display도 다른 driver처럼 사용할 수 있게 됩니다. 먼저 adapter의 header(interface) 부터 살펴 보도록 하겠습니다.
extern driver_t *setup_display_adapter(void);
setup_display_adapter을 extern으로 선언해줍니다. setup_display_adapter를 호출하면 driver_t의 포인터를 전달해 주도록 되어있습니다.
헤더를 선언할 때 아래와 같은 코드가 많이 나오는데요, 혹시 모르시는 분들이 계실까봐 설명드리자면 여러 파일에서 하나의 header파일을 include할 때 중복선언으로 컴파일러가 에러를 내게 됩니다. 그럴 경우 아래와 같이 define 해주면 에러를 나지 않게 됩니다.
#ifndef ADAPTER_ADAPTER_H_
#define ADAPTER_ADAPTER_H_
...(생략)
#endif /* ADAPTER_ADAPTER_H_ */
계속해서 .c 파일을 보도록 하겠습니다. display와 driver의 호환을 위해 driver의 각 메소드들을 구현하고 있습니다.
static bool open(void);
static bool close(void);
static bool read(uint32_t addr, uint8_t *value);
static bool write(uint32_t addr, uint8_t *value, uint32_t len);
static display_t *display=null;
static driver_t *this =
{
DRIVER_ID_DISPLAY,
open,
close,
read,
write
};
driver_t *setup_display_adapter(void)
{
display = setup_display();
return &this;
}
static bool open(void)
{
if(display == null)
return false;
return display->init();
}
static bool close(void)
{
if(display == null)
return false;
return display->deinit();
}
static bool read(uint32_t addr, uint8_t *value, uint32_t len)
{
if(display == null)
return false;
return display->read(addr, value, (uint16_t) len);
}
static bool write(uint32_t addr, uint8_t *value, uint32_t len)
{
if(display == null)
return false;
return display->draw((uint8_t)(addr >> 8), (uint8_t)(addr&0x00FF), value, len);
}
driver의 write를 display의 draw로 구현한 부분을 보시면 감이 촥하고 오실 겁니다. driver의 address를 display의 x, y 좌표로 변경하였습니다.
내부적으로 display를 이용해 처리하고 외부적으로는 driver_t를 전달해줘서 다른 driver와 동일한 취급을 받도록 하고있습니다. 이것이 wrapper입니다.
그럼 이제 main.c에서 사용하는 예제를 보도록 하겠습니다.
void main(void)
{
set_driver(setup_display_adapter());
get_driver(DRIVER_ID_DISPLAY)->open();
static uint8_t buffer[100];
static uint8_t color = 0;
while(1)
{
color++;
for(int i=0; i<100; i++)
{
buffer[i] = color;
}
get_driver(DRIVER_ID_DISPLAY)->write(0x0000, buffer, 100);
delay_ms(1000);
}
}
setup_display_adapter호출하여 driver를 넘겨주고, 다른 driver와 동일한 방식으로 사용하는 것을 볼 수 있습니다.
위의 예제에서는 x=0, y=0 좌표에 color값을 바꿔가며 1초에 한번씩 화면을 갱신하는 루틴을 구현해 놓고 있습니다.
아쉽게도 위의 코드에서 약간 위험해 보는 부분이 보이네요. 바로 3번째 줄에서 setup_display_adapter 와 16번줄의 DRIVER_ID_DISPLAY가 어떠한 연관이 있는지 모르면 사용할 수가 없게 되는데, 이러한 사항이 문제가 될 수 있습니다.
여러분들이 직접 어떻게 하면 이 문제를 풀 수 있을지 고민해 보는 것도 좋을 거 같습니다.
좋은 하루되세요!
'▶ C Application > 디자인 패턴' 카테고리의 다른 글
Facade 패턴 (0) | 2024.02.12 |
---|---|
Builder 패턴 - 키(Key)처리 (1) | 2024.01.17 |
Adapter 패턴 - 2 (0) | 2023.12.24 |
Adapter 패턴 - 1 (0) | 2023.12.24 |
Factory method 패턴 (0) | 2023.12.23 |