Autor Wątek: Banalny, niebanalny problem z organizacją folderów.  (Przeczytany 1877 razy)

Offline MrKaktus

  • Użytkownik

# Luty 19, 2011, 17:31:58
Hej,

Mam taki banalny problem. Za każdym razem gdy kończe jeden projekt, a zaczynam następny, okazuje się że nie tak łatwo jest przywrócić silnik do "czystej" formy. Mam tutaj na mysli wydzielenie gotowego już projektu od Solution silnika tak aby nadal się on kompilował a sam silnik mógł być użyty do nowego projektu. Nie chodzi o to że kod projektu "zlał sie" z kodem silnika ponieważ mam osobne Projekty Visuala dla kazdego z nich, ale okazuje sie ze sa problemy z zaleznosciami, sciezkami etc.

Co robilem do tej pory:
Patrzalem zniechęcony na folder z zawartoscia i czulem ze proces "rozdzielenia" bedzie rownie meczacy co przy operacji rozdzielenia blizniat syjamskich. Tworzylem wiec sobie nowy folder, i nowe solution silnika po czym kopiowalem jego kod ze starego i rozpoczynalem prace nad nowym projektem.

Co chcialbym zmienic:
O ile jest to ewolucyjne podejscie do sprawy, o tyle chcialbym miec wszystko jakos sensownie przygotowane w jednym miejscu zeby zaoszczedzic sobie roboty. W zwiazku z tym potrzebuje folderu glownego w ktorym bede mial podfoldery z kolejnymi grami i podfoldery z kolejnymi wersjami silnika. Dodatkowo niezbedne jest aby wszystkie wersje silnika + foldery z ich rilisami (czyli liby+hedery) byly w jednym SVN'ie a kazdy z projektow gier + odpowiadajacy mu folder z rilisem danego engina byl w osobnym SVN'ie. Kazda gra miala by teraz osobne solution w ktorym bylby tylko projekt gry i sciezki do folderu z daym rilisem enginu. Wszystkie wersje enginu bylyby w osobnym Solution jako osobne projekty.

Pytanie czy jest mozliwosc wersjonowania tego samego folderu w dwóch repozytoriach tak aby jedno moglo tylko z niego czytac a drugie mial dostep R/W ?

Jak powinna wygladac taka struktura folderow waszym zdaniem ?

Dzieki,
Kaktus

Offline Mr. Spam

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

Offline Oti

  • Użytkownik

# Luty 19, 2011, 17:42:47
Moim zdaniem źle zabierasz się za pisanie silnika. Silnik, to tak jakby podwalina pod grę. Piszesz silnik, dodajesz tam jakieś ficzery(GUI, wypaśny renderer etc.), aż w końcu będziesz miał to co chcesz i zaczynasz pisać grę. Gra używa silnika, ale silnik zupełnie nic nie wie o tej grze. :P Do kodu silnika nie dopisujesz funkcjonalności stricte związanych z grą, którą aktualnie na nim piszesz, to nie będzie problemu z kompatybilnością(chyba, że w którymś momencie stwierdzisz, że cośtam w tym silniku trzeba zaprojektować inaczej i napisać od nowa, no ale to chyba oczywiste).

Offline MrKaktus

  • Użytkownik

# Luty 19, 2011, 17:47:50
Nie zrozumiales o co mi chodzi. Od strony projektu visualowego i kodu engine jest calkowicie osobny a gra korzysta tylko z jego hederow i libow w swoim projekcie visualowym. Problem w tym ze projekt gry tworzylem w Solution enginu i teraz jest problem zeby to jakos wydzielic. Poza tym chcialbym miec silnik i jego solution na jednym SVN a kazdy projekt gry i jej solution na osobnym SVN. Problem pojawia sie w przypadku folderu w do ktorego engine wrzuca swoje lib'y (i przechowuje hedery) a z ktorego dane projekty gier czerpia aby sie wybildowac. Folder ten jest szerowany wiec powinien wystepowac tez w obu repozytoriach jakos ;/.

