JUCE - JUCE의 기본 모듈

LeeTaeHwa·2023년 6월 11일
0

JUCE

목록 보기
1/2

Juce Application

Juce 라이브러리를 처음 생성하면 마주하게 되는 모듈이다. 왜냐하면 JUCEApplication 클래스를 상속받아야 메인 루프를 정의 및 실행을 할 수 있기 때문이다. Juce 애플리케이션의 초기화호 및 진입점(entry point)와 종료점(exit point)과 관련한 기능을 수행하며, 이외에는 프로젝트의 정보를 관리한다. 예제 코드는 다음과 같다.

Example Code

class SweetJuce  : public JUCEApplication
{
public:
	//Don't put any kind of JUCE code in constructor and destructor!
    SweetJuce()  {}
    ~SweetJuce() {}
 
 	//this method will be called when application starts
    void initialise (const String& commandLine) override {
    	//assign new window instance
        sweetWindow.reset (new SweetWindow());
        sweetWindow->setBounds (100, 100, 400, 500);
        sweetWindow->setVisible (true);
    }
 
 	//this method will be called when application quits
    void shutdown() override {
        sweetWindow = nullptr;
    }
 
    const String getApplicationName() override {
        return "Sweet Juce!";
    }
 
    const String getApplicationVersion() override {
        return "0.00001";
    }
 
private:
	//smart pointer and window instance
    std::unique_ptr<SweetWindow> sweetWindow;
};
 
// this generates boilerplate code to launch our app class:
START_JUCE_APPLICATION (SweetJuce)

위의 예제 코드에서 눈여겨 볼 부분은 initialiseshutdown이다. initialise 메소드에서 초기화를 진행하고, shutdown 메소드에서는 애플리케이션을 종료하면서 종료해야 할 서브 프로세스라던가, 해제되어야 할 인스턴스들을 처리해주면 된다. 그리고 override 키워드가 붙은 것을 보면 알 수 있지만, initialiseshutdown은 가상 함수들이다.

이외에는 프로젝트의 정보를 반환하는 정도이며, 주석으로도 명시했지만 생성자 및 소멸자에서 Juce와 관련한 함수들을 호출하면 안된다.

DocumentWindow

GUI 프로젝트를 만든다면 자주 보게 될 클래스다. Juce의 윈도우 클래스로 윈도우를 생성 및 관리하는 것과 관련한 모듈이다. 보통 '애플리케이션 = 윈도우'로 생각하는 경우가 많은데, 애플리케이션에서 편의를 제공하기 위해 윈도우를 사용하는 것이다. 때문에 윈도우와 애플리케이션 모듈은 분리하는 것이 맞다.

그리고 보통의 GUI 라이브러리들은 윈도우와 그 컨텐츠들을 통합하여 관리하는데, Juce는 윈도우와 컨텐츠를 분리하여 관리한다. 때문에 공식 홈페이지에서 DocumentWindow를 순수하게 윈도우를 관리하는 데에만 사용 할 것을 권장한다.

그렇다면 윈도우에 필요한 내용들을 어떻게 다룰 것인가 하는 문제가 남는다. 이와 관련하여서는 후술하도록 하겠다.

Example Code

class SweetWindow : public juce::DocumentWindow {
    public:
        SweetWindow (juce::String name) : DocumentWindow (
            name, //윈도우의 이름
            juce::Desktop::getInstance() //윈도우의 색상값
                .getDefaultLookAndFeel()
                .findColour (juce::ResizableWindow::backgroundColourId),
            DocumentWindow::allButtons //윈도우 헤드바에 표시할 버튼(종료 및 최소화 등)
        ) {
            setUsingNativeTitleBar (false);
            setContentOwned (new SweetComponent(), true);

           #if JUCE_IOS || JUCE_ANDROID
            setFullScreen (true);
           #else
            setResizable (true, true);
            centreWithSize (getWidth(), getHeight());
           #endif

            setVisible (true);
        }

        void closeButtonPressed() override {
            JUCEApplication::getInstance()->systemRequestedQuit();
        }
    private:
        JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MainWindow)
    };

생성자 코드를 보면 상당히 많은 인자를 넘겨주는 것을 볼 수 있다. 첫번째로는 윈도우의 이름을 정해준다. String 이 C++에서 제공하는 표준 std::string 이 아닌데, Juce에서 자체적으로 제공하는 String 라이브러리를 사용한다. 지금은 언급하는 정도로 다루고, 좀 더 상세한 내용은 추후에 다루도록 하겠다.

그리고 생성자의 초기화 리스트에서 특이한 함수를 볼수 있는데, 다음 코드를 보도록하자.

	juce::Desktop::getInstance() //Desktop 인스턴스를 호출
    	.getDefaultLookAndFeel() //기본LookAndFeel 인스턴스 호출
        .findColour(juce::ResizableWindow::backgroundColourId)
        //색상값 탐색

이 코드들 또한 사전지식이 있어야 이해가 가능한데, DesktopLookAndFeel에 대해 어느정도 이해를 하고 있어야한다. 먼저, Desktop 클래스는 이름 그대로 데스크탑, 머신에 대한 정보를 담은 모듈로 다른 프레임워크에서는 context 라는 이름으로 유사하게 사용되기도 한다. 그리고 LookAndFeel 클래스는 이름이 상당히 특이한데, 겉 모양새에 대한 모듈이다. 어쩌면 스킨이라는 표현이 더 와닿을 지도 모르겠다.

그 다음으로는 어떤 버튼들을 사용 할 것인지를 지정하면 기본적으로 넘겨준다. 그리고 생성자 블록 안의 코드들을 보면 몇 가지 설정들을 해주고 있다. 가장 눈여겨 보아야 할 부분이 setOwnedComponent 이다. 앞서 설명 했듯이, DocumentWindow 는 순수하게 윈도우와 관련한 기능들만 다루며, 그 내용에 대한 것들 별도로 정의해주어야 한다. 그 내용들의 정의가 바로 SweetComponent 안에 들어가 있는 것이다.

그래서 Component 를 상속받아 윈도우에 필요한 컨트롤(UI)와 동작들을 정의해줘야 한다. 지금은 이 정도로만 다루기로 하며, Component에 대한 더 자세한 내용은 다른 포스팅에서 다루도록 하겠다.

마지막으로 매크로를 호출하는데, 해당 클래스가 복사가 불가능하게 만들고, 동시에 메모리 누수 여부를 관찰하는 것이다. C++의 고질적인 문제중 하나가 객체의 복사 문제와 메모리 누수이다. 그래서 복사를 불가능하게 하고, GC가 없기 때문에 자체적으로 이에 대한 대책을 강구해야 한다. Juce에서는 LeackObjectDetector 라는 모듈을 통해서 메모리를 관리 할 수 있는데, 이에 대한 자세한 내용은 다른 포스팅에서 다루겠다.

profile
하늘을 향해 걸어가고 있습니다.

0개의 댓글