CommonLib 8.0

Biblioteka CommonLib
Wersja: 8.0
Data: 29 marca 2008

CommonLib to uniwersalna biblioteka dla C++ zawierająca różnorodne elementy. Powstała przy okazji pisania silnika graficznego i różnych innych moich projektów. Obecna wersja jest pisana od wakacji 2006.

Właściwie od dziecka, odkąd tylko zacząłem programować (wtedy to był jeszcze Turbo Pascal pod DOS) zawsze rozwijałem jakąś swoją bibliotekę modułów bazowych, z którymi potem nigdy się nie rozstawałem pisząc swoje projekty. Teraz uważam, że nadal jest to potrzebne - szczególnie w C++, którego biblioteka standardowa - w przeciwieństwie do nowoczesnych języków i środowisk programowania takich jak Delphi, C# czy Java - jest bardzo uboga, a to co zawiera pozostawia wiele do życzenia.

Cechy i założenia

Jak użyć

Biblioteka ma postać plików z kodem C++ - CPP i HPP. Możesz z tym kodem zrobić co chcesz. Najprościej jest po prostu skopiować te pliki i dodać do swojego projektu.

Poniżej opisana jest jedna z możliwości - przygotowanie kodu jako biblioteki LIB i jej użycie w projekcie w Visual C++ 2005. Niestety nie jest to tak banalne jak rozpakować i od razu zacząć używać. To nie moja wina - takie są uroki języka C++...

Aby przygotować bibliotekę LIB:

  1. Utwórz projekt Visual C++ lub otwórz istniejący, który znajdziesz w pliku Common.sln.
  2. Wejdź do opcji projektu i zmień:
    1. Configuration Properties > General > Character Set: zależnie czy chcesz używać Unicode, ustaw na "Not Set" lub "Use Unicode Character Set" (w obydwu konfiguracjach - Debug i Release).
    2. Configuration Properties > C/C++ > Code Generation > Runtime Library: zależnie jak będziesz kompilował kod swoich programów korzystających z CommonLib: jeśli chcesz aby nie musiały używać dodatkowych plików DLL z biblioteką standardową C (których część użytkowników nie ma), przestaw na "Multithreaded Debug" (konfiguracja Debug) i "Multithreaded" (konfiguracja Release). Jeśli wolisz otrzymywać mniejsze pliki EXE, wybierze "Multithreaded Debug DLL" (konfiguracja Debug) i "Multithreaded DLL" (konfiguracja Release).
    3. Configuration Properties > C/C++ > Preprocessor > Preprocessor Definitions: W obydwu konfiguracjach (w każdej osobno) dopisz wybrane makra odpowiednio do bibliotek, których będziesz używał w swoim kodzie: USE_SDL, USE_OPENGL, USE_FMOD, USE_WINSOCK, USE_DEVIL, USE_AVI_FILE
    4. Jeśli nie masz zainstalowanej biblioteki zlib, nie chcesz jej używać albo w ogóle nie wiesz co to jest, usuń z projektu pliki ZlibUtils.cpp i ZlibUtils.hpp.
  3. Skompiluj bibliotekę w obydwu konfiguracjach - Debug i Release.
  4. Załóz na swoim dysku jakiś katalog, gdzie umieścisz skompilowaną bibliotekę jako gotową do używania w projektach. Utwórz w nim podkatalog include i skopiuj do niego pliki HPP. Utwórz katalog lib i skopiuj do niego pliki Common.lib (który powstał w podkatalogu Release) i Common_d.lib (który powstał w katalogu Debug).
  5. Skonfiguruj ścieżki do katalogów w Visual C++. W tym celu wybierze polecenie z menu Tools > Options. Po lewej zaznacz Projects and Solutions > VC++ Directories. Do "Include files" dopisz ścieżkę do podkatalogu includes. Do "Library files" dopisz ścieżkę do podkatalogu lib.

Aby skorzystać z tak skompilowanej biblioteki w swoim projekcie:

  1. Utwórz lub otwórz istniejący projekt programu w Visual C++.
  2. Dołącz wybane nagłówki biblioeki w postaci takiej jak np. include <Common/Base.hpp>. Jeśli używasz jakichkolwiek nagłówków CommonLib, musisz najpierw włączyć nagłówek Base.hpp.
  3. Wejdź do opcji projektu i zmień:
    1. Configuration Properties > General > Character Set: Tak jak wyżej.
    2. Configuration Properties > C/C++ > Code Generation > Runtime Library: Tak jak wyżej.
    3. Configuration Properties > C/C++ > Preprocessor > Preprocessor Definitions: Tak jak wyżej.
    4. Opcjonalnie, jeśli masz procesor dwurdzeniowy: Configuration Properties > C/C++ > Command Line > Additional Options: Wpisz "/MP" (w obydwu konfiguracjach). To przyspieszy kompilację.
    5. Opcjonalnie, skonfiguruj Precompiled Headers. Dopisz też do nich włączenie nagłówków CommonLib. Jeśli jeszcze nie wiesz, co to jest Precompiled Headers, dowiedz się czym prędzej - ten prosty mechanizm Visual C++ wielokrotnie przyspiesza kompilację!