Offline Dab

  • Redaktor
    • blog

# Luty 19, 2011, 17:49:23
Git udostępnia taką możliwość (submodules). Ew. zrobić to najprościej:

/xxx/engine -- repo z engine
/xxx/gameA -- repo z grą A
/xxx/gameB -- repo z grą B

Solution/makefile oczywiście w gameA i gameB.

Offline MrKaktus

  • Użytkownik

# Luty 19, 2011, 17:58:29
no tak ale jest jeszcze folder:

/xxx/common/ <- tu jest engine lib+h po wybildowaniu go z targetem: Distribute i stad gameA i gameB zasysaja last engine release ?

Offline Reg

  • Administrator
    • Adam Sawicki - Home Page

# Luty 19, 2011, 18:49:53
Z tymi ścieżkami to zawsze są problemy... Moje pierwsze pomysły:

Używać jakiegoś DCVS np. Git, zamiast SVN. Może to uprościłoby problem z systemem kontroli wersji?

1. Kopiować cały silnik do solucji każdej gry, a w razie potrzeby co jakiś czas robić merge wprowadzonych zmian?
2. Podejście z drugiego krańca: silnik mieć w zupełnie osobnej solucji, a ścieżki do jego nagłówków i LIB-ów mieć wpisane do konfiguracji Visual C++ tak jak do innych bibliotek typu DirectX SDK.
3. Ewentualnie podejście pośrednie: do solucji każdej gry dodawać projekt silnika - leżący w jednej kopii ale gdzieś w osobnym katalogu - przez Add Existing Project.

Opcja 1 ma tą zaletę, że pisząc grę możesz swobodnie modyfikować silnik, a potem będziesz się martwił jak te zmiany wpłyną na inne korzystające z niego projekty.

U mnie w pracy jest tak, że projekty wspólnych bibliotek leżą w osobnych katalogach repozytorium SVN, ale są dołączone do każdej solucji przez svn:external. Kopia robocza repozytorium danej solucji ma więc kopię tych bibliotek, ale Commit jakichkolwiek zmian będzie widoczny po Update w kodzie biblioteki w każdej innej solucji.

Takie podejście skłania z kolei do przemyślanych zmian w bibliotece, jasnego oddzielania kodu biblioteki od kodu programu i zachowywania wstecznej kompatybilności. Na przykład kiedy dodaję do funkcji parametr, wtedy muszę mu wprowadzić wartość domyślną, bo inne projekty tego parametru nie podają i przestałyby się kompilować.

Offline MrKaktus

  • Użytkownik

# Luty 20, 2011, 22:26:06
Ok, myslalem nad tym i dumalem i ostatecznie doszedlem do takiego rozwiazania ktore mnie satysfakcjonuje. Moze sie to komus przyda na wzor:


SVN Engine (for engine developer use only):


/Engine/trunk/...
/Engine/trunk/Ngine3/...
/Engine/trunk/Ngine4/documentation/ <- engine documentation
/Engine/trunk/Ngine4/resources/     <- engine resources
/Engine/trunk/Ngine4/tools/         <- engine tools
/Engine/trunk/Ngine4/middleware/    <- headers and lib's of external
                                       libraries used by engine
/Engine/trunk/Ngine4/include/       <- engine include files
/Engine/trunk/Ngine4/src/           <- engine source code
/Engine/trunk/Ngine4/Debug/         <- engine debug build
/Engine/trunk/Ngine4/Release/       <- engine release build
/Engine/trunk/Ngine4/               <- engine solution and projects config files


SVN Engine SDK (for engine developer Read/Write, for SDK users Read):


/Engine SDK/trunk/...
/Engine SDK/trunk/Ngine4/documentation/                       <- release engine documentation
/Engine SDK/trunk/Ngine4/common/                              <- common libraries and headers used by samples
/Engine SDK/trunk/Ngine4/engine/                              <- official engine distribution libraries and headers
/Engine SDK/trunk/Ngine4/samples/Sample 1 HelloWorld/include/ <- example sample include files
/Engine SDK/trunk/Ngine4/samples/Sample 1 HelloWorld/src/     <- example sample source files
/Engine SDK/trunk/Ngine4/samples/Sample 1 HelloWorld/         <- example sample folder with its project
/Engine SDK/trunk/Ngine4/samples/                             <- solution and samples projects config files


