Strona używa cookies (ciasteczek). Dowiedz się więcej o celu ich używania i zmianach ustawień. Korzystając ze strony wyrażasz zgodę na używanie cookies, zgodnie z aktualnymi ustawieniami przeglądarki.    X

Notatki programisty: integracja PhysicsFS z SFML

W poniższym wpisie chciałbym przedstawić prosty sposób na wykorzystanie plików z rozszerzeniem *.zip do przechowywania zasobów, w aplikacji używającej SFML. Motywacją do wpisu był fakt że przeszukując internet, nie znalazłem gotowego działającego kawałka kodu który zapewniłby mi taką funkcjonalność. Przechodząc do konkretów, zapraszam do lektury.

PhysicsFS

Do odczytu plików z archiwum *.zip będziemy używać biblioteki PhysicsFS. Jest to otwarto-źródłowa bibliotek wydana na licencji zlib dzięki czemu możemy być pewni że nikt nie będzie wołać o otwarcie naszego kodu. Mimo iż ostatnia aktualizacja miała miejsce w 2012 roku, format *.zip jest na tyle powszechny i uniwersalny że nie jest to jakaś duża niedogodność. Co prawda można ubolewać nad brakiem rozwoju projektu gdyż, prawdopodobnie, nie doczekamy się w nim funkcjonalności zabezpieczenia archiwum, hasłem, ale na potrzeby prostej aplikacji sprawdzi się w sam raz.

Biblioteka jest rozpowszechniana w postaci kodu źródłowego, co oznacza że sami musimy ją zbudować. W poniżej przedstawionym przykładzie, do zbudowania kodu używam QtCreatora z MinGW ze skonfigurowanym Cmakem w IDE. Uważam to za bardzo wygodne połączenie gdyż całość odbywa się w jednym oknie. Instrukcję jak skonfigurować Cmake w QtCreatorze znajdziemy tutaj.

Mając przystosowane środowisko, otwieramy plik CmakeLists.txt, projekt zostaje otworzony. Wybieramy typ budowy na release gdyż interesuje nas wersja bez znaczników debugowania. Przechodząc do do zakładki Projekty, mamy możliwość spersonalizowania budowanej biblioteki. Możemy wybrać jakie formaty mają być wspierane itp. PhysicsFS poza *.zip’em, oferuje wsparcie dla kilku innych rozszerzeń, więcej informacji znajduje się na stronie projektu. Wracając do tematu głównego: zatwierdzamy konfigurację i budujemy projekt.

Jako że wybrałem w konfiguracji opcje OFF w polu PHYSFS_BUILD_STATIC, interesującym mnie wynikiem kompilacji będą pliki: libphysfs.dll oraz libphysfs.dll.a. Następnie dobrze jest uporządkować katalog bibliotek. Wyżej wspomniane pliki przerzucamy do katalogu o nazwie lib, nagłówki ze źródeł PhysicFS przenosimy do nowego katalogu o nazwie: include, całość zamykamy w folderze o nazwie physicfs.

Integracja z SFML.

Pozwolę sobie nie opisywać procesu budowania SFML’a pod QtCreatorem. Jest to dobrze wytłumaczone w podanym przeze mnie linku dotyczącym konfiguracji Cmake’a lub też jak kto woli: analogiczny do budowania PhysicsFS. Na potrzeby przykładowej aplikacji utworzymy archiwum o następującej strukturze.

data | | --- > textures (katalog zawierający pliki cpp.png oraz uszatek.png) | --- > audio (katalog zawierajacy neverwinter_theme.ogg )

W archiwum będziemy przechowywać najpopularniejsze zasoby z których korzystają proste gry indie czyli tekstury i audio. Tworzymy projekt w QtCreatorze, dołączamy zależności i możemy przystąpić do tego co tygryski lubią najbardziej. Czyli kodu. ;) Poniżej przedstawione zostało jak będą wyglądać nasze funkcje ładujące pliki z archiwum.

