Autor Wątek: Jak napisać fundamenty frameworka czy silnika  (Przeczytany 2775 razy)

Offline LizarD

  • Użytkownik

# Wrzesień 07, 2012, 19:31:25
Witam!

Pisząc takie rzeczy trzeba sobie ładnie poukładać kilka podstawowych rzeczy, tylko jak to zrobić ? Zawsze pisałem sobie klasę CCore która przechowywała wejście do pętli komunikatów, metodę onInit w której tworzyło się urządzenie wczytywało zasoby itp.
class CCore
{
public:
        bool onInit();
        void onRelease();

        void onUpdate();
void onHandleEvents();       
        void onDraw();

         void enterMainLoop();
};

Kolejna sprawa to okno, a raczej obsługa wielu okien, pisać czy nie ? Komuś to było do czegoś potrzebne ?
W Funkcji obsługi komunikatów miałem kilka metod do wypełnienia ( onChangeSize, onMessage ), te metody wywoływane są wtedy gdy przyjdzie odpowiedni komunikat, użytkownik sam je wypełniał wraz z metodami onInit onRelease itp

Założenie miałem takie żeby każdą klasę umieścić jako singleton np właśnie klasa CCore, czy klasa odpowiadająca za obiekty DirectX'a, direct input czy okna. W ten sposób robię n klas powiązanych ze sobą tylko metodami, w pewnym sensie jest to bałagan...

Wygląda to tak:
bool CCore::onInit()
{
     // tworzymy okno, urządzenie directx'a

return true;
}

void CCore::onRelease()
{
     // Zwalniamy obiekty utworzone przez framework/silnik wszystkie managery zasobów, direct input itp
}

void CWindow::onMessage()
{
}

void CWindow::onChangeSize()
{
}

// aktualizacja zmiennych
void CCore::onUpdate();
{
}

// reakcje na zdarzenia od klawiatury czy myszy
void CCore::onHandleEvents();   
{
}

// rysowanie
void CCore::onDraw();
{
}

Macie jakieś swoje pomysły jak można to ładnie i sprawnie napisać ? Może powinienem stworzyć klasę która to wszystko posiadała by jako obiekty w sobie ?
Podam taki przykład w tej chwili jeżeli chciał bym przejść do trybu pełno ekranowego to musiał bym utworzyć w klasie CCore metode która wywoływała by w obiekcie klasy okna metodę zmieniająca styl oraz rozmiar okna i potem w klasie odpowiadającej za urządzenie dx'a wywołanie zmiany trybu na pełno ekranowy, tworzę takie powiązania metodowe pomiędzy klasami że w końcu sam się pogubię...

Offline Mr. Spam

  • Miłośnik przetworów mięsnych

Offline Rokuzo

  • Użytkownik
    • Masz na sprzedaż klucze do cs go?

# Wrzesień 07, 2012, 23:36:36
Ja bym to napisal nieco inaczej ^^
Klasa core to singleton posiadajcy liste rendererow.
Nim tworzymy renderery, okna, uyskujemy dostep do menadzera zasobow inputu itd.
Kazdy renderer operuje na wskazniku na scene, ktora miesci listy obiektow do wyswiet.
przez renderer. Renderer ponadto posiada dostep do zasobow.

Offline Krzysiek K.

  • Redaktor
    • DevKK.net

  • +1
# Wrzesień 07, 2012, 23:42:33
Cytuj
Ja bym to napisal nieco inaczej ^^
Klasa core to singleton posiadajcy liste rendererow.
Nim tworzymy renderery, okna, uyskujemy dostep do menadzera zasobow inputu itd.
Kazdy renderer operuje na wskazniku na scene, ktora miesci listy obiektow do wyswiet.
przez renderer. Renderer ponadto posiada dostep do zasobow.
Twój Jak prosi o swoje włosy spowrotem. ;)


Przede wszystkim framework jest po to, żeby maksymalnie upraszczał resztę pisania. U mnie wygląda to tak, że pozwalam tworzyć obiekty globalne, które same się rejestrują.

Offline Veldrin

  • Użytkownik

# Wrzesień 08, 2012, 02:36:35
Jeżeli coś jest proste w użyciu + działa + proste w wykorzystaniu + proste w rozwinięciu + proste w testowaniu = dobre.

Tyle.

A jak to zrobisz - to już właśnie wyróżnia Cię jako programistę wśród tłumu "programistów"(co to pisać fory i ify potrafią, a semafora definicji nie znają...)

Offline PoD

  • Użytkownik

# Wrzesień 08, 2012, 03:31:40
Ja tam radzę, żebyś zapisał sobie na kartce główne założenia i zaznaczył te najważniejsze. Pisząc wszystko staraj się patrzeć, jak to będzie wyglądało od strony użytkowej.

Ja pisząc swojego frameworka założyłem, że przede wszystkim zależy mi na tym, abym mógł góra w trzech linijkach odpalić cały system, a reszta to dodatkowa funkcjonalność. Stwierdziłem, że nie potrzeba mi renderowania w wielu oknach, więc sprawę olałem. Zamiast tego zająłem się pisaniem ważniejszych rzeczy, takich jak zarządzanie stanami programu.