Składniki i możliwości

Moduł Base

Moduł podstawowy

Dokumentacja: Module_Base
Elementy modułu: Moduł Base
Nagłówek: Base.hpp

Moduł Config

Dokumentacja: Module_Config
Elementy modułu: Moduł Config
Nagłówek: Config.hpp

Obsługa plików konfiguracyjnych

Obsługuje hierarchiczne pliki konfiguracyjne o składni wzorowanej na C/C++.

Moduł DateTime

Data i czas

Dokumentacja: Module_DateTime
Elementy modułu: Moduł DateTime
Nagłówek: DateTime.hpp

Moduł Dator

Otoczka na pojedynczą wartość dowolnego typu

Dokumentacja: Module_Dator
Elementy modułu: Moduł Dator
Nagłówek: Dator.hpp

Moduł Error

Klasy wyjątków do obsługi błędów

Dokumentacja: Module_Error
Elementy modułu: Moduł Error
Nagłówek: Error.hpp

Moduł Files

Obsługa plików i systemu plików

Dokumentacja: Module_Files
Elementy modułu: Moduł Files
Nagłówek: Files.hpp

Moduł FreeList

Bardzo szybki alokator pamięci

Dokumentacja: Module_FreeList
Elementy modułu: Moduł FreeList
Nagłówek: FreeList.hpp

Szablony klas common::FreeList oraz common::DynamicFreeList. Obiekty tych klas to napisane we własnym zakresie alokatory przeznaczone do alokowania dużych ilości zmiennych jednego wybranego typu, które działają znacząco szybciej niż standardowe operatory new i delete.

Moduł Logger

Mechanizm logowania komunikatów

Dokumentacja: Module_Logger
Elementy modułu: Moduł Logger
Nagłówek: Logger.hpp

Moduł Math

Moduł matematyczny

Dokumentacja: Module_Math
Elementy modułu: Moduł Math
Nagłówek: Math.hpp

Moduł Profiler

Przyrząd do pomiarów czasu i wydajności

Dokumentacja: Module_Profiler
Elementy modułu: Moduł Profiler
Nagłówek: Profiler.hpp

Moduł Stream

Hierarchia klas strumieni

Dokumentacja: Module_Stream
Elementy modułu: Moduł Stream
Nagłówek: Stream.hpp

Moduł Threads

Biblioteka do wielowątkowości i synchronizacji

Dokumentacja: Module_Threads
Elementy modułu: Moduł Threads
Nagłówek: Threads.hpp

Moduł Tokenizer

Parser składni języka podobnego do C/C++

Dokumentacja: Module_Tokenizer
Elementy modułu: Moduł Tokenizer
Nagłówek: Tokenizer.hpp

Moduł ZlibUtils

Moduł wspmagający biblioteki zlib

Dokumentacja: Module_ZlibUtils
Elementy modułu: Moduł ZlibUtils
Nagłówek: ZlibUtils.hpp

Obsługa Unicode

Od wersji 8.0 biblioteka posiada w systemie Windows możliwość pracy ze znakami i łańcuchami Unicode. Aby przełączyć CommonLib w tryb pracy z Unicode, należy podjąć te same kroki, co podczas przełączania do tego trybu WinAPI i DirectX. Trzeba w tym celu zdefiniować dla całego projektu makra preprocesora UNICODE i _UNICODE. W przypadki Visual C++ można przestawić w opcjach projektu, na zakładce Configuration Properties > General, opcję Character Set na Use Unicode Character Set - wówczas to makro zostanie dodane automatycznie.

Przy starannym stosowaniu się do poniższych zaleceń można pisać kod programu korzystający z WinAPI, DirectX i CommonLib tak, aby kompilował się i działał zarówno ze znakami Unicode, jak i zwykłymi ANSI, bez jakichkolwiek zmian w kodzie (wystarczy zmiana opisanego wyżej ustawienia).

Moduł definiuje typ znakowy common::tchar jako alias do char lub wchar_t oraz typ łańcuchowy common::tstring jako alias do std::string lub std::wstring, zależnie od ustawienia. Prawie wszystkie klasy i funkcje CommonLib korzystają z tych typów, tak że automatycznie przełączają się na używanie znaków i łańcuchów Unicode zależnie od tego ustawienia.