/* Funkcja ladowania tekstur z objasnieniem. */ sf::Texture* getTextureFromZip(std::string name) { sf::Texture* texturePtr = nullptr; /* Test czy plik istnieje w obszarze poszukiwan.*/ if(PHYSFS_exists(name.c_str())) { std::cout << name + " - exists. \n"; /* Otwieramy plik i przypisujemy do niego * wskaznik. Nastepnie odczytujemy dane do * buffora oraz ilosc danych (jak duzo ich jest) */ PHYSFS_File* fileFromZip = PHYSFS_openRead(name.c_str()); const int fileLenght = PHYSFS_fileLength(fileFromZip); char* buffer = new char[fileLenght]; int readLength = PHYSFS_read (fileFromZip, buffer, 1, fileLenght); /* Tworzymy obiekt SFML w pamieci. */ texturePtr = new sf::Texture(); texturePtr->loadFromMemory(buffer, readLength); /* Nie trzeba chyba tlumaczyc, prawda? ;) */ PHYSFS_close(fileFromZip); } else { std::cout << name + " - doesn't exists. \n"; } return texturePtr; } /* Analogiczna funkcja dla plikow audio. */ sf::SoundBuffer* getSoundBufferFromZip(std::string name) { sf::SoundBuffer* soundBufferPtr = nullptr; if(PHYSFS_exists(name.c_str())) { std::cout << name + " - exists. \n"; PHYSFS_File* fileFromZip = PHYSFS_openRead(name.c_str()); const int fileLenght = PHYSFS_fileLength(fileFromZip); char* buffer = new char[fileLenght]; int readLength = PHYSFS_read (fileFromZip, buffer, 1, fileLenght); soundBufferPtr = new sf::SoundBuffer(); soundBufferPtr->loadFromMemory(buffer, readLength); PHYSFS_close(fileFromZip); } else { std::cout << name + " - doesn't exists. \n"; } return soundBufferPtr; }

Myślę że komentarz zawarty w kodzie jest wystarczająco wyczerpujący. Poniżej kod naszej funkcji głównej:

int main(int argc, char *argv[]) { /* Zainicjuj PHYSFS i dodaj plik *.zip * do "obszaru poszukiwań". */ PHYSFS_init(nullptr); PHYSFS_addToSearchPath("data.zip", 1); /* Funkcje zwracaja wskazniki wiec warto * sie zabezpieczyc przed ewentualnym * zapomnieniem o dealokacji pamieci. Stad * std::unique_ptr. Zakladamy ze funkcje * nie zwroci nam nullptr stad brak testu. * Co moze pojsc zle? ;) */ std::unique_ptr<sf::Texture> textureCpp( getTextureFromZip("texture/cpp.png")); std::unique_ptr<sf::Texture> textureUszatek( getTextureFromZip("texture/uszatek.png")); std::unique_ptr<sf::SoundBuffer> soundBufferNeverwinter( getSoundBufferFromZip("audio/neverwinter_theme.ogg")); /* Po zakonczeniu pracy z PHYSFS * nalezy go zdeinicjalizowac. */ PHYSFS_deinit(); /* Standardowy kod apki SFML. */ sf::RenderWindow window(sf::VideoMode(600, 400, 32), "AppZip", sf::Style::Default); sf::RectangleShape shapeCpp; shapeCpp.setSize(sf::Vector2f(150,150)); shapeCpp.setPosition(sf::Vector2f(50, 50)); shapeCpp.setTexture(textureCpp.get()); sf::RectangleShape shapeUszatek; shapeUszatek.setSize(sf::Vector2f(150,150)); shapeUszatek.setPosition(sf::Vector2f(300, 50)); shapeUszatek.setTexture(textureUszatek.get()); sf::Sound soundNeverwinterTheme; soundNeverwinterTheme.setBuffer(*soundBufferNeverwinter.get()); soundNeverwinterTheme.play(); while(window.isOpen()) { sf::Event myEvent; while(window.pollEvent(myEvent)){ if(myEvent.type == sf::Event::Closed){ window.close(); } } window.clear(); window.draw(shapeCpp); window.draw(shapeUszatek); window.display(); } return 0; }

