################################################################################
  Kodowanie Windows-1250, koniec wiersza CR+LF, test: Za gl ja
  Logger - Mechanizm logowania komunikatw
  Copyleft (C) 2007 Adam Sawicki
  Licencja: GNU LGPL
  Kontakt: mailto:sawickiap@poczta.onet.pl , http://regedit.gamedev.pl/
################################################################################


Wstp
================================================================================

Logger to modu do logowania, czyli zapisywania krtkich komunikatw tekstowych
do pliku, na konsol i w dowolne inne miejsca - typowo przeznaczony do
wyprowadzania informacji o zdarzeniach zachodzcych w programie, bdach itd.

Waciwoci:

- Przenony
  Dziaa na Windowsie i Linuksie.
- Wielowtkowy
  Bezpieczny wtkowo. Sam te wykorzystuje wtki.
- Wypasiony
  Ma praktycznie wszelkie moliwoci jakie tylko potrafiem wymyli :)

- Uoglnienie logw
  Log to abstrakcyjny obiekt, ktrym moe by plik, konsola i dowolne inne
  miejsce. Mona pisa wasne logi.
- Rozdzielenie komunikatw od logw
  Zapisywane komunikaty trafiaj do centralnego loggera, a stamtd dopiero kady
  jest mapowany na zero, jeden lub wicej logw.
- Uoglniony podzia komunikatw
  Komuniaty s opisywane przez mask bitow, ktra moe oznacza kategori,
  priorytet lub cokolwiek i ktr mona wykorzysta do mapowania na logi
  docelowe, na prefiksy, kolory i dowolne inne rzeczy zalenie od loga.


Podstawy
================================================================================

*Logger* to system logowania. Jest tylko jeden. Inicjalizuje si go funkcj
CreateLogger, a finalizuje - DestroyLogger. Midzy tymi wywoaniami mona
otrzyma go funkcj GetLogger.

*Log* to obiekt klasy dziedziczcej z interfejsu ILog. Reprezentuje miejsce,
do ktrego mog trafia logowane komunikaty i odpowiada za ich zapisywanie
do tego miejsca. Moe to by na przykad plik tekstowy w jakim formacie,
realizowana z uyciem jakiego API konsola albo cokolwiek.

Prawidowa sekwencja wywoa wyglda jak w przykadzie:

	// 1. Utworzenie loggera
	//    Utworzenie logw
	logger::CreateLogger(false);
	logger::Logger & Logger = logger::GetLogger();
	logger::TextFileLog *Log = new logger::TextFileLog("Log.txt", logger::FILE_MODE_NORMAL, base::EOL_CRLF);

	// 2. Konfiguracja logw
	//    Konfiguracja loggera
	//    Zarejestrowanie logw
	Logger.AddLogMapping(0xFFFFFFFF, Log);

	// 3. Uywanie w czasie pracy programu
	Logger.Log(1, "Komunikat 1");
	Logger.Log(1, "Komunikat 2");
	Logger.Log(1, "Komunikat 3");

	// 4. Usunicie loggera
	logger::DestroyLogger();

	// 5. Usunicie logw
	delete Log;

Bardzo wane jest, aby logi usuwa dopiero po usuniciu loggera. Wane te,
by po rozpoczciu uywania loggera nie dokonywa ju adnej konfiguracji
loggera ani logw, nie tworzy nowych logw itd.


Typy, maski, mapowanie
================================================================================

*Komunikat* to krtka wiadomo tekstowa, ktra podlega zalogowaniu. Komunikat
skada si z treci [string] oraz typu (uint4). Tre powinna by w kodowaniu
Windows-1250 (jak w caym projekcie). Moe zawiera koce wiersza (w dowolnym
formacie) - logi maj obowizek prawidowo obsugiwa komunikaty
wielowierszowe - ale jest to raczej niezalecane, bo powinna by krtka.

*Typ komunikatu* to maska bitowa. Mona jej nada dowolne znaczenie, np.:

- Rodzaj komunikatu
- Rodzaj nadawcy komunikatu
- Priorytet komunikatu

Komunikaty logujemy za pomoc metody loggera Log podajc kolejno typ i tre.
Logger wysya go do zera, jednego lub wielu logw zalenie od mapowania.
Podczas rejestrowania logw w loggerze podajemy *mask bitow*, ktra bdzie
czona operatorem & z typem komunikatu i jeli wynik bdzie niezerowy,
komunikat trafi do danego loga. W ten sposb mona mapowa tylko wybrane typy
komunikatw na wybrane logi. Log zarejestrowany z mask 0xFFFFFFFF otrzyma
wszystkie komunikaty o niezerowym typie.

Przykad mapowania typw komunikatw na logi:

	Logger.AddLogMapping(0xFFFFFFFF, Log1);
	Logger.AddLogMapping(1, Log2);

	Logger.Log(1, "Komunikat 1");
	Logger.Log(2, "Komunikat 2");
	Logger.Log(3, "Komunikat 3");

W tym przykadzie do Log1 trafi wszystkie komunikaty, a do Log2 tylko te,
ktrych typ ma ustawiony najmodszy bit, czyli komunikaty 1 i 3.

Nie naley rejestrowa logw w loggerze wicej ni raz.


Prefiksy
================================================================================

*Prefiks* to przedrostek dodawany do treci kadego logowanego komunikatu.
Jest skadany indywidualnie dla kadego loga na podstawie ustawionego dla niego
*formatu prefiksu*, ktry jest dowolnym acuchem, a specjalne wartoci s w nim
zastpowane przez:

