| name | unspaghettify-your-code |
| description | Essential rules and methods you must follow when refactoring code. Use when this capability is needed. |
| metadata | {"author":"dj-oyu"} |
ãšãŒãžã§ã³ãã¹ãã«: æçããã³ãŒãã3å±€ã¢ãŒããã¯ãã£ã«ãªãã¡ã¯ã¿ãªã³ã°ãã
å²åŠ: ãã€ãªãã¡ã¯ã¿ãªã³ã°ãã¹ãã
â ãªãã¡ã¯ã¿ãªã³ã°ãã¹ãã§ãªããšã
- æ°æ©èœã®å®è£
äž: ãŸãåããããšãåªå
- èŠä»¶ãäžæç¢º: äœãæ£è§£ãåãããªã段éã§æ§é åã¯ç¡æå³
- ãããã¿ã€ãã³ã°/PoC段é: æ€èšŒãç®çãã³ãŒãå質ã¯äºã®æ¬¡
- 1åéãã®ã¹ã¯ãªãã: äœ¿ãæšãŠã³ãŒãã«æè³ããªã
åå: "Premature optimization is the root of all evil" (æ©ãããæé©åã¯è«žæªã®æ ¹æº)
â
ãªãã¡ã¯ã¿ãªã³ã°ãã¹ããšã
以äžã®ãã¹ãŠãæºããå Žå:
- èŠä»¶ãåºãŸã£ã: äœãäœãã¹ããæç¢ºã«ãªã£ã
- åäœæ€èšŒæžã¿: PoC/ãããã¿ã€ãã§åäœã確èªãã
- ãã¿ãŒã³ãèŠãã: ç¹°ãè¿ãã責åã®æ··åšãæç¢ºã«ãªã£ã
- ä¿å®ãå¿
èŠ: ããããé·æçã«ã¡ã³ããã³ã¹ãã
- æ¡åŒµäºå®: é¡äŒŒæ©èœã远å ããèšç»ããã
åå: "Make it work, make it right, make it fast"
ãªãã¡ã¯ã¿ãªã³ã°å€æåºæº
å®éçãªåºæº
| ææš | ãããå€ | ã¢ã¯ã·ã§ã³ |
|---|
| ãã¡ã€ã«è¡æ° | > 500è¡ | åå²ãæ€èš |
| 颿°è¡æ° | > 100è¡ | åå²ãæ€èš |
| 颿°å
ã®è²¬å | 3ã€ä»¥äž | åé¢ãæ€èš |
| éè€ã³ãŒã | 3ç®æä»¥äž | æœè±¡åãæ€èš |
宿§çãªåºæº
- "ããã«äœãæžãã°ãããåãããªã" â 責åãäžæç¢º
- "倿Žã®åœ±é¿ç¯å²ãäºæž¬ã§ããªã" â çµå床ãé«ã
- "ãã¹ããæžããªã" â äŸåé¢ä¿ãè€é
- "䌌ãã³ãŒãã3åæžãã" â æœè±¡åã®æ©äŒ
3å±€ã¢ãŒããã¯ãã£æ¹é
ç®ç
- é¢å¿ã®åé¢: ããŒããŠã§ã¢/ããžãã¹ããžãã¯/UIã®åé¢
- ãã¹ã¿ããªãã£: åå±€ãç¬ç«ããŠãã¹ãå¯èœ
- åå©çšæ§: HALå±€ã¯ä»ãããžã§ã¯ãã§ãå©çšå¯èœ
- ä¿å®æ§: 倿Žã®åœ±é¿ç¯å²ãéå®
å±€ã®å®çŸ©
âââââââââââââââââââââââââââââââââââââââââââ
â Layer 3: Application Layer â
â - main(), CLI parsing, signal handling â
â - 責å: ã©ã€ããµã€ã¯ã«ç®¡ç â
â - ãµã€ãº: ~100è¡ â
âââââââââââââââââââââââââââââââââââââââââââ
â
âââââââââââââââââââââââââââââââââââââââââââ
â Layer 2: Pipeline/Business Logic â
â - ã¯ãŒã¯ãããŒçµ±åãããŒã¿ãã㌠â
â - 責å: è€æ°ã®HALãçµã¿åãããåŠç â
â - ãµã€ãº: ~200-300è¡/ãã¡ã€ã« â
âââââââââââââââââââââââââââââââââââââââââââ
â
âââââââââââââââââââââââââââââââââââââââââââ
â Layer 1: Hardware Abstraction (HAL) â
â - ããŒããŠã§ã¢API ã®èãã©ãã㌠â
â - 責å: åäžããŒããŠã§ã¢ã®æäœ â
â - ãµã€ãº: ~200-300è¡/ãã¡ã€ã« â
âââââââââââââââââââââââââââââââââââââââââââ
åå±€ã®è²¬å
Layer 1: HAL (Hardware Abstraction Layer)
DO (æšå¥š):
- â
ããŒããŠã§ã¢APIã®çŽæ¥åŒã³åºããã«ãã»ã«å
- â
ãšã©ãŒãã³ããªã³ã°ãçµ±äž
- â
ãªãœãŒã¹ç®¡ç (create/destroy) ãæäŸ
- â
ããŒããŠã§ã¢åºæã®èšå®ãé èœ
DON'T (çŠæ¢):
- â ããžãã¹ããžãã¯ãå«ããªã
- â ä»ã®HALå±€ãåŒã°ãªã (äŸåããªã)
- â ã°ããŒãã«ç¶æ
ãæããªã
- â ã¢ããªã±ãŒã·ã§ã³åºæã®åŠçãå«ããªã
ãµã³ãã« (ä»åã®å®è£
):
int vio_create(vio_context_t *ctx, int camera_index, ...);
int vio_start(vio_context_t *ctx);
int vio_get_frame(vio_context_t *ctx, hbn_vnode_image_t *frame, int timeout_ms);
void vio_destroy(vio_context_t *ctx);
Layer 2: Pipeline/Business Logic
DO (æšå¥š):
- â
è€æ°ã®HALå±€ãçµã¿åããã
- â
ããŒã¿ãããŒãå¶åŸ¡
- â
ããžãã¹ããžãã¯ãå®è£
- â
ç¶æ
管ç
DON'T (çŠæ¢):
- â ããŒããŠã§ã¢APIãçŽæ¥åŒã°ãªã
- â main()ãå«ããªã
- â CLIåŒæ°è§£æãå«ããªã
ãµã³ãã« (ä»åã®å®è£
):
typedef struct {
vio_context_t vio;
encoder_context_t encoder;
SharedFrameBuffer *shm_h264;
volatile bool *running_flag;
} camera_pipeline_t;
int pipeline_run(camera_pipeline_t *pipeline, volatile bool *running_flag);
Layer 3: Application Layer
DO (æšå¥š):
- â
main()颿°
- â
CLIåŒæ°è§£æ
- â
ã·ã°ãã«ãã³ããªã³ã°
- â
ã©ã€ããµã€ã¯ã«ç®¡ç
DON'T (çŠæ¢):
- â ããžãã¹ããžãã¯ãå«ããªã
- â ããŒããŠã§ã¢APIãçŽæ¥åŒã°ãªã
- â è€éãªåŠçãå«ããªã (Pipelineå±€ã«å§è²)
ãµã³ãã« (ä»åã®å®è£
):
int main(int argc, char *argv[]) {
}
åœåèŠå
ãã¡ã€ã«åœå
| å±€ | ãã¿ãŒã³ | äŸ |
|---|
| HAL | {hardware}_lowlevel.c/h | vio_lowlevel.c, encoder_lowlevel.c |
| Pipeline | {domain}_pipeline.c/h | camera_pipeline.c |
| Application | {app}_main.c | camera_daemon_main.c |
颿°åœå
| å±€ | ãã¿ãŒã³ | äŸ |
|---|
| HAL | {hardware}_{verb}() | vio_create(), encoder_encode_frame() |
| Pipeline | pipeline_{verb}() | pipeline_run(), pipeline_create() |
ã€ã³ãã©ã¹ãã©ã¯ãã£
ãã°ã©ã€ãã©ãª
èŠä»¶:
- ãã°ã¬ãã« (DEBUG, INFO, WARN, ERROR)
- ã¢ãžã¥ãŒã«å衚瀺
- ã¹ã¬ããã»ãŒã
- çµã¿èŸŒã¿ã·ã¹ãã ã§è»œé (~150è¡)
å®è£
: logger.c/h
äœ¿ãæ¹:
#include "logger.h"
log_init(LOG_LEVEL_INFO, stdout, 0);
LOG_INFO("VIO", "Pipeline created successfully");
LOG_ERROR("Encoder", "hb_mm_mc_configure failed: %d", ret);
æšå¥š:
- â
printf/fprintf ã®ä»£ããã«LOG_*ãã¯ãã䜿ã
- â
ã¢ãžã¥ãŒã«åã¯åºå®æåå (ãã¡ã€ã«åç±æ¥)
- â
ãšã©ãŒæã¯å¿
ããšã©ãŒã³ãŒããåºå
çŠæ¢:
- â
printfã§ãšã©ãŒãåºåããªã (LOG_ERRORã䜿ã)
- â ãã°ã¬ãã«ãç¡èŠããªã (DEBUGæ
å ±ã¯LOG_DEBUGã§)
ãªãã¡ã¯ã¿ãªã³ã°ããã»ã¹
Phase 1: åæ
-
æ¢åã³ãŒãã®çè§£
- 責åãåæ (ããŒããŠã§ã¢æäœ / ããžãã¹ããžã㯠/ UI)
- äŸåé¢ä¿ãå³ç€º
- éè€ã³ãŒããç¹å®
-
å¢çã®ç¹å®
- ã©ãã§HALå±€ãšPipelineå±€ãåããã
- ã©ã®ããŒããŠã§ã¢ãã«ãã»ã«åããã
Phase 2: HALå±€ã®æœåº
-
1ã€ã®ããŒããŠã§ã¢ã«éäž
- äŸ: VIO (VINâISPâVSE)
- äŸ: Encoder (H.264)
-
æå°éã®APIãèšèš
- create/start/process/stop/destroy ãã¿ãŒã³
- contextæ§é äœã§ã¹ããŒãã管ç
-
æ¢åã³ãŒãããæœåº
- ããŒããŠã§ã¢APIã®åŒã³åºããã³ããŒ
- ãšã©ãŒãã³ããªã³ã°ãçµ±äž
- ãã°åºåãçµ±äž
-
ãã¹ã
- å
ã®ã³ãŒããšåãåäœãããã確èª
Phase 3: Pipelineå±€ã®æœåº
-
ã¯ãŒã¯ãããŒãç¹å®
- äŸ: VIO â Encoder â å
±æã¡ã¢ãª
-
HALå±€ãçµã¿åããã
- è€æ°ã®HAL contextãä¿æ
- ããŒã¿ãããŒãå®è£
-
ãã¹ã
- ãšã³ãããŒãšã³ãã§åäœç¢ºèª
Phase 4: Applicationå±€ã®ç°¡çŽ å
-
main()ãã·ã³ãã«ã«
- åŒæ°è§£æ
- Pipelineå±€ã®åŒã³åºã
- ã¯ãªãŒã³ã¢ãã
-
ãã¹ã
- å
ã®æ©èœãšåçã確èª
- ããã©ãŒãã³ã¹æ€èšŒ (FPSç)
ãããžã§ã¯ãåºæã®è©³çް
D-Robotics X5 åºæ
ããŒããŠã§ã¢å¶çŽ
| é
ç® | å¶é | å¯ŸåŠ |
|---|
| H.264 Bitrate | <= 700 kbps | ããã©ã«ã600kbpsæšå¥š |
| Camera Index | 0 or 1 | Camera 0âMIPI Host 0, Camera 1âMIPI Host 2 |
| bus_select | åžžã«0 | äž¡ã«ã¡ã©ã§0ãäœ¿çš |
éèŠAPI
VIO (Low-level):
hbn_camera_create() - ã«ã¡ã©åæå
hbn_vnode_open() - VIN/ISP/VSEããŒãäœæ
hbn_vflow_bind_vnode() - ãã€ãã©ã€ã³æ¥ç¶
hbn_vnode_getframe() - ãã¬ãŒã ååŸ
Encoder (Low-level):
hb_mm_mc_initialize() - ãšã³ã³ãŒããŒåæå
hb_mm_mc_configure() - ãšã³ã³ãŒããŒèšå®
hb_mm_mc_start() - ãšã³ã³ãŒããŒèµ·å
hb_mm_mc_queue_input_buffer() - NV12å
¥å
hb_mm_mc_dequeue_output_buffer() - H.264åºå
ãã«ãèšå®
å¿
é ã©ã€ãã©ãª:
LDLIBS := -lrt -lpthread -lcam -lvpf -lhbmem -lmultimedia
ããããŒã€ã³ã¯ã«ãŒã:
#include "hb_camera_interface.h"
#include "hb_camera_data_config.h"
#include "hbn_api.h"
#include "hb_media_codec.h"
#include "hb_mem_mgr.h"
æåææš
ãªãã¡ã¯ã¿ãªã³ã°ãæåãããã®å€æåºæº:
å¿
é æ¡ä»¶
- â
æ©èœç䟡æ§: å
ã®ã³ãŒããšåãåäœããã
- â
æ§èœç¶æ: FPSçã®ããã©ãŒãã³ã¹ãå£åããªã
- â
ãã«ãæå: èŠåãªãã§ãã«ãã§ãã
æšå¥šæ¡ä»¶
- â
ãã¡ã€ã«ãµã€ãº: åãã¡ã€ã«ã300è¡ä»¥äž
- â
責åæç¢º: åãã¡ã€ã«ã®åœ¹å²ã1æã§èª¬æã§ãã
- â
äŸåæå°: åå±€ãäžã®å±€ã®ã¿ã«äŸå
- â
ãã¹ãå¯èœ: åå±€ãç¬ç«ããŠãã¹ãå¯èœ
- â
ãã°æŽç: çµ±äžããããã°åºå
ãã§ãã¯ãªã¹ã
ãªãã¡ã¯ã¿ãªã³ã°å
ãªãã¡ã¯ã¿ãªã³ã°äž
ãªãã¡ã¯ã¿ãªã³ã°åŸ
åèæç®
- Martin Fowler - "Refactoring: Improving the Design of Existing Code"
- Robert C. Martin - "Clean Architecture"
- Kent Beck - "Test Driven Development: By Example"
ãã®ã¹ãã«ã®äœ¿ãæ¹
ãŠãŒã¶ãŒããªãã¡ã¯ã¿ãªã³ã°ãäŸé Œããå Žå
User: "camera_daemon_drobotics.c (886è¡) ããªãã¡ã¯ã¿ãªã³ã°ããã"
Agent:
1. ãŸãå€æåºæºã確èªããŸã
- èŠä»¶ã¯åºãŸã£ãŠããŸããïŒ
- åäœæ€èšŒã¯æžãã§ããŸããïŒ
- ä¿å®ã»æ¡åŒµã®äºå®ã¯ãããŸããïŒ
2. (æ¡ä»¶ãæºããå Žå) Phase 1: åæ
- ãã¡ã€ã«ãèªã¿ã責åãåæ
- HALå±€åè£ãç¹å®
3. Phase 2-4: å®è£
- HALå±€ãæœåº
- Pipelineå±€ãäœæ
- Applicationå±€ãç°¡çŽ å
4. æ€èšŒ
- ããã©ãŒãã³ã¹ãã¹ã
- åäœç¢ºèª
ãšãŒãžã§ã³ããèªå倿ããå Žå
ãšãŒãžã§ã³ãã¯ä»¥äžã®ç¶æ³ã§èªåçã«ãªãã¡ã¯ã¿ãªã³ã°ãææ¡ããŸã:
- ãã¡ã€ã«ã500è¡ãè¶
ããè€æ°ã®è²¬åãæ··åšããŠãã
- ãŠãŒã¶ãŒããæŽçãããããæ§é åãããããšçºèšãã
- é¡äŒŒã³ãŒãã3ç®æä»¥äžã«åºçŸãã
ææ¡åœ¢åŒ:
"ãã®ãã¡ã€ã«ã¯{è¡æ°}è¡ã§ã{責å1}ãš{責å2}ãæ··åšããŠããŸãã
3å±€ã¢ãŒããã¯ãã£ã«ãªãã¡ã¯ã¿ãªã³ã°ããããšã§:
- åãã¡ã€ã«ã{äºæ³è¡æ°}è¡çšåºŠã«åãŸã
- ãã¹ã¿ããªãã£ãåäžãã
- ä¿å®æ§ãåäžãã
ãªãã¡ã¯ã¿ãªã³ã°ã宿œããŸããïŒ"
ã¢ã³ããã¿ãŒã³
â æ©ããããªãã¡ã¯ã¿ãªã³ã°
NGäŸ:
æ£è§£: å°ããã·ã³ãã«ãªã³ãŒãã¯ãã®ãŸãŸæ®ã
â éåºŠãªæœè±¡å
NGäŸ:
AbstractFactoryBuilder* builder = createAbstractFactoryBuilder();
æ£è§£: 3ç®æä»¥äžã§éè€ããŠããæœè±¡åãæ€èš
â ç¡æå³ãªåå²
NGäŸ:
æ£è§£: æç¢ºãªè²¬åãæã€åäœã§åå²
ä»åã®ã±ãŒã¹ã¹ã¿ãã£
Before (PoC段é)
camera_poc_lowlevel.c - 639è¡
- VIOæäœ + Encoderæäœ + ã¡ã€ã³ã«ãŒããæ··åš
- ç®ç: 30fpséæã®æ€èšŒ â â
æå
倿
- èŠä»¶åºå®: 2ã«ã¡ã©åæ30fps
- åäœæ€èšŒæžã¿: PoCã§éæ
- ä¿å®äºå®: ããŒã¢ã³ãšããŠé·æéçš
- æ¡åŒµäºå®: ãã³ãŒããŒè¿œå ãªã©
â ãªãã¡ã¯ã¿ãªã³ã°æ±ºå®
After (ãªãã¡ã¯ã¿ãªã³ã°åŸ)
vio_lowlevel.c/h - 334è¡ (HAL)
encoder_lowlevel.c/h - 203è¡ (HAL)
camera_pipeline.c/h - 217è¡ (Pipeline)
camera_daemon_main.c - 177è¡ (Application)
logger.c/h - 106è¡ (Infrastructure)
åèš: 1037è¡ (PoC 639è¡ãã400è¡å¢)
ãã¬ãŒããªã:
- ã³ãŒãéã¯å¢ããããåãã¡ã€ã«ã®è²¬åãæç¢ºã«
- ãã¹ã¿ããªãã£åäž (åå±€ãç¬ç«ãã¹ãå¯èœ)
- åå©çšæ§åäž (HALå±€ã¯ä»ãããžã§ã¯ãã§ã䜿çšå¯)
- ä¿å®æ§åäž (倿Žã®åœ±é¿ç¯å²ãéå®)
çµæ:
- æ©èœç䟡æ§: â
åãåäœ
- æ§èœç¶æ: â
Camera 0: 29.87 FPS, Camera 1: 30.40 FPS
- ãã«ã: â
èŠåãªã
ãŸãšã
ãªãã¡ã¯ã¿ãªã³ã°ã®éèš:
"Make it work, make it right, make it fast"
ãŸãåãããæ¬¡ã«æ£ãããããæåŸã«éãããã
ãªãã¡ã¯ã¿ãªã³ã°ãã¹ãã¿ã€ãã³ã°:
èŠä»¶ãåºãŸããåäœã確èªã§ããé·æä¿å®ãå¿
èŠã«ãªã£ããšãã
ãããŸã§ã¯ãæ±ããŠãçŽ æ©ãåãã
Converted and distributed by TomeVault â claim your Tome and manage your conversions.