요즘 Emscripten으로 WASM 작업하고 있는데 동작하나 확인을 하기 위해서는 c++ 코드 작성하고, 자바스크립트 작성 하고, 브라우저 켜서 콘솔창 확인하기 너무 번거로운 것이다. 이왕하는 것 c++ 코드로만 테스트를 진행하고 싶다. 그래서 이것저것 찾아봐서 Google Test를 적용시켜 보았다.
GitHub 프로젝트에서 작업할 때, issue를 사용하여 작업 항목을 추적하고 관리하기로 마음 먹었다. issue와 연관된 작업을 수행하기 위해 새로운 브랜치를 만들어야 하는데 이 과정을 더욱 편하게 하기 위해 alias를 사용하여 GitHub issue를 기반으로 새로운 브랜치를 만들도록 했다.
필수 설치 사항
GitHub CLI : GitHub의 기능을 커맨드 라인에서 사용할 수 있도록 도와주는 도구.
git icb 명령을 실행하면, GitHub issue 목록을 검색하고 선택한 issue를 기반으로 브랜치를 만들 수 있다.
코드 설명
이 코드는 다음과 같은 작업을 수행한다.
gh issue list 명령을 사용하여 현재 GitHub 프로젝트의 issue 목록을 가져옵니다.
fzf를 사용하여 사용자에게 issue 목록을 선택하도록 합니다.
사용자가 선택한 issue의 번호와 제목을 awk를 사용하여 적절한 형식으로 가공합니다.
이 단계에서는 awk 명령을 사용하여 사용자가 선택한 issue의 번호와 제목을 가공한다. -F 옵션을 사용하여 입력 필드 구분자를 설정하고, $1과 $3를 사용하여 선택한 issue의 번호와 제목에 접근했다. 그런 다음, gsub() 함수를 사용하여 제목에서 공백을 밑줄(_)로 대체하여 브랜치 이름으로 사용할 수 있도록 했다. 최종적으로, print 함수를 사용하여 적절한 형식으로 가공된 문자열을 출력하도록 했다.
최종적으로 git checkout -b 명령을 사용하여 선택한 issue를 기반으로 새로운 브랜치를 만든다.
하지만 이럴 경우 너무 길고, 불편하기 때문에 git alias에 등록하고 했다. git alias를 사용하면 내가 원하는 축약된 이름으로 위의 명령어를 사용할 수 있다고 생각했기 때문이다.
하지만 git alias에서 이 명령어가 통하지 않았다. ㅠㅠ 여기저기 찾아보고 ai의 도움도 받았다.
여기서(링크) 함수를 선언 후 사용할 수 있다고 했길래, f()라는 함수로 감싸서 실행시켰다.
그 다음 문제점은 바로 터미널에서 실행했을 때는 상관없었지만, alias 파일에 등록할 때는 " "로 감싸야했다. 하지만 나는 " "를 사용했기 때문에 꼬이기 시작한 것이다. 이부분에 대해서는 \를 사용하면 해결된다는 것을 알기 때문에 쉽게 해결할 수 있었다. c/c++ 코딩하면서 얻은 경험치가 여기서 사용이 되다니! 아무튼 \"가 "가 문자열의 일부라는 것을 알려주는 것이기에 되는 것이다.
그 외에 다른 명령어들은 chat gpt한테 물어본 후 함수를 알고 그 함수를 이것저것 테스트하면서 내가 원하는 형식으로 만들 수 있게 되었다. 아마 수십번 테스트 한 것이다. 언제 한번 본격적으로 배워야하는데 미루고 있다.
위에는 살짝 가식은 섞은 것이고, 진짜 이유는 맥북에 모니터를 연결하지 못할 경우, 크롬 켰다, vscode 켰다 하는게 귀찮아서 CLI로 해결하자는 마음이 거대해졌기 때문이다.
그리고 fzf를 사용해보고, 왠지 모르게 나의 도전욕구를 건드리고 있다. 많은 아이디어를 생각나게 하는 것은 오랜만인걸. 결과도 바로바로 볼 수 있어서 좋다.
인터페이스로 만든 함수가 호출 시 이 함수가 호출 될 것이다. 호출이 되면 애니메이션이 끝나게 되는 상황이기 때문에 콤보를 초기화 해준다. 그 다음 애니메이션에서 애니메이션이 끝나는 부분에 Interface함수를 호출해야 한다.
그렇게 하기 위해서는 AnimNotify를 만들어 준 후 Anim Notify Blueprint 클래스를 제작해야한다.
AnimNotify Blueprint 클래스를 제작한다.
Interface함수를 호출하는 노드를 제작한다.
원하는 애니메이션 시점에 만들어준 Notify를 추가하면 된다. 이렇게 해서 끝나는 시점까지 누르지 않으면 콤보가 초기화 되는 조작을 하게 되었다.
그런데 말입니다….
누르는 속도에 따라 엄청나게 빠르게 칼질하는 플레이어의 모습을 볼 수 있다.
이렇게 되는 이유는 마우스 클릭할 때마다 AttackStart()의 애니메이션이 재생되기 때문이다. 자연스러운 동작을 보고 싶으면 애니메이션이 끝날 때 콤보가 있을 경우 다음 애니메이션으로 보여주게 하는 것이다.
그러면 우선 AttackStart부분을 수정해야 한다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
// MyPlayer.cpp
voidAMyPlayer::AttackStart() { //attack이 true 일 때 클릭하면 if (m_bAttack) { //콤보상태를 true한다. m_bCombo = true; } else {//그렇지 않을 경우 //m_bAttack 상태를 true 바꾸고, 콤보도 0으로 바꾸고 m_bAttack = true; m_iCombo = 0;
Web에서 웹캠 프레임 데이터를 받아 처리를 하는 프로그램을 만들고 있다. 근데 시간이 지나면 메모리 문제가 발생한다. 이를 해결하기 위해 여러 방법을 시도하게 되는데!
현재 상황과 문제점
프로세스는 웹캠 프레임 데이터를 처리하기 위해 큐를 활용하고 있다. 그러나 매번 새로운 데이터가 추가될 때마다 메모리를 할당하고 큐에 저장한 후, 데이터를 처리한 후에 해당 데이터의 메모리를 해제해야 하는 과정에서 문제가 발생하고 있다. 이 과정에서 메모리 할당이 해제보다 빠르게 진행되어 메모리 사용량이 지나치게 늘어나는 현상이 나타나고 있다. 이로 인해 큐에 저장되는 데이터의 양이 해제되는 데이터의 양보다 많아지는 문제가 발생하고 있다.
현재 설정된 최대 메모리 한계는 약 2GB이지만, 실제 데이터가 저장되는 양은 이를 초과한다. 예를 들어, 각 데이터가 800(width) * 600(height) * 4(rgba) 바이트 크기로 저장되고 이러한 데이터가 1729개 저장된다면 전체 메모리 사용량은 3.18GB에 이를 것이다.
해결 방안
이 문제를 해결하기 위해 매번 새로운 데이터가 추가될 때마다 메모리를 할당하는 것보다는 미리 몇 개의 메모리를 할당하고 재사용하는 방법을 추천 받았다. 이를 위해 원형 큐를 변형하여 사용하기로 결정했다.
원형 큐를 선택한 이유는 미리 몇 개의 메모리를 할당하여 재사용할 수 있으며, 큐가 가득 찬 경우 가장 오래된 데이터를 제거하고 새로운 데이터를 추가할 수 있기 때문이다. 이러한 방식은 웹캠 프레임 데이터의 손실이 허용되었기 때문에 가능했다.
해야할 조치는 다음과 같다.
매번 데이터를 저장할 때마다 새로운 메모리를 할당하는 것이 아니라, 몇 개의 메모리를 미리 할당하여 재사용해야한다.
큐에 데이터가 가득 찬 경우, 가장 오래된 데이터를 제거하고 새로운 데이터를 추가해야 한다. 이를 통해 큐의 크기를 일정하게 유지할 수 있다.
원형 큐 활용하기
위의 문제를 해결하기 위해 원형 큐를 활용하여 구현했다.
원형 큐의 생성
1 2 3 4 5
CircularQueue(unsignedint buffer_size) : head_(0), tail_(0), size_(0), buffer_size_(buffer_size) { for (int i = 0; i < MAX_BUFFER_SIZE; i++) { data_.push_back(newunsignedchar[buffer_size]); } }
원하는 버퍼 사이즈만큼 추가하여 원형 큐를 생성한다. 이때, head는 나중에 데이터를 가져올 때의 인덱스를, tail은 데이터를 추가할 위치를 나타낸다.
OpenGL을 사용하여 작업하는데 렌더링이 제대로 되지 않는 경우가 빈번해서 꽤나 골치아팠다. 이럴 때 디버깅을 할 수 있는 도구가 있을까 찾아보다가 렌더독(RenderDoc)을 알게 되었다! 렌더독을 사용하면서 많은 문제들을 해결할 수 있게 되었다. 지금은 렌더독을 사용하는 방법에 대해 정리해보고자 한다.
해당 명령어를 사용하면 빌드를 할 수 있지만, Visual Studio Code를 사용하면 쉽게 할 수 있다.
vscode 폴더
.vscode 폴더는 Visual Studio Code 프로젝트나 작업 공간에서 설정과 관련된 파일을 보관하는 디렉토리이다. 이 폴더는 특정 프로젝트 또는 작업에 대한 설정 및 환경 구성을 담당한다.
tasks.json (빌드 명령어 설정 파일): 이 파일은 프로젝트를 빌드하기 위한 명령어와 설정을 정의.
launch.json (디버깅 설정 파일) : 디버깅을 위한 설정을 담고 있으며, 디버거 설정과 실행 환경을 구성.
생성된 파일들은 Visual Studio Code에서 C++ 개발 환경을 구성하고 프로젝트를 관리하는 데 도움을 준다.
tasks.json
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
{ "version":"2.0.0", "tasks":[ { "label":"cmake build and run",// 작업 이름 "type":"shell",// 명령어 실행을 위한 shell 타입 "command":"cmake -B ./build -G 'Visual Studio 16 2019' .; cmake --build ./build --config Debug; cd ./build/Debug; ./SampleCPlusPlusProject.exe",// 빌드 및 실행 커맨드 입력 "options":{ "cwd":"${workspaceFolder}"// 현재 작업 디렉토리 설정 }, "group":{ "kind":"build",// 작업 그룹을 빌드로 설정 "isDefault":true// 기본 작업으로 설정 } } ] }
ctrl + shift + b 를 누르면 프로그램이 실행되는 것을 확인할 수 있다.
launch.json
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
{ "version":"0.2.0", "configurations":[ { "name":"cmake build and debug",// 디버그 구성 이름 "type":"cppvsdbg",// C++ 디버그 타입 "request":"launch",// 디버그 실행 요청 "program":"${workspaceFolder}/build/Debug/SampleCPlusPlusProject.exe",// 실행할 바이너리 파일 경로 "args":[],// 실행 시 전달할 명령행 인수 "stopAtEntry":true,// 브레이크 포인트 사용 여부 "cwd":"",// 현재 작업 디렉토리 (의존성 및 기타 파일을 찾기 위함) "environment":[],// 환경 변수 설정 "externalConsole":true,// 외부 콘솔 사용 여부 "preLaunchTask":"cmake build and run"// 디버그 실행 전에 실행할 작업(Task) 이름 } ] }
F5를 누르면 디버거가 실행되며 디버깅을 할 수 있게 된다.
Finish
이제 명령어를 안치고 간단한 단축키로 실행파일을 실행하고, 디버깅도 할 수 있다!!! 쉘 스크립트나 CMake를 이용해서 하나의 명령어로 OS별로 빌드, 실행, 디버깅되면 편하겠다. 이 부분에 대해서 좀 더 연구해봐야 할 듯!!!