Tu tak samo jak w przypadku kodu funkcji, myślę że komentarze wyczerpują temat. Po zbudowaniu aplikacji wszystko powinno wyglądać a nawet śpiewać. ;) Niestety na blogu nie zaprezentuje działającego dźwięku przez co zachęcam do własnoręcznego sprawdzenia kodu.

Podsumowanie.

W ten oto sposób dobrnęliśmy do końca. Na początku wpisu wspomniałem że biblioteka nie jest już rozwijana i prawdopodobnie nie zostanie w niej zaimplementowany mechanizm zabezpieczania archiwum hasłem. Na pocieszenie, wspomnę o tym że jeden z najlepszych hack’n’slashy ostatnich lat, Torchlight, przechowywał swoje zasoby w niezabezpieczonym pliku *.zip o ile dobrze pamiętam. Jak widać, można w komercyjnym produkcie zawierać tak "trywialne" rozwiązania.

Co więcej mógłbym zaproponować to jeżeli ktoś chciałby korzystać z PhysicsFS w większej aplikacji to warto jest go „ucywilizować” i opakować klasą ze spójnym interfejsem. Korzystanie z biblioteki w stylu strukturalnym na dłuższą metę wydaje się niewygodne i mało praktyczne.

Dzięki za uwagę. ;) 

programowanie hobby

Komentarze

0 nowych
  #1 03.01.2017 22:20

Qt? Czytałeś swoje wcześniejsze wpisy?

  #2 04.01.2017 15:08

Jak lubisz C++ to polecam zobaczyć Rust-a, to bardzo ciekawy język inspirowany trochę Scalą i nadaje się do takich małych sprytnych projektów.

SebaZ   18 #3 05.01.2017 13:40

Temat ciekawy, ale też ciężki merytorycznie. Tajniki sztuki magicznej :D

Autor edytował komentarz w dniu: 05.01.2017 13:40
kowgli   9 #4 06.01.2017 09:29

@SebaZ: Powiedziałbym, że ani specjalnie ciekawy (czytanie pliku z wewnątrz archiwum ZIP), ani ciężki merytorycznie ;)
Po prostu C++ jest mało czytelny (przez ogromną ilość magicznych symboli, do tego jeszcze wieloznacznych) oraz bez garbage collectora, przez co rzeczy które powinny być banalne i na które szkoda spędzać czas, stają się wyzwaniami. Chociaż w tym wypadku napisałoby się to pewnie podobnie w każdym innym jężyku. No.. może bez tylu gwiazdek ;)

Autor edytował komentarz w dniu: 06.01.2017 09:35
dragon321   12 #5 06.01.2017 12:16

@kowgli: C++ nie jest mało czytelny. Taki się tylko wydaje dla kogoś z zewnątrz, albo dla programistów wynalazków typu Java itd. Czy te rzeczy są wyzwaniami? Po prostu musisz pamiętać o zwolnieniu pamięci i tyle. Nie widzę żadnego wyzwania w tym fakcie. Na początku pare razy zapomnisz, a potem już będziesz to robił automatycznie. Wiem co mówię, bo w tym języku siedzę już spory czas.

Temat bardzo ciekawy (zwłaszcza, że dotyczy SFML, w którym i ja czasem coś dłubałem), ale obawiam się, że na takim portalu nie będziesz miał za dużo rozgłosu. Poprostu względnie mało osób tutaj programuje, a jeszcze mniej programuje w C++ i SFML.

biomen   8 #6 06.01.2017 12:25

@dragon321
Nie zależy mi na rozgłosie. Po prostu jak zaczynałem z klepaniem "gier indie" to doszedłem do momentu w którym to zasoby trzeba było jakoś po ludzku trzymać. Z czasem opracowałem satysfakcjonujące mnie rozwiązanie i stwierdziłem że nie ma sensu go kisić w szufladzie skoro komuś może się przydać. A że mam bloga na dobrychprogramach.

Niech przyszłe pokolenie polskich indie deweloperów ma łatwiejszy dostęp do wiedzy i nie musi wynajdować koła na nowo. ;)

kowgli   9 #7 06.01.2017 12:35

