Lua Interface
Lua 스크립팅 - C++ 브릿지, Drawing Tools, 모듈 시스템
모듈 개요
Lua Interface는 ImEDA의 스크립팅 계층입니다. sol2 라이브러리를 통해 C++ 엔진 기능을 Lua에 노출하며, 288개의 Drawing Tool 스크립트가 Lua로 구현되어 있습니다.
sol2 Library 288 Drawing Tools lua-protobuf lpeg / luaext
Lua ↔ C++ 브릿지
C++ 엔진 함수를 Lua에서 호출할 수 있도록 luainterface.cpp에서 바인딩합니다. sol2로 C++ 클래스와 함수를 Lua usertype으로 등록합니다.
Lua ↔ C++ 통신 구조
Lua Script
.lua 파일
.lua 파일
↓ ↑
sol2 Binding
luainterface.cpp
luainterface.cpp
__ccall Bridge
imeda wxWidgets
imeda wxWidgets
↓ ↑
C++ Engine
imengine 핵심 로직
imengine 핵심 로직
sol2 usertype 규칙
sol2 호출 규칙
sol2 usertype은 geo.Type.new(...) 형식으로 생성해야 합니다. geo.Type(...) 직접 호출은 불가합니다 (sol2 __call 미지원).
-- sol2 usertype 사용 예시
local pt = geo.VECTOR2D.new(100, 200) -- O: .new() 사용
local box = geo.BOX2I.new(0, 0, 500, 300) -- O: .new() 사용
-- local pt = geo.VECTOR2D(100, 200) -- X: __call 미지원
on_lua_command_call 패턴
C++ 측에서 Lua 명령을 처리하는 핵심 패턴입니다.
// .h 선언
int on_lua_command_call(const char *cmd, void *LL) override;
using super = <ParentClass>;
// .cpp 구현
#include <strswitch.h>
#include <c_lua.h>
int ClassName::on_lua_command_call(const char *cmd, void *LL) {
lua_State *L = (lua_State *)LL;
STR_SWITCH_BEGIN(cmd)
CASE("doSomething") {
const char* arg = lua_tostring(L, 3);
lua_pushboolean(L, true);
return 1;
}
STR_SWITCH_END()
return super::on_lua_command_call(cmd, LL);
}
strswitch.h 매크로 주의
반드시 CASE("...")를 사용해야 합니다. STR_CASE는 존재하지 않는 매크로입니다.
Lua 스택 규칙
엔진의 on_lua_command_call은 Lua 스택 절대 위치(1,2,3)로 인수에 접근합니다.
lua_settop(L, 0); // 스택 초기화 (필수)
lua_pushnil(L); // pos 1: self
lua_pushstring(L, cmd); // pos 2: cmd
lua_pushboolean(L, val); // pos 3: value
s_luaCommand(m_frame, cmd, L);
| 스택 위치 | 역할 | 타입 |
|---|---|---|
| 1 | self (객체 참조) | userdata / nil |
| 2 | cmd (명령 이름) | string |
| 3+ | 인수 | 다양 |
Drawing Tools - Lua 스크립트
ImEDA의 모든 드로잉 도구는 Lua 스크립트로 구현되어 있습니다. 문서 유형별 288개 스크립트.
스크립트 위치
install/script/lua/tools/<docType>/<toolName>.lua
# 예시:
install/script/lua/tools/sch/wire.lua # 회로도 배선
install/script/lua/tools/sch/symbol.lua # 심볼 배치
install/script/lua/tools/pcb/track.lua # PCB 트랙
install/script/lua/tools/pcb/via.lua # 비아 배치
install/script/lua/tools/epd/line.lua # EPD 선 그리기
2-Point 드로잉 패턴
2-Point 드로잉 흐름
Click (P1)
시작점 설정
시작점 설정
Drag (P2 추적)
실시간 미리보기
실시간 미리보기
Click (P2)
고정 + Commit
고정 + Commit
↓
Reset
상태 초기화
상태 초기화
P1 대기
다음 도형
다음 도형
| 상태 | 동작 | Cancel 시 |
|---|---|---|
| pointCount == 0 | P1 대기 | QueueAction("action_edit_select") |
| pointCount > 0 | P2 추적 | 마지막 포인트 제거 |
| P2 클릭 | 도형 확정 + Commit | - |
Lua 코딩 규칙
local function 필수
모든 함수는 local function으로 선언. 전역 함수는 이름 충돌 유발하므로 금지.
printf() 포맷
{} C++20 포맷 권장. 폴백: % string.format → tab 연결.
모듈 Export
return { Name = localFunc, ... } 패턴으로 내보냅니다.
-- Lua 모듈 패턴
local function onInit()
-- 초기화
end
local function onDraw(ctx)
local pt = geo.VECTOR2D.new(ctx.x, ctx.y)
printf("Position: {} {}", pt.x, pt.y)
end
return {
OnInit = onInit,
OnDraw = onDraw,
}
__ccall 브릿지 (imeda wxWidgets)
| 플랫폼 | 브릿지 | 예시 |
|---|---|---|
| devhome (VCL) | cadframe1.Method | cadframe1.SetCursor("cross") |
| imeda (wxWidgets) | __ccall | __ccall("SetCursor", "cross") |
관련 라이브러리
| 라이브러리 | 용도 | 설명 |
|---|---|---|
lua-protobuf | 직렬화 | Lua에서 Protocol Buffers 읽기/쓰기 |
lpeg | 파싱 | PEG 기반 텍스트 파서 |
luaext | 확장 | Lua 표준 라이브러리 확장 |
sol2 | C++ 바인딩 | C++ ↔ Lua 타입 자동 변환 |
참조 구현 경로
# 검증된 드로잉 도구 패턴 원본
D:\devhome\install\script\lua\oop\drawtool
# ImEDA 드로잉 도구 스크립트
install/script/lua/tools/<docType>/<toolName>.lua