- %D - data
- %T - czas
- %1 ... %3 - wasne informacje prefiksu
- %% - znak "%"

Format prefiksu mona ustawi dla loga metod SetPrefixFormat. Mona te ustawi
na raz format prefiksu dla wszystkich logw zarejestrowanych w loggerze metod
SetPrefixFormat loggera. Ustawianie formatu prefiksu jest czci procesu
konfiguracji.

*Wasne informacje prefiksu* to trzy acuchy, ktre mona zmienia w czasie
dziaania programu (ich zmiana jest czci procesu uywania loggera) i ktre
mog by doczane do prefiksu. S wsplne dla caego loggera. Do ich zmiany
suy metoda SetCustomPrefixInfo. Mona je wykorzystywa np. do wskazania
numeru biecej klatki gry czy innych tym podobnych rzeczy.

*Prefiks typu* to dodatkowy prefiks doczany za prefiksem gwnym do treci
logowanego komunikatu. Jest ustalonym na stae acuchem. Kady log ma wasne
mapowanie masek typw na prefiksy typu. Mona to mapowanie wykona metod
AddTypePrefixMapping loga. Metoda AddTypePrefixMapping loggera dokonuje go
jednoczenie dla wszystkich zarejestrowanych w nim logw. Jest to cz procesu
konfiguracji.

Przykad:

	Log1->SetPrefixFormat("[%D %T %1] ");
	Log1->AddTypePrefixMapping(1, "(!) ");
	Logger.SetCustomPrefixInfo(0, "Frame:123");

	Logger.Log(1, "Komunikat 1");
	Logger.Log(2, "Komunikat 2");
	Logger.Log(3, "Komunikat 3");

Da w efekcie mniej wicej takie wyjcie:

	[2006-08-18 21:52:28 Frame:123] (!) Komunikat 1
	[2006-08-18 21:52:28 Frame:123] Komunikat 2
	[2006-08-18 21:52:28 Frame:123] (!) Komunikat 3

W przypadku kiedy typ danego komunikatu pasuje do wielu mapowa na prefiks,
wykorzystane zostanie pierwsze z nich. Dlatego mapowania naley dodawa
w kolejnoci od najbardziej szczegowych do najbardziej oglnych. Na przykad
jeli chcemy doda mapowanie ktre dotyczy "wszystkich pozostaych" komunikatw,
dodajemy je z mask 0xFFFFFFFF na samym kocu.


Tryby pracy
================================================================================

Logger moe pracowa w dwch trybach:

1. BEZ KOLEJKI
Kiedy podamy podczas tworzenia loggera jako parametr CreateLogger warto false,
logger loguje komunikaty natychmiast po ich otrzymaniu.

2. Z KOLEJK
Kiedy podamy podczas tworzenia loggera jako parametr CreateLogger warto true,
logger tworzy osobny wtek zajmujcy si logowaniem. Logowane komunikaty
trafiaj do specjalnej kolejki, a wtek pobiera je i loguje w swoim tempie.

Tryb z kolejk jest szybszy, ale tryb bez kolejki jest bardziej niezawodny
w wypadku awarii programu. W trybie z kolejk finalizacja loggera moe potrwa
dusz chwil, jeli wymaga poczekania na zalogowanie zalegajcych w kolejce
komunikatw.

Kolejno wywoa logowania komunikatw i zmiany wasnych informacji prefiksu
jest respektowana take w trybie z kolejk.

Loggery plikowe mona otwiera w trzech trybach:

- FILE_MODE_NORMAL
- FILE_MODE_FLUSH
- FILE_MODE_REOPEN

Tryb z kolejk w poczeniu z FILE_MODE_NORMAL jest najszybszy.

Tryb bez kolejki w poczeniu z FILE_MODE_REOPEN jest najpewniejszy - daje
gwarancj, e nawet w przypadku nagego wysypania si programu wszystko, co byo
wczeniej logowane trafio do logw.


Bezpieczestwo wtkowe
================================================================================

Tworzenie logw, ich konfiguracja, konfiguracja loggera - nie s bezpieczne
wtkowo. Dlatego naley ich dokonywa przed rozpoczciem uywania loggera.

Logowanie i zmiana wasnych informacji prefiksu s bezpieczne wtkowo. Mona
ich dokonywa z wielu wtkw na raz.


Tworzenie wasnych logw
================================================================================

Aby utworzy wasny log, naley napisa wasn klas dziedziczc z intefejsu
ILog. Jej jedynym obowizkiem jest implementacja metody OnLog, ktra bdzie
miaa za zadanie zalogowa komunikat. Otrzymuje ona ju zredagowane do acuchw
prefiksy (gwny i prefiks typu) oraz tre. Przekazywany take typ moe
wykorzysta do realizacji wasnego mapowania, np. na kolor. Jej obowizkiem
jest dostosowanie treci wszystkich otrzymanych achw do kodowania znakw i
kocw wiersza obowizujcego w miejscu docelowym. Wejciowe kodowanie znakw
to Windows-1250, a kocw wiersza - nieokrelone.

Klasa ta nie musi by bezpieczna wtkowo - o bezpieczestwo wtkowe dba sam
logger. Metody tej klasy mog by wywoywane z rnych wtkw, ale nigdy nie
bd wywoywane rwnoczenie.