@dragon321: Programuję od prawie 20 lat, w wielu językach, w tym C++. W C++ nigdy nie programowałem zawodowo, ale parę całkiem sporych projektów zrobiłem. Używałem wielu języków i uważam, że C++ jest relatywnie mało czytelny (mówię o językach mainstreamowych). Jest często zbyt skrótowy, a rzeczy typu takich, że "*" w zależności od kontekstu znaczy zupełnie różne rzeczy (wskaźnik, wartość, mnożenie) jest moim zdaniem karygodne. Być może miało to sens 30 lat temu, kiedy każdy bajt się liczył, a monitory miały 80 linii. Obecnie nie ma.
Nie za bardzo rozumiem pejoratywnego określenia "wynalazków typu Java itd.". Chyba nie zajmujesz się tym zawodowo, bo miałbyś bardziej pragmatyczne podejście oraz umiał lepiej dobierać narzędzie do zastosowania. Np. tworzenie aplikacji CRUD, prostych gierek, czy serwisów webowych w C++ jest kompletnie bez sensu. Zmusza do męczenia się zupełnie nie z tym co trzeba. Zamiast logiki biznesowej, czy skalowalności skupiamy się na rzeczach trzeciorzędnych, typu zarządzanie pamięcią, czy operacje wejścia/wyjścia.

Co do powyższego kodu, nie twierdzę, że jest zły. Ale też nie widzę nic ciekawego w otwarciu zipa i odczytaniu z niego pliku, za pomocą gotowej biblioteki. Ot zwykły kod narzędziowy..jakiego są tysiące w każdym projekcie.

"Po prostu musisz pamiętać o zwolnieniu pamięci i tyle. Nie widzę żadnego wyzwania w tym fakcie. Na początku pare razy zapomnisz, a potem już będziesz to robił automatycznie. "
Wygląda to cudnie jak masz kilka, czy kilkanaście obiektów na krzyż. Co jednak jeśli liczba ta rośnie w tysiące, albo setki tysięcy? Skończysz pisząc swoją własną wersję GC, przy czym na pewno nie będzie on tak wydajny i sprawdzony w bojach jak np. ten z Javy, czy .NET oraz znowu zajmujesz się nie tym co powinieneś (implementacją wymagań biznesowych). Są badania mówiące o tym, że nieprawidłowości w zarządzaniu pamięcią odpowiadają za zdecydowaną większość (produkcyjnych) błędów w aplikacjach wykonanych w technologiach niezarządzanych.

Autor edytował komentarz w dniu: 06.01.2017 12:45
dragon321   12 #8 06.01.2017 12:50

@biomen: Po prostu to dość ciekawy artykuł i szkoda, żeby został przywalony innymi. Ale doceniam fakt, że opisałeś takie rozwiązanie - komuś może i się przyda.

@kowgli: Ciężko pomylił wskaźnik z mnożeniem, pomimo tego samego znaku. Widząc taki zapis: int *wsk - raczej nie pomylisz tego z mnożeniem. Widząc taki zapis: a*b - raczej nie pomylisz tego z wskaźnikiem. Niby operator ten sam, ale używa się go zupełnie inaczej, więc nie potrafię wyobrazić sobie sytuacji, w której ktoś mógłby pomylić te dwa operatory i wziąć mnożenie za używanie wskaźnika i vice versa. Tego się po prostu nie da pomylić, bo stosuje się je zupełnie inaczej. To czy jest skrótowy czy nie, to zależy jak piszesz kod. Możesz sobie pisać nieskrótowo, nic nie jest narzucone. I to jest właśnie zaleta, w przeciwieństwie do wynalazków typu Java - nic Ci nie narzuca w kwestii pisania kodu.