Łańcuch znaków ANSI zapisuje się w kodzie C++, jak wiadomo, w taki sposób: "ABC". Łańcuch znaków Unicode zapisuje się tak: L"ABC". Moduł Base definiuje makro, którym należy obejmować wszystkie łańcuchy w kodzie, jeśli chcemy, aby zostały zamienione na odpowiednią postać (ANSI lub Unicode) zależnie od ustawienia. Przykład: _T("ABC").

Jeśli piszemy kod, który ma działać zarówno ze znakami ANSI jak i Unicode, jako makro oznaczające nazwę bieżącego pliku źródłowego (podawane do konstruktora klas wyjątków modułu Error) używać należy zdefiniowanego w module Base makra __TFILE__. Podobnie, makro przechowujące sygnatuję bieżącej funkcji to __TFUNCSIG__.

Do konwersji między standardami kodowania znaków użyj funkcji common::ConvertUnicodeToChars i common::ConvertCharsToUnicode. Działają one tylko w Windows. Są niezależne od ustawienia _UNICODE. Pozwalają zamieniać łańćuchy między kodowaniem UTF-16 (Unicode), UTF-8 i ANSI (np. Windows-1250 w przypadku języka polskiego).

Jeśli piszesz kod, który ma się kompilować bez zmian zarówno w ANSI jak i Unicode, przydatne będą funkcje konwertujące łańćuchy między kodowaniem ASNI (typ string) lub Unicode (typ wstring), a tym używanym zależnie od ustawienia (typ common::tstring). Te funkcje to: common::TstringToString, common::StringToTstring, common::TstringToWstring, common::WstringToTstring. Jak można się domyślić, połowa z nich (która, to zależy od ustawienia) nic nie robi, tylko zwraca podany łańcuch.

Do zapisywania i odczytywania plików tekstowych w różnym kodowaniu służą funkcje modułu Files: common::SaveUnicodeToFile, common::SaveUnicodeToStream, common::LoadUnicodeFromFile, common::LoadUnicodeFromStream. W razie potrzeby automatycznie konwertują kodowanie znaków. Obsługują kodowanie ANSI, UTF-16 LE i UTF-8. Funkcje zapisujące mogą dołączać nagłówek BOM. Funkcje odczytujące, na podstawie nagłówka i analizy treści, mogą automatycznie rozpoznać kodowanie.

Mini FAQ

Skąd taka nazwa?

W moim głównym kodzie, z którego biblioteka się wywodzi, mam w Visual C++ w Solution szereg projektów. Jednym z nich jest silnik graficzny, innym pomocnicze narzędzie konsolowe czy program testujący. Kod wspólny dla wszystkich projektów zgromadziłem w katalogu, który nazwałem Common i tak już zostało.

Skąd taka wersja?

Faktycznie nie było CommonLib 4 czy 5, a wersja 6.1 była tak różna od 6.0, że powinna się nazywać 7.0. Jednak chciałem zrównać numerację biblioteki z numeracją mojego głównego projektu - silnika graficznego, na potrzeby którego napisałem tą bibliotekę.

Nowe wydanie - CommonLib 8.0 - nie oznacza że zacząłem pisać od nowa swój silnik graficzny. Oznacza raczej, że biblioteka przeszła wielkie zmiany po tym, jak silnik w wersji 7 został uznany za skończony.

Co nowego?

Wersja 8.0 (29 marca 2008)

Biblioteka przeszła wielkie zmiany. Logicznie większość kodu jest nadal kompatybilna wstecz, ale tekstowo zmiany są tak duże, że praktycznie nie ma sensu robić Diff. Ogólne, duże nowości:

Inne zmiany:

Wersja 7.0 (3 listopada 2007)

Biblioteka była przez ostatnie miesiące uzupełniana i poprawiana na bieżąco wraz z rozwojem silnika graficznego 3D, na potrzeby którego powstała.

Wersja 6.1 (29 czerwca 2007)

Od wersji 6.0 biblioteka zmieniła się właściwie nie do poznania. Dlatego nie ma sensu wypisywać zmian. Szczególnie, że pewnie nikt z niej wcześniej nie korzystał :P

Licencja

Biblioteka dostępna jest na licencji GNU LGPL, co znaczy m.in., że masz dostęp do jej kodu źródłowego oraz że możesz używać jej za darmo w dowolnych swoich programach, także zamkniętych.

Autor

Adam Sawicki
E-mail: sawickiap@poczta.onet.pl
WWW: http://regedit.gamedev.pl
IRC: warsztat @ PolNet
Gadu-Gadu: 2272474

Wygenerowano Sat Mar 29 18:16:59 2008 dla CommonLib programem  doxygen 1.5.5