Eeach engine from Engine SVN has "Distribution" configuration which compiles it and saves resulting lib files together with header files into corresponding folder in Engine SDK SVN. Example:

/Engine/trunk/Ngine4/include/...
/Engine/trunk/Ngine4/Debug/Ngine4dbg.lib
/Engine/trunk/Ngine4/Release/Ngine4.lib

will be copied to:

/Engine SDK/trunk/Ngine4/engine/include/..
/Engine SDK/trunk/Ngine4/engine/lib/Ngine4dbg.lib
/Engine SDK/trunk/Ngine4/engine/lib/Ngine4.lib

And these folders will be used by any app using this version of engine after downloading latest version of Engine SDK from SVN. Therefore any application can be made in any location using any Engine version without breaking old ones and Engine solution itseld. Game needs to have its own Solution and SVN repository (sync by engine push and game pull model locally).
« Ostatnia zmiana: Luty 20, 2011, 22:28:27 wysłana przez MrKaktus »

Offline Pomnico

  • Użytkownik
    • Magic-Ars

# Luty 21, 2011, 08:27:36
Widzę że rozwiązałeś już swój problem, ale że nie tak dawno temu, napiszę jak ja mam to zrobione:
Mam jedno repozytorium z różnymi projektami (ale nie widzę powodu, aby miało to być na kilku różnych repozytoriach):
- BBoxes (kod z implementacją różnych kontenerów itp)
- Engine 3D
- Engine Audio
- Game Project
- Helpers etc.

To na czym mi zależało, to aby mieć silnik w osobnym projekcie svn, kod gry w innym, ale żeby ściągając grę (Game Project) ściągnęło mi również wszystkie projekty z silnikiem, helpersami itd. W związku z tym w katalogu Game Project zrobiłem podkatalog Engine i jemu dałem w svn propertiesa svn::export. On mówi, że w środku ma ściągnąć takie a takie elementy z jakiegoś repozytorium. Tortoise dodatkowo potrafi pokazywać różnice rekursywnie w takich elementach, pomimo że pochodzą z różnych repozytoriów. Więc w tych propertiesach external mam np.
Engine3D svn:\\Engine3D\trunk
EngineAudio svn:\\EngineAudo\trunk

Co do zależności ścieżek, założyłem że te zewnętrzne projekty w każdym solution'ie będą w takiej samej lokalizacji, więc mam ich identyczne rozmieszczenie we wszystkich solucjach. Dodatkowo chciałem, aby był tylko jeden katalog z assetami i aby wszystkie binarki lądowały właśnie do niego. Zrobiłem więc dodatkowy katalog bin w głównym katalogu solucji i wszystkie projekty generujące exe lub dll mają Custom Build Step'a który kopiuje ich binarkę do tego właśnie katalogu.

Edit:
External jest cholernie pomocne, ale ma jedną wadę. Trudniej jest przez nie zrobić brancha / taga, bo nie wystarczy tylko przekopiować repozytorium w inne miejsce (kilku w tym wypadku, np. Game/trunk do Game/branches/1.0.0, Engine3D/trunk do Engine3D/branches/1.00), ale dodatkowo trzeba jeszcze ręcznie zmienić wartośc tego properties'a na odpowiednią (z trunk na branches/...). Podobnie ma się rzecz ze ściągnięciem projektu po określonej rewizji lub dacie. Niby ściągasz z rewizji -100, ale po dojściu do external svn zaciągnie je z HEADa. No chyba że od samego początku korzystasz wewnątrz z projektów z konkretnych tagów lub rewizji. Wtedy takich problemów oczywiście nie ma.
« Ostatnia zmiana: Luty 21, 2011, 08:33:03 wysłana przez Pomnico »