Nie muszę programować zawodowo by nie przepadać za Javą. Pozatym z webowymi zastosowaniami się trochę minąłeś - Java w zastosowaniu webowym wymarła już jakiś czas temu. Wtyczka jest nierozwijana a i sam Javy nie widziałem na stronie już spory czas. Do desktopu już bym wolał C# niż Jave. Zarządzanie pamięcią - jak już pisałem, jedynie musisz pamiętać o jej zwolnieniu jak nie jest potrzebna. Poza tym w wielu projektach wcale Ci nie jest potrzebne ręczne zarządzanie pamięcią. Ręczne zarządzanie wejściem/wyjściem? Od tego wymyślono biblioteki, mamy XXI wiek. Kto teraz się ręcznie bawi w obsługę wejścia/wyjścia?

Autor edytował komentarz w dniu: 06.01.2017 12:50
kowgli   9 #9 06.01.2017 13:14

@dragon321: "Nie muszę programować zawodowo by nie przepadać za Javą."

Nie musisz. Sam też nie przepadam. Nie pisałem konkretnie o Javie, tylko językach "typu Java".
Zawodowe zajmowanie się czymś powoduje jednak, że zamieniamy ideologię na pragmatyzm.
Pisząc o zastosowaniach webowych nie miałem oczywiście na myśli appletów, czy nawet JSP. To dużo szerze zagadnienie, patrząc choćby w stronę bardziej klasycznych usług i mikroserwisów. Nie zmienia to faktu, że C++ się do tego kompletnie nie nadaje, podobnie jak do 99% projektów.

Autor edytował komentarz w dniu: 06.01.2017 13:16
SebaZ   18 #10 06.01.2017 13:20

@kowgli: nie miałem na myśli technologii, a ciężkość tematu dla przeciętnego czytelnika portalu

biomen   8 #11 06.01.2017 13:24

@kowgli
Tak zapytam z ciekawości bo napisałeś:
"Nie zmienia to faktu, że C++ się do tego kompletnie nie nadaje, podobnie jak do 99% projektów."

Miałeś na myśli projekty że cały zbiór projektów/wszystkich typów czy tylko jakąś konkretną dziedzinę? Bo ciężko mi jednoznacznie zinterpretować twoje wypowiedzi.

kowgli   9 #12 06.01.2017 13:31

@biomen: Zbiór projektów wszystkich typów. Nie nadaje się do rzeczy webowych, aplikacji biznesowych i mobilnych, które łącznie stanowią obecnie "99%" wszystkich projektów.
Nie nadaje = zupełnie się nie nadaje lub istnieją lepsze narzędzia pozwalającej osiągnąć to samo, w dużo krótszym czasie.*

* A czas to pieniądz. Klienci płacą za funkcjonalność, nie technologię.

Autor edytował komentarz w dniu: 06.01.2017 13:42
dragon321   12 #13 06.01.2017 14:30

@kowgli: Jak już pisałem, w C# mógłbym programować - a zdaje się, że mechanizmy oferuje podobne jak Java. Pozatym to nie ideologia. Poprostu uważam ten język za lepszy.

C++ nie był projektowany do zastosowań webowych. Ciężko, żeby język kompilowany do kodu natywnego był taki. Jego zastosowania leżą gdzie indziej. I tam zazwyczaj nieco większym nakładem pracy sprawdzi się lepiej niż Java. 99% to lekka przesada. Sądzę, że C++ nadaje się do większej ilości projektów niż Java.

kowgli   9 #14 06.01.2017 16:03

@dragon321: Co do tego, że C#/.NET jest lepszy (a na pewno przyjemniejszy w użyciu) od Javy to pełna zgoda. Jest to moja ulubiona technologia, chociaż czuję się przez to dziadkiem...młodzież używa teraz przecież Node.js i podobnych.

Jeśli chodzi o C++ to moim zdaniem jego użycie ma sens tylko wtedy, kiedy czerpiemy korzyści z jego niskopoziomowych możliwości. Czyli głównie tam gdzie musimy komunikować się bezpośrednio ze sprzętem (oprogramowanie mikrokontrolerów, silniki graficzne, jądra systemów operacyjnych, sterowniki itp.). W innych zastosowaniach będzie tylko kulą u nogi. Zresztą widać to po praktyce.

Autor edytował komentarz w dniu: 06.01.2017 16:05
dragon321   12 #15 06.01.2017 16:08