Offline komorra

  • Użytkownik
    • Blog naszego teamu (o grze Voxelfield)

# Wrzesień 08, 2012, 07:03:08
Możesz też podpatrzeć jak to wygląda u innych: Unity -> http://teotigraphix.com/taxonomy/term/40
 poczytać sobie dokumentację innych silniczków.

Offline Avaj

  • Użytkownik

# Wrzesień 08, 2012, 09:18:38
Możesz też podpatrzeć jak to wygląda u innych: Unity -> http://teotigraphix.com/taxonomy/term/40
 poczytać sobie dokumentację innych silniczków.
to akurat kiepski link bo najciekawsze rzeczy są w klasie MonoBehaviour, która nie jest rozwinięta na obrazku :)

Offline PsichiX (ΨΧΞ)

  • Użytkownik
    • PsichiX Website

# Wrzesień 08, 2012, 14:25:08
jak chcesz zobaczyć jak wygląda framework od kodu to looknij na to: subversion.assembla.com/svn/xenon-core-2/trunk/XenonFramework2/XenonFramework2/
główna część znajduje się bodajże w klasie Manager, ale śledząc main.cpp zobaczysz całą strukturę kodu.

Offline LizarD

  • Użytkownik

# Wrzesień 12, 2012, 12:21:15
Co do kartki, i tego co potrzebuję, fundamentami to ja nazywam klasy podstawowe bez których cały framework by nie istniał jest to klasa odpowiadająca za grafikę, okno, directinput są to podstawowe rzeczy, dalej z czasem chciał bym rozbudować cały framework, chodzi o to że dodam zarządzanie zasobami , mapę wysokości (teren) w pewnym sensie zacznie przypominać silnik ale chcę zacząć to pisać tak że ułatwi mi to bawienie się różnymi efektami np chcę dodać coś tam żeby zobaczyć jak to będzie wyglądało z tym i z tym... Co do całego użytkowania to nie mam zamiar zakładać firmy czy sprzedawać tego tylko ma być tylko i wyłącznie na mój własny użytek. Ale trzeba to jakoś zacząć, więc zaczynając od fundamentów to mam klasy:

-> Window

create
release

setBasicStyle
setExtendedStyle

onMessage
onChangeSize
onMove
onActivce
onInActive


-> Directx

create
release

getDevice

-> DirectInput

create
release

cilckMouseButton <- w argumencie przekazuje się numer przycisku, i zwraca się true albo false
clickKey <- w argumencie przekazuje się numer klawisza, i zwraca się true albo false.


Dla przykładu, użytkownik zmieni rozmiar okna no to trzeba odświeżyć urządzenie żeby dopasować rozmiar backbuffera czyli odświeżyć klasy frameworka ale użytkownik czyli ja może zechcieć wywołać też jakieś metody w czasie tego zdarzenia czyli trzeba jakoś to połączyć, i od tego miałem klasę Core:

->Core

init <- użytkownik tworzy okno i urządzenie
release <- wywołuje się zaraz przed zamknięciem programu

onMessage
onChangeSize
onMove
onActivce
onInActive

W tych klasach zarządza się frameworkiem a wywołuje się je tak

void Window::onChangeSize()
{
      Core.onChangeSize();
      // użytkownik robi co chce
}

Tutaj znowu założyłem że wszystko jest singletonem w pewnym sensie jest to dobre ale robi to też taki bałagan ponieważ do klas podstawowych trzeba zaliczyć też szablon klasy singletona

Edit:
A jeszcze klasy odpowiedzialne za rysowanie odświeżanie zmiennych, kiedyś może będę miał ochotę przed efektem napisać sobie jakieś menu to dochodzi zarządzanie stanami nie jest to jakiś duży kawałek kodu więc można go dopisać czyli metoda powinna wyglądać tak:

void Window::onChangeSize()
{
      Core.onChangeSize();
      StateManager.getActiveState()->onChangeSize();
}

void SimpleState::onChangeSize()
{
     // użytkownik robi co chce
}

Nie wiem czy ładną rzeczą jest nie przekazywanie do klasy rysującej referencji do klasy DirectX tylko korzystanie w jej ciele z singletona. Tak samo klasa zarządzająca zasobami w pewnym sensie to też uznaje do fundamentów

Edit2:
Przeraża mnie sytuacja typu Klasa Winow wywołuje metody klasy Core, a klasa Core wywołuje metody klasy Window ponieważ te klasy są singletonami, to jest normalne ?
« Ostatnia zmiana: Wrzesień 12, 2012, 12:52:10 wysłana przez LizarD »

Offline Paweł

  • Użytkownik

# Wrzesień 13, 2012, 02:09:18
Przede wszystkim framework jest po to, żeby maksymalnie upraszczał resztę pisania. U mnie wygląda to tak, że pozwalam tworzyć obiekty globalne, które same się rejestrują.
Z ciekawości: jak ustalasz kolejność inicjalizacji?