Autor Wątek: [c++] Co lepsze? Menedżer, interfejs czy kilka obiektów tego samego typu?  (Przeczytany 10784 razy)

Offline Xenox93

  • Użytkownik

# Marzec 20, 2014, 11:45:11
Witam

Cały czas mam problem z odpowiednim zaprojektowaniem kodu, gdy już wszystko mi działa i kod osiąga duże rozmiary, każda próba dodania czegoś nowego kończy się fiaskiem i zmusza mnie do zmiany struktury kodu/innego podejścia do projektowania :/ Dlatego chciałbym się dowiedzieć, jak to się robi profesjonalnie i uniwersalnie.

1. Załóżmy, że mam klasę Window. Wiadomo, że musi posiadać takie opcje jak Create, Destroy, Resize itp. Wcześniej do problemu podchodziłem jak początkujący( przynajmniej mi się tak wydaje ). Otóż aby utworzyć nowe okno, tworzyłem kilka obiektów tej samej klasy:
Window window1, window2, ... ;
1.1. Wszystko było ładnie pięknie, ale problem pojawiał się jak chciałem dodać coś nowego. Na dodatek dowiedziałem się o czymś takim jak Manager. Więc nie zwlekając poczytałem co nieco o tym i szczerze powiedziawszy zaciekawiło mnie to. Utworzyłem strukturę opisującą każde okno( tytuł, rozmiar, FullScreen/Windowed( tryb wyświetlenia okna ) oraz co najważniejsze uchwyt każdego okna )

Tylko, że wydaje mi się że o ile oszczędzamy na pamięci, to nie koniecznie na czasie procesora i nie mam na myśli mikro optymalizacji. Otóż moja konstrukcja Menedżera Okna wyglądała mniej więcej tak:
struct WindowParam
{
string title;

     struct Resolution
     {
         unsigned short width, height;
     } resolution;

     enum DisplayModeWindow
     {
         fullscreen,
         windowed
     } displayModeWindow;

Handle handle; // Uchwyt okna
};
class WindowManager
{
private:
vector< WindowParam > windowParam;

public:
WindowManager() {  }
WindowManager( const WindowManager &windowManager ) { ... }
WindowManager( WindowParam &wndParam ) { ... }

bool Create( WindowParam &wndParam  ) { ... }
void Destroy( string title ) { ...  }

void Resize( unsigned short width,  unsigned short  height ) { ... }

vector< WindowParam > &Get() { return windowParam; }
WindowParam &Get( string title ) { ... }
};

Jak można zauważyć, jako ułatwienie stosuję pobieranie pojedyńczego/danego/konkretnego okna za pomocą tytułu. Teraz pytanie czy to jest dość wydajne? Bo muszę przelecieć przez pętle vector'a w poszukiwaniu konkretnego okna. Ofc, że mógłbym podać konkretny numer ID/index, ale ta koncepcja wydaje mi się być archaiczna, gdyż mając kilka okien, muszę wiedzieć/pamiętać, który index należy do którego okna.

1.2. Ale poszedłem o krok dalej i znalazłem również informację o uniwersalnym interfejsie(?), RAII(?), polimorfizmie oraz użyciu szablonów. Nawet przykładowy kod jest umieszczony tu, na stronie warsztat.gd, jednym z wielu artykułów, poruszających kwestię zasobów, co przydaje się przy pisaniu framework'a. Dzięki temu nie jestem zmuszony pisać za każdym razem tego samego kodu jak chcę rozpocząć nowy projekt lub tak jak w moim przypadku, jak muszę ciągle zmieniać składnię kodu :/
Otóż kod Manager'a umieszczony w artykule wyglądał mniej więcej w ten sposób:
template< typename TypeOfStructure > class Manager
{
        private:
TypeOfStructure structure;

public:
Manager() {  }
Manager( const Manager &manager) { ... }
Manager( TypeOfStructure &str ) { ... }

virtual bool Add( TypeOfStructure &str  ) { ... }
virtual void Remove() { ...  }

                virtual TypeOfStructure &Get() { return structure; }

};

struct WindowParam
{
string title;