@kowgli: Nie używam jej zbytnio, bo ma słabe wsparcie dla multiplatformowości. A napewno gorsze niż C++. Chociaż nie mam do niej nic - nie jest zła.

To Twoje zdanie i masz do niego prawo. Ale ono było prawdziwe może 20 lat temu. Dzisiejszy C++ ma tyle bibliotek i tyle mechanizmów, że jego niskopoziomowość jest praktycznie nie widoczna w większości projektów. Chcesz napisać aplikację desktopową? Spoko, bierzesz Qt, które to co trzeba, załatwia za Ciebie. Chcesz napisać grę? Spoko, bierzesz framework, który też załatwia co trzeba. Chcesz własną bibliotekę do GUI lub framwork do gier? Siadasz i piszesz, też się da. Na fali popularności języków wykonywanych przez maszyny wirtualne czy runtime (Java, C#) wydaje się, że język kompilowany do kodu maszynowego i mający wskaźniki jest niskpoziomowy. Ale to błędne przeświadczenie.

  #16 06.01.2017 20:31

@dragon321:

void mul(const int* in_a, const int* in_b, int* out_c)
{
*out_c *= *in_a * *in_b;
}

  #17 07.01.2017 10:37

@dragon321: Co z tego, że są biblioteki. Do Perla też są. To nie znaczy, że się wygodnie i wydajnie programuje. Nie na darmo na Qt się mówi "Write Once, Debug Everywhere". Ludzie z doświadczeniem już wolą używać Electron.

revcorey   8 #18 07.01.2017 13:57

@kowgli: std::shared_ptr itd. Nie chce mi się tego technicznie dalej komentować o C++.

Widziałem takie akcje w stylu "no przecież te nasze javascripty i inne to już takie dojrzałe technologie wprowadźmy do embbed(mówię tu o mocnych ARM/MIPS a nie o jakimś M0)"
Za każdym razem kończy się to porażką. Bo po prostu C++ jest uniwersalny ale i dość skomplikowany.
Do tego jak robisz soft budujesz sobie klasy całą funkcjonalność(od dołu do góry) i w front-end nie widzisz nawet niskopoziomowych operacji chyba że tak pisaliście soft że w klasie było wszystko ale to już kwestia że ludzie oprogramowania pisać nie umieją.

dragon321   12 #19 07.01.2017 14:40

@Anonim (niezalogowany)(#16): I to jest niby ten dwuznaczny kod? Analiza tego co robi zajęła mi kilka sekund. A ja jakimś bardzo dobrym programistą C++ nie jestem.

hyouka   9 #20 07.01.2017 16:01

@dragon321: Niby czytelne, ale można się pogubić, zwłaszcza na początku.

dragon321   12 #21 07.01.2017 21:34

@hyouka: Dokładnie tak samo można się pogubić w Javie czy innym wysokopoziomowym języku. Jak już pisałem - jako nieco bardziej zaawansowany amator C++ nie miałem żadnych problemów w ogarnięciu co ten kod robi.

hyouka   9 #22 07.01.2017 21:51

@dragon321: " nieco bardziej zaawansowany amator"

Co to za poziom?

  #23 07.01.2017 22:18

dra@dragon321o tylko jedna linijka pokazujaca slaba skladnie niewystepujaca w zadnym innym jezyku. m.in dlatego C++ wprowadzil pojecie referencji. Mozesz sprobowac poczytac zrodla boosta, cos wiecej niz jedna linijka-esencja metaprogramowanua z C++

dragon321   12 #24 08.01.2017 02:28

@Roman syn Ryżu (niezalogowany): Z tym, że Electron to taki półśrodek. Aplikacja webowa oprawiona w okno. Wydajnościowo nie dorówna to normalnej aplikacji.

dragon321   12 #25 08.01.2017 02:32

@Anonim (niezalogowany): Gdyby ta składnia była słaba, to powinienem poświęcić trochę czasu na jej analize. Jednakowoż analiza tego kodu zajęła mi nie więcej niż kilka sekund. Jeżeli to jest przykład słabej składni, to chyba nie widziałeś naprawdę słabego kodu.

@hyouka: Amator, który wie nieco więcej niż przeciętny amator, a za mało na określenie "średniozaawansowany" :)

Autor edytował komentarz w dniu: 08.01.2017 02:33
  #26 08.01.2017 09:09

@dragon321: Do czego ci wydajność jeśli użytkownik klika raz na kilkanaście sekund? Czas reakcji jest wystarczający.
Jeśli aplikacja ma coś wydajnie przetwarzać na lokalnym komputerze, to wtedy warto napisać w C++ sam element przetwarzania. Zgodnie z data driven development.

  #27 08.01.2017 10:53

@dragon321: Chcesz sie upierac przy tym jednolinijkowcu,do Boosta sie nie odniosles. To moze inaczej, C++ nie ma opracowanej calej formalnej gramatyki bo ta nie jest mozliwa do opisania,stad parsery C++ sa najbardziej skomplikowanymi ze wszystkich popularnych jezykow.

dragon321   12 #28 09.01.2017 01:11

@Roman syn Ryżu (niezalogowany): "Jeśli aplikacja ma coś wydajnie przetwarzać na lokalnym komputerze, to wtedy warto napisać w C++ sam element przetwarzania. Zgodnie z data driven development."

Dokładnie. Jednak wyżej zostało zasugerowane, że C++ się nie nadaje do 99% rzeczy. Co jest brednią.

Anonim (niezalogowany): "Chcesz sie upierac przy tym jednolinijkowcu,do Boosta sie nie odniosles. To moze inaczej, C++ nie ma opracowanej calej formalnej gramatyki bo ta nie jest mozliwa do opisania,stad parsery C++ sa najbardziej skomplikowanymi ze wszystkich popularnych jezykow."
Ależ w czym się upierać? To miał być przykład strasznej i dwuznacznej składni C++, a takowym nie jest. Nie trzeba być niewiadomo kim, by z łatwością go zaanalizować i dowiedzieć się co robi. Więc to słaby przykład.

  #29 09.01.2017 08:03

@dragon321: Bo nadaje się głównie do tego do czego dawniej nadawały się wstawki w asm. GUI bym w nim nie pisał. Szczególnie, że większość frameworków jest obiektowa i robi więcej krzywdy niż pożytku w tym języku.

dragon321   12 #30 09.01.2017 13:32

@Roman syn Ryżu (niezalogowany): "Bo nadaje się głównie do tego do czego dawniej nadawały się wstawki w asm. "

Do tego nadaje się C. C++ się nie nadaje do pisania rzeczy stricte niskopoziomowych. Jak myślisz, czemu większosć istniejących systemów operacyjnych (i chyba wszystkie najpopularniejsze, jak Windows, Linux czy macOS) mają jądra pisane w C? Czemu sterowniki pisze się głównie w C? Nie, nie dlatego, że wtedy nie było C++. Obecność wskaźników nie sprawia, że dany język jest niskopoziomowy. To błędne myślenie.

Obiektowość jest właśnie tym, co najbardziej rozróżnia C++ od C i umożliwia mu odpowiednią wysokopoziomowość. Robi mu krzywdę? Pod jakim względem?

Autor edytował komentarz w dniu: 09.01.2017 13:34
fras   8 #31 11.01.2017 10:31

@dragon321:

" I to jest niby ten dwuznaczny kod? Analiza tego co robi zajęła mi kilka sekund."

Takich rzeczy w ogóle nie powinieneś analizować. To powinno być czytelne od pierwszego spojrzenia.
Zauważ, że nawet czcionki projektuje się tak by człowiek szybko czytał. Możesz się pochwalić, że czytasz żółtą czcionkę bezszeryfową na niebieskim tle. Dasz radę? Dasz. No to przeczytaj w rozsądnym czasie 200 stron :)

dragon321   12 #32 11.01.2017 13:29

@fras: Użyłem słowa "analizować" jako zamiennika dla "zrozumieć". Serio, możesz dać osobie nieobeznanej do przeczytania kod w C++ i go przeczyta, ale czy zrozumie?

To nie jest nieczytelny kod. A już napewno nie dla programisty tego języka. Chcesz nieczytelny kod, to poczytaj sobie kod Asemblera wykrojony z komentarzy. Analiza trochę Ci zajmie ;)

fras   8 #33 11.01.2017 15:01

@dragon321: tutaj nie chodzi o jakiś mega nieczytelny kod dający wielogodzinną rozkminę, ale kod zmuszający nawet doświadczonego programistę do niepotrzebnego wysiłku intelektualnego. Dlatego podałem analogię do ergonomii czcionki. Czytać - przeczytasz, ale przy złej czcionce efektywność niepotrzebnie spada.
Jeszcze inna analogia: zamiłowanie polskich drogowców do szpikowania dróg znakami drogowymi. Najlepsze są skrzyżowania z jakimiś wydumanymi regułami pierwszeństwa. :) Te znaki zrozumie nawet osoba z IQ=80, ale ich analiza *każdemu* zabiera cenne ułamki sekund.
Po co sobie życie komplikować?
Jeśli tę samą myśl możemy wyrazić prościej i czytelniej, to tym lepiej! Rozwój języków programowania jest wszak określony przez ograniczoną percepcję człowieka. To jest główny motor zmian w językach programowania.