     struct Resolution
     {
         unsigned short width, height;
     } resolution;

     enum DisplayModeWindow
     {
         fullscreen,
         windowed
     } displayModeWindow;

Handle handle; // Uchwyt okna
};

class WindowManager : public Manager< WindowParam  >
{
public:
WindowManager() : Manager< WindowParam  >()  {  }
WindowManager( const WindowManager &windowManager ) : Manager< WindowParam  >( windowManager ) { ... }
WindowManager( WindowParam &wndParam ) : Manager< WindowParam  >(  ) { ... }

bool Create( WindowParam &wndParam  ) { Add( ... ); }
void Destroy( string title ) { Remove( title ); }

void Resize( unsigned short width,  unsigned short  height ) { ... }

WindowParam &Get( string title ) { return Get(); }

        private:
                bool Add( WindowParam &str  ) { ... }
void Remove( string title ) { ...  }
};

1.3. Czy powyższa konstrukcja nie wydaje się naciągana i niepotrzebnie dzielona na klasy i dziedziczona? Bo wygląda mi to na wciskanie na siłę polimorfizmu, gdzie się tylko da :/ Dodatkowo problem powstaje, gdy jako typ struktury Manager'a, przekaże kontener STL :/
[...]
class WindowManager : public Manager< vector< WindowParam > >
[...]

2. Dodatkowo byłbym zainteresowany ( o ile nie naruszam regulaminu ), jak kiedyś się pisało obsługę zdarzeń, dla kontrolki, okna? Czy znowu musiałbym wrócić do początkowej koncepcji i tworzyć oddzielną klasę dla każdego nowego okna, która dziedziczyłaby po klasie nadrzędnej Window, gdzie znajdowałaby się funkcja wirtualna:
virtual void Action( ... ) { ... }
Sam już nie wiem, która koncepcja jest lepsza? Pewnie jeszcze parę pytań będę miał, ale na chwilę obecną i tak już wystarczająco pytań zadałem...

Z góry thx za pomoc ;)

Offline Mr. Spam

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

Offline Stig

  • Użytkownik

  • +1
# Marzec 20, 2014, 20:50:35

Offline Xirdus

  • Redaktor

  • +1
# Marzec 20, 2014, 21:55:24
Klasa powinna robić jedną i tylko jedną rzecz. Jeśli manager przechowuje okna, jest OK. Jeśli manager wykonuje operacje na tych oknach niezwiązane z samą funkcją przechowywania (np. resize), nie jest OK.

Przedwczesna optymalizacja jest źródłem wszelkiego zła. Nie myśl o wydajności póki masz więcej niż 60FPS. W ogóle.

Wykorzystywanie kodu ze starych projektów w nowych to niemalże mit. Jeśli nie robisz stricte biblioteki, gdzie głównym założeniem jest właśnie możliwość wykorzystania w wielu projektach, to niemal nigdy ci się to nie uda. A nie napiszesz żadnej sensownej biblioteki jeśli nie ukończyłeś wcześniej żadnej gry.

Abstrakcja nie zawsze jest fajna. Rób tylko tyle abstrakcji, ile ci potrzeba. Nie bój się, że później może zajść możliwość napisania czegoś od nowa, bo dałeś za mało abstrakcji - jest miliard innych powodów, przez które może zajść możliwość przepisania pewnej części od zera, niezależnie od użytych abstrakcji. Manager mogący przyjąć różne rodzaje kontenerów to jest za duży poziom abstrakcji - najprawdopodobniej na zawsze zostaniesz przy wektorze. Szablonowy manager na różne rodzaje obiektów też nie zawsze musi się sprawdzić - przemyśl to jeszcze raz.



Co do ostatniego problemu: współcześnie stosuje się do tego callbacki - zmienne przechowujące funkcje, które potem są wywoływane. Zaletą jest, że jedna klasa może mieć dziesiątki tysięcy różnych zachowań (patrz: przycisk).

Offline Xenox93

  • Użytkownik

# Marzec 20, 2014, 23:03:23
1.
Cytuj
Klasa powinna robić jedną i tylko jedną rzecz. Jeśli manager przechowuje okna, jest OK. Jeśli manager wykonuje operacje na tych oknach niezwiązane z samą funkcją przechowywania (np. resize), nie jest OK.

Zrozumiałem to tak, że Manager tylko przechowuje zmienną i posiada co najwyżej metody, które pozwalają na dodanie, usunięcie, ustawienie i pobranie zmiennej( hermetyzacja danych ). Później mam utworzyć klasę Window lub jakąś inną( np. Texture ), która powinna dziedziczyć Manager przechowujący okna. Natomiast co do samej klasy Window, to ona powinna operować na oknach, np. zmienić rozmiar, utworzyć okno itp.? Czy dobrze zrozumiałem? Może nadal myślę zbyt abstrakcyjnie i zbytnio wybiegam poza ramy?

Reasumując, klasa Window -> operacje na oknach( np. Resize ); klasa Manager -> przechowuje okna( np. vector, Add, Remove, Get, Set ). Czy powinno to wyglądać w ten sposób? ;) Jeśli tak, to czy opłaca się lub powinno się ustawiać metody Manager'a wirtualnymi? Pewnie znowu abstrakcja, ale czasami warto zmienić deklarację metody. Po głębszym zastanowieniu, jaki sens ma stosowanie Manager'a? Czy nie lepiej w jednej klasie zadeklarować jedną zmienną vector oraz metody, które pozwolą na utworzenie okna, usunięcie, pobranie, zmianę rozmiaru itp. ?

2.
Mam w planach napisać Framework, za pomocą, którego będę mógł utworzyć okno, dodać kontrolki, ogólnie rzecz biorąc napisać program z użyciem okienek, jednocześnie na Windows'a i Linux'a, tak aby nie pisać za każdym razem od nowa kodu, który robi to samo w każdym projekcie ;) Na razie nie planuję wybiegać zbytnio do przodu, więc na początku piszę kod tylko na Windows'a. Ciężko to nazwać jakimś profesjonalnym framework'em, ale dla celów osobistych i dydaktycznych, wydaje mi się że warto. Choćby jako szybsze napisanie prostego programu i pochwalenie się przed znajomymi, rodziną lub w portfolio ;)

3.
Cytuj
Co do ostatniego problemu: współcześnie stosuje się do tego callbacki [...]

Hmm, coś o tym słyszałem. Tylko nie rozumiem za bardzo co miałeś na myśli pisząc: "zmienne przechowujące funkcje". Czyżby chodziło Ci o wskaźniki do funkcji, czy same funkcje? Tylko jest jedno ale... Ja nigdy nie pisałem funkcji z użyciem wskaźników jak i w postaci zmiennych :/

4.
Cytuj
Przedwczesna optymalizacja jest źródłem wszelkiego zła. Nie myśl o wydajności póki masz więcej niż 60FPS. W ogóle.

Tym akurat się nie przejmuję, ale trochę podejrzanie wyglądał sposób szukania oraz operowania, np. na konkretnym oknie. Bo jednak iterowanie kontenera STL i porównywanie nazw coś kosztuje, ale to właściwie sprawa drugorzędna ;)

PS. Każda pomoc, jest na wagę złota. W przeszłości dużo rzeczy poznałem za pomocą tego forum i do dziś stosuję wiedzę, która na prawdę ułatwia programowanie ;)

Offline Xirdus

  • Redaktor

  • +1
# Marzec 20, 2014, 23:45:28
Pamiętaj, że dziedziczenie jest najsilniejszym związkiem między klasami, a im silniejsze związki, tym trudniej refaktoryzować kod. Dlatego dziedziczenia powinno się używać najrzadziej jak się da - staraj się w ogóle (przynajmniej do czasu, kiedy będziesz już sam wiedział, kiedy jest dobre).

2.
Mam w planach napisać Framework, za pomocą, którego będę mógł utworzyć okno, dodać kontrolki, ogólnie rzecz biorąc napisać program z użyciem okienek, jednocześnie na Windows'a i Linux'a, tak aby nie pisać za każdym razem od nowa kodu, który robi to samo w każdym projekcie ;) Na razie nie planuję wybiegać zbytnio do przodu, więc na początku piszę kod tylko na Windows'a. Ciężko to nazwać jakimś profesjonalnym framework'em, ale dla celów osobistych i dydaktycznych, wydaje mi się że warto. Choćby jako szybsze napisanie prostego programu i pochwalenie się przed znajomymi, rodziną lub w portfolio ;)
Po co, kiedy jest Qt/GTK/wxWidgets/wiele wiele innych?

3.
Hmm, coś o tym słyszałem. Tylko nie rozumiem za bardzo co miałeś na myśli pisząc: "zmienne przechowujące funkcje". Czyżby chodziło Ci o wskaźniki do funkcji, czy same funkcje? Tylko jest jedno ale... Ja nigdy nie pisałem funkcji z użyciem wskaźników jak i w postaci zmiennych :/
Krok 1: jeśli jeszcze tego nie zrobiłeś, włącz w swoim kompilatorze C++11.
Krok 2: poczytaj sobie o std::function oraz std::bind.
Krok 3: ???
Krok 4: profit.

std::function to w dużym uproszczeniu zmienna trzymająca funkcję - to znaczy przypisujesz jej funkcję i możesz potem wywołać nawiasami tą zmienną, i wywoła ci się funkcja która pod tą zmienną siedzi. std::function możesz kopiować, możesz przekazywać w argumencie do innej funkcji, możesz trzymać w kontenerze, możesz robić wszystko co byś normalnie robił ze zmienną. Dodatkowo przez std::bind możesz na stałe przyczepić do funkcji w std::function argumenty do wywołania - i będzie to niewidoczne dla użytkownika tej funkcji.

4.
Tym akurat się nie przejmuję, ale trochę podejrzanie wyglądał sposób szukania oraz operowania, np. na konkretnym oknie. Bo jednak iterowanie kontenera STL i porównywanie nazw coś kosztuje, ale to właściwie sprawa drugorzędna ;)
Iterowanie po kontenerze STL jest na tyle szybkie, żeby nie martwić się o to póki FPS nie spadnie poniżej 60. Jednakże, przyznam że przeoczyłem fakt że wyszukujesz po nazwie - a jest on tutaj kluczowy, i sprawia że std::vector niezupełnie się tu nadaje. W tym przypadku o wiele lepszym rozwiązaniem będzie std::map. Jest to kontener, który indeksuje elementy podobnie jak tablica, ale nie tylko intem - możesz to robić dowolnym typem, i niekoniecznie musisz zaczynać od zera ani mieć wszystkie elementy pomiędzy. W twoim konkretnym przypadku powinieneś użyć std::map<std::string, Window>.

Offline Xender

  • Użytkownik

  • +1
# Marzec 21, 2014, 08:40:10
^ s/map/unordered_map/g

map operuje na drzewie, co AFAIK łatwo rozwala cache coherency.
unordered_map to stara dobra hashmapa.

Offline Xenox93

  • Użytkownik

# Marzec 21, 2014, 11:38:04
1.
Ok, w takim razie nie mam tworzyć szablonów( na chwilę obecną ), a Manager pisać oddzielnie do każdego, czyli ogólnie rzecz mówiąc: utworzyć klasę, np. Window, z wszystkimi możliwymi metoda, które określają dany obiekt, tak? Tak samo z klasą Texture, Shader, Scene itp.? Czy jednak warto utworzyć oddzielną klasę Manager, ale powyższe klasy nie mają dziedziczyć, a jedynie deklarować zmienną o typie manager'a:
struct TextureParams
{
       [...]
};

class Texture
{
      private:
            Manager< TextureParams > textures; <- w ten sposób

      public:
            [ Metody operujące na zasobach ]
           
            [...]
};

// Czy lepiej jednak nie tworzyć żadnego Manager'a, a właściwie utworzyć klasę, np. Texture, która sama
// będzie operowała na danych?

class Texture
{
      private:
            map< string, TextureMap > textures;

      public:
            bool Add( ... );
            void Remove( ... );

            map< string, TextureMap > &GetTexture() { ... }

            itd.
            [ ... ]
}

Czym różnią się powyższe klasy? Na pewno tym, że ta pierwsza korzysta z Manager'a, który nie jest dziedziczony, natomiast ta druga, sama operuje na danych( btw. ta klasa wygląda tak samo jak manager )

2.
Cytuj
Po co, kiedy jest Qt/GTK/wxWidgets/wiele wiele innych?

Na pewno masz rację, ale jedyny powód dla którego nie korzystam z tych bibliotek to wydajność. wxWidget był łatwy do tworzenia okien, kontrolek, ale już połączenie go z OpenGL nie było takie proste.

Natomiast wolę pisać w tak archaicznym API jakim jest WinAPI, gdyż wydajność jaką tam osiągam jest ogromna. Więcej mogę poszaleć, niż się ograniczać i włączać później profiler, a tym samym wyrywać włosy z głowy, zastanawiając się, która funkcja/część kodu spowalnia program, oczywiście patrząc na funkcje tworzące okno ze zgryzem, które zachłannie zabierają czas.

Jeszcze kiedyś korzystałem z GLFW/GLFW3, ale okazało się że jest mocno ograniczony... Nie mamy wyboru, której karty graficznej chcemy użyć. Nie ma pobrania możliwych opcji rozdzielczości i innych ustawień. Dodatkowo szukałem kodu, który pozwoliłby mi włączyć/wyłączyć Vsync, ale niestety, nie działał.

Reasumując, planuję napisać Framework, który będzie korzystał z natywnego API dostępnego przez dany system. Dzięki temu będę mógł tworzyć okna w zależności od tego czego będę chciał w danej chwili użyć oraz wszystko będzie działało wydajnie. Dodatkowo, w przyszłości planuję zabrać się za framework graficzny, jakieś podstawowe klasy, które zawsze robią to samo, a nie potrzebnie, za każdym razem piszę ten fragment, zamiast skupić się na czymś nowym.

3.
A no tak, przecież nie raz widziałem te funkcje( std::function i std::bind ), ale nigdy nie myślałem, że one są wykorzystywane w tym celu. Dzięki, jak będę pisał callback'i to zabiorę się za poznawanie tych funkcji.

4.
Hmm... no tak, że też na to nie wpadłem. Ale tak jak napisał to Xender, że map jest drzewem, czyli jego wydajność zależy od rozmiaru drzewo/wysokości. Trochę mało wydajny sposób :/
Ale ok, zrobię tak jak mówicie, bo szczerze powiedziawszy, ten kontener STL dużo by mi ułatwił.

PS. Już wiem dlaczego nie użyłem map, bo szukałem okna o danym tytule, a nie nazwie. W skład struktury opisującej dane okno wchodzi tytuł, tak więc za jego pomocą szukam konkretnego obiektu. Tylko pytanie czy wtedy zrezygnować z vector'a( gdyż tak i tak szukam obiektu o konkretnym tytule okna ) na rzecz map?

Offline Xirdus

  • Redaktor

  • +1
# Marzec 21, 2014, 11:49:50
^ s/map/unordered_map/g

map operuje na drzewie, co AFAIK łatwo rozwala cache coherency.
unordered_map to stara dobra hashmapa.
No wiem, ale jak by nie patrzeć, interfejs obu jest bardzo podobny, a o std::map jest więcej tutoriali. Tak więc na czas nauki std::map, a kiedy ogarnie to zmiana na std::unordered_map - bo to jest po prostu niskopoziomowa optymalizacja. Ważna optymalizacja, ale wciąż tylko optymalizacja, i bez niej wszystko będzie działało dobrze.

1.
Ok, w takim razie nie mam tworzyć szablonów( na chwilę obecną ), a Manager pisać oddzielnie do każdego, czyli ogólnie rzecz mówiąc: utworzyć klasę, np. Window, z wszystkimi możliwymi metoda, które określają dany obiekt, tak? Tak samo z klasą Texture, Shader, Scene itp.? Czy jednak warto utworzyć oddzielną klasę Manager, ale powyższe klasy nie mają dziedziczyć, a jedynie deklarować zmienną o typie manager'a:
Po pierwsze: jaki jest logiczny sens żeby zasoby miały w sobie managera tych zasobów? Czy w środku rury siedzi hydraulik?

Na pewno masz rację, ale jedyny powód dla którego nie korzystam z tych bibliotek to wydajność.
Z obecnym poziomem wiedzy nigdy ci się to nie uda. Nad tamtymi bibliotekami siedziało dziesiątki ludzi, kazdy z nich mial wiele lat doswiadczenia w programowaniu i spedzil nad biblioteka tysiace roboczogodzin. Myslisz, ze potrafisz napisac GUI lepiej od nich wszystkich?

4.
Hmm... no tak, że też na to nie wpadłem. Ale tak jak napisał to Xender, że map jest drzewem, czyli jego wydajność zależy od rozmiaru drzewo/wysokości. Trochę mało wydajny sposób :/
Iterowanie po calym kontenerze jest jeszcze mniej wydajne. Ale tu nie chodzi o wydajnosc, tylko semantyke - jesli przypisujesz obiekt do stringa, to uzywaj kontenera, ktory przypisuje obiekty do stringow.

PS. Już wiem dlaczego nie użyłem map, bo szukałem okna o danym tytule, a nie nazwie. W skład struktury opisującej dane okno wchodzi tytuł, tak więc za jego pomocą szukam konkretnego obiektu.
Jesli rzecza, ktora pozwala ci odroznic od siebie poszczegolne okna jest napis na ich gornej belce, robisz to zle. Nazwa okna widoczna przez uzytkownika i nazwa okna uzywana przy wyszukiwaniu powinny byc od siebie niezalezne - bo co, jesli zechcesz zmienic nazwe okna?
« Ostatnia zmiana: Marzec 21, 2014, 11:51:38 wysłana przez Xirdus »

Offline wozix

  • Użytkownik

  • +1
# Marzec 21, 2014, 17:51:17
Co do wszelakiej maści Managerów

http://objology.blogspot.com/2011/09/one-of-best-bits-of-programming-advice.html
Nie rozumiem. Przecież zmiana nazwy nie zmienia problemu :o

Offline Xirdus

  • Redaktor

  • +1
# Marzec 21, 2014, 18:01:02
Nie rozumiem. Przecież zmiana nazwy nie zmienia problemu :o
Zmiana nazwy implikuje dostosowanie klasy do tego, co mówi nowa nazwa.

Offline yarpen

  • Użytkownik

  • +1
# Marzec 21, 2014, 20:57:31
4.
Hmm... no tak, że też na to nie wpadłem. Ale tak jak napisał to Xender, że map jest drzewem, czyli jego wydajność zależy od rozmiaru drzewo/wysokości. Trochę mało wydajny sposób :/
Ale ok, zrobię tak jak mówicie, bo szczerze powiedziawszy, ten kontener STL dużo by mi ułatwił.
map jest drzewem czerwono czarnym, wiec zawsze bedzie b. dobrze zbalansowane i masz konkretne gwarancje na maksymalna wysokosc.

Offline Xender

  • Użytkownik

  • +1
# Marzec 22, 2014, 21:27:00
^ Ale nadal AFAIK hashmapa będzie lepsza tam, gdzie nie jest potrzebna kolejność elementów wg. klucza przy przechodzeniu po całym kontenerze. Oczywiście w miarę możliwości najlepiej w ogóle unikać iterowania po kontenerach asocjacyjnych.

No wiem, ale jak by nie patrzeć, interfejs obu jest bardzo podobny, a o std::map jest więcej tutoriali. Tak więc na czas nauki std::map, a kiedy ogarnie to zmiana na std::unordered_map - bo to jest po prostu niskopoziomowa optymalizacja. Ważna optymalizacja, ale wciąż tylko optymalizacja, i bez niej wszystko będzie działało dobrze.
Ale skoro interfejs jest podobny, to czemu nie zrobić tego dobrze od razu?
A w razie problemów z dopasowaniem kodu z tutoriala do zwykłego map - http://en.cppreference.com/w/cpp/container/unordered_map i jedziemy. Programowanie to też sztuka dopasowywania istniejącego kodu do nowych warunków, na copy-paste nie zajedzie się daleko. ;)

Offline Xirdus

  • Redaktor

  • +1
# Marzec 22, 2014, 22:31:52
Ale skoro interfejs jest podobny, to czemu nie zrobić tego dobrze od razu?
Googlnij sobie std::map a potem std::unordered_map - jak myślisz, które wyniki są bardziej przyjazne dla kogoś, kto pierwszy raz widzi to na oczy?

Offline Xenox93

  • Użytkownik

# Marzec 23, 2014, 16:11:24
Cytuj
Po pierwsze: jaki jest logiczny sens żeby zasoby miały w sobie managera tych zasobów? Czy w środku rury siedzi hydraulik?

Hmm.. ogólnie rzecz biorąc masz rację, ale w programowaniu jest trochę inaczej. A właściwie tak samo, bo kilku specjalistów powoduje biurokrację. Tak samo w informatyce, tworzenie kilku klas w zależności od przeznaczenia( inne dla okna, inne przechowujące tekstury ), a czasami dziedziczenie jest kosztowne. Każda klasa, zmienna, dziedziczenie itp. zabiera cenny czas. Ale tak jak pisaliście już wcześniej, na razie nie mam myśleć o abstrakcji i optymalizacjach, więc nie myślę ;)

Cytuj
Z obecnym poziomem wiedzy nigdy ci się to nie uda. Nad tamtymi bibliotekami siedziało dziesiątki ludzi, kazdy z nich mial wiele lat doswiadczenia w programowaniu i spedzil nad biblioteka tysiace roboczogodzin. Myslisz, ze potrafisz napisac GUI lepiej od nich wszystkich?

Moim celem nie jest wydanie tego komercyjnie lub dla innych. Pierwszym priorytetowym celem jest napisanie tego dla siebie. Przynajmniej nauczę się jak programuje się framework'i i w przyszłości będę wiedział czy warto brać się za coś podobnego jeśli nie podołam.
No i nie warto podchodzić w ten sposób do sprawy, bo gdyby Kopernik myślałby w ten sposób, nadal byśmy wierzyli w Geocentryzm ;p
Każde studio zaczynało od kilku lub jednej osoby, czy to tu programiści piszący własny parser skryptów lub silniki. A nawet nie chcę konkurować z Qt lub wxWidget.

Cytuj
Iterowanie po calym kontenerze jest jeszcze mniej wydajne. Ale tu nie chodzi o wydajnosc, tylko semantyke - jesli przypisujesz obiekt do stringa, to uzywaj kontenera, ktory przypisuje obiekty do stringow.

Ok, przekonałeś mnie :] Więc jak teraz będę zabierał się za pisanie to zastosuję się do twoich rad.

Cytuj
Jesli rzecza, ktora pozwala ci odroznic od siebie poszczegolne okna jest napis na ich gornej belce, robisz to zle. Nazwa okna widoczna przez uzytkownika i nazwa okna uzywana przy wyszukiwaniu powinny byc od siebie niezalezne - bo co, jesli zechcesz zmienic nazwe okna?

Fakt, tego nie przewidziałem :/ Masz rację, powinna być jakaś nazwa, bo bez tego po wprowadzeniu w jednym miejscu zmian, muszę pozmieniać wszystko.

Ogólnie jak wrócę do domu, to zabiorę się za pisanie szkieletu framework'a okna i stwierdzicie czy to powinno wyglądać w ten sposób. Może ktoś ma jeszcze jakieś propozycje zaprojektowania kodu, bo szczerze to cały czas po głowie chodzi utworzenie klasy Window, która dziedziczy Manager lub w klasie window zadeklarować obiekt/zmienną klasy Manager.

Offline ArekBal

  • Użytkownik

  • +1
# Marzec 23, 2014, 19:34:21
Po dziada ci ten manager?
Co on ma robić wg. ciebie.

Moim zdaniem tworzysz problem nie rozwiązując żadnego chcąc zastosować coś takiego...