Autor edytował komentarz w dniu: 11.01.2017 15:03
dragon321   12 #34 11.01.2017 16:08

@fras: "nawet doświadczonego programistę do niepotrzebnego wysiłku intelektualnego"

Od początku piszę, że mnie ten kod nie zmusił mnie do żadnego wzmożonego wysiłku intelektualnego, a doświadczonym programistą bym się napewno nie nazwał. Poza tym jak już tak ktoś nienawidzi wskaźników, to od czegoś wprowadzono referencję w C++. Ten kod można zapisać tak z wykorzystaniem referencji:
void mul(const int &in_a, const int &in_b, int &out_c)
{
out_c *= in_a * in_b;
}

Robi dokładnie to samo co tamten. Czyli, jak to ładnie określiłeś, masz tę samą myśl wyrażoną "prościej i czytelniej". Tamten też nie był strasznie nieczytelny, ale jak ktoś tak uważa, no to można prościej.

Autor edytował komentarz w dniu: 11.01.2017 16:09
fras   8 #35 11.01.2017 23:50

@dragon321: Nie neguję, że kod C++ może być zgrabny i czytelny. Przykładową linijkę zamieszczoną w tym wątku odebrałem jako ilustrację niezbyt optymalnego doboru znaków i składni dla konkretnej operacji (konstrukcji języka), a nie że wszystko co się napisze w C++ musi wyglądać źle.

Zasadniczo kod wygląda OK, a przy nowoczesnym stylu bardzo OK.
Wieki w tym nie pisałem, ale pamiętam, że na składnię nie narzekałem, a jedyny ból, to uszkodzenia sterty wynikające z mojego niedbalstwa. Myślę, że wielu się na tym ślizgało i dlatego teraz w większości zastosowań działa GC.

Jednak składnię dałoby się troszkę poprawić. Nie zapominajmy, że tu są naleciałości z lat 60, a wstecznej kompatybilności nie można było psuć. Jak na takie warunki C++ jest całkiem, całkiem. Niech się tłumaczą autorzy języków powstałych niedawno, np. JS.

Autor edytował komentarz w dniu: 11.01.2017 23:53
dragon321   12 #36 12.01.2017 09:02

@fras: Z takim przedstawieniem sprawy mogę się zgodzić. C++ jest o tyle dobry, że z nowymi rozszerzeniami ułatwia różne sprawy.

Cóż, na jego składni wzoruje się wiele nowoczesnych języków (Java, C#, JS itd.). Kompatybilność z C była może i zaletą, ale teraz już nie wiem, czy to zaleta - i tak C ma swoją niszę, której C++ nie zastąpi. Niestety na wiele ułatwień z Javy czy C# nie ma co liczyć, bo w przeciwieństwie do wyżej wymienionych, jest to język kompilowany do kodu maszynowego. Nie jest uruchamiany przez maszynę wirtualną czy inne środowisko.