Wątek przeniesiony 2015-07-20 15:20 z przez furious programming. Powód: (użytkownik nie podał powodu)

TreeStructInfo - format tekstowych i binarnych plików konfiguracyjnych

Odpowiedz Nowy wątek
2014-07-13 00:44
10

Po wielu miesiącach żmudnej pracy, w końcu udało się ukończyć pracę nad projektem TreeStructInfo; Poniżej znajduje się więc ogólny opis zarówno formatu plików, jak i przygotowanego API do ich obsługi, dlatego że jest to zaganienie dość obszerne;

Strona projektu: https://tsinfo.4programmers.net
Specyfikacja formatu: https://tsinfo.4programmers.net/pl/format/1.0.htm


Czym jest TreeStructInfo?

Format TreeStructInfo to projekt tekstowych i binarnych plików konfiguracyjnych, umożliwiających zapis informacji w postaci czytelnych drzewiastych struktur; Opracowany został z myślą o przechowywaniu różnego rodzaju ustawień aplikacji, gier i innych narzędzi; Umożliwia tworzenie zarówno prostych - jednoplikowych konfiguracji, a także bardziej złożonych, wieloplikowych systemów konfiguracyjnych; Nie jest on zależny od platform programowych, więc można z niego korzystać np. pod Windows, Linuks czy OS X;

Format ten według mnie stanowi ciekawą alternatywę przede wszytkim dla rejestru systemu oraz plików Ini, a także dla takich formatów jak XML, YAML czy TOML, z racji bardzo prostej budowy i składni, a także unikalnej funkcjonalności;

Uwaga! Format **TreeStructInfo** nie powinien być stosowany w zastępstwie systemów bazodanowych - nie takie jest jego pierwotne przeznaczenie i do tego się zbytnio nie nadaje;

1. Formy plików TreeStructInfo

Format ten przewiduje dwie formy plików konfiguracyjnych - tekstową oraz binarną; Pomiędzy tymi formami istnieje pełna kompatybilność; Dowolny plik tekstowy przekonwertowany na formę binarną i z powrotem, będzie posiadać dokładnie taką samą zawartość, jak pierwotna - konwersja nie powoduje utraty części zapisanych informacji;

Pliki binarne zawierać mogą te same elementy, co pliki tekstowe;


1.1. Forma tekstowa

Forma ta służy do tworzenia otwartych konfiguracji, umożliwiając tworzenie plików w dowolnych edytorach, a także umoliżliwiając użytkownikowi swobodę wprowadzania modyfikacji;

Pliki w formie tekstowej budowane są w sposób liniowy - jedna linia może zawierać tylko jedną informację (np. nagłówek drzewa, deklarację atrybutu itd.); Kolejnym atutem jest bardzo czytelna składnia, oparta na niedużej ilości słów i fraz kluczowych, a także znikomej liczby używanych znaków specjalnych; Dzięki temu zawartość plików tekstowych jest bardzo przyjazna dla człowieka, a zapisywane do atrybutów dane mogą zawierać praktycznie dowolne znaki, z wyjątkiem kilku zarezerwowanych;

Przykładowy plik: https://tsinfo.4programmers.net/pl/format/1.0.htm#idSampleFile

Główną zaletą plików tekstowych jest możliwość dzielenia drzewa konfiguracji na mniejsze części, co może znacząco wpłynąć na ich czytelność; Dzielenie drzewa odbywa się za pomocą referencjonowania elementów - ich deklaracje określają miejsce elementów w drzewie, zaś definicje posiadają już konkretną zawartość;

Fragmentacja drzewa z wykorzystaniem referencjonowanych elementów to pierwszy z dwóch metod dzielenia drzew; Drugim sposobem jest podział drzewa na wiele plików, powiązanych ze sobą na podstawie dowiązań (linków do plików dołączanych);

Więcej: https://tsinfo.4programmers.net/pl/format/1.0.htm#idTextForm


1.2. Forma binarna

Forma binarna służy do przechowywania takich samych konfiguracji jak forma tekstowa, jednak odróżnia ją mniejszy (czasem znacząco) rozmiar, a także dużo większa szybkość ładowania zawartości plików do pamęci; Dzieje się tak dlatego, że do plików binarnych nie są zapisywane takie informacje jak słowa kluczowe czy wcięcia, a przetwarzanie tych plików odbywa się bardzo prostą i szybką rekurencyjną techniką;

Forma ta przeznaczona jest dla zamkniętych konfiguracji, zawartych w większych plikach, dzięki czemu ich ładowanie jest po prostu krótsze, prostsze i szybsze; Natomiast w żadnym wpadku nie służy do maskowania danych, dlatego że zawartość nie jest szyfrowana;

Więcej: https://tsinfo.4programmers.net/pl/format/1.0.htm#idBinaryForm


2. Elementy drzew

Do budowy drzew wykorzystywane są trzy typy elementów: atrybuty, węzły oraz linki do plików dołączanych; Przeznaczenie poszczególnych elementów:

  • atrybuty - służą do przechowywania pojedynczych danych; Przechowywane mogą być dane wielu typów i w wielu postaciach, jako wartości jednoliniowe lub wieloliniowe;
  • węzły - umożliwiają grupowanie elementów oraz tworzenia drzewiastej struktury informacji;
  • linki do plików dołączanych - udostępniają możliwość dowiązania w ich miejscu innych drzew, zawartych w osobnych plikach; Dołączane drzewa z zewnętrznych plików mogą być zapisane w dowolnej formie (tekstowej lub binarnej); Elementami łączącymi drzewa w miejscu linków są tzw. węzły wirtualne;

Więcej: https://tsinfo.4programmers.n[...]ormat/1.0.htm#idBasicElements


3. Komentarze

Format ten zezwala na używanie komentarzy zarówno jednoliniowych, jak i wieloliniowych; Same komentarze nie są postrzegane jako osobne elementy - są integralną częścią elementów drzew, a także samych drzew i nie mogą istnieć w dowolnych miejscach plików;

Komentarze dzielą się na dwie grupy - główny komentarz drzewa, zapisywany na samym początku plików, a także komentarze elementów, zapisywane zawsze ponad deklaracjami lub definicjami elementów;

Elementy referencjonowane (których ciała definiowane sa poza głównym ciałem drzewa) mogą posiadać dwa komentarze - jeden deklaracji i jeden definicji; Mogą być jedno lub wieloliniowe; Elementy te nie muszą posiadać ich obu - mogą posiadać tylko jeden (deklaracji lub definicji), lub nie posiadać go wcale;

Wszelkie komentarze są informacjami dodatkowymi i nieobowiązkowymi, bez względu na ich typ;

Więcej: https://tsinfo.4programmers.net/pl/format/1.0.htm#idComments


4. Tworzenie systemów konfiguracyjnych

Format umożliwia także tworzenie rozbudowanych, wieloplikowych konfiguracji; Z racji tej, że dowolne pliki TreeStructInfo nie zawierają w sobie informacji o tym, czy egzystują jako pojedyncze pliki, czy są dołączane przez inne pliki, do budowy systemów konfiguracyjnych można wykorzystać zarówno pliki tekstowe, jak i binarne;

Pliki natomiast mogą posiadać informację o tym, czy same linkują inne pliki; Informacje te zapisywane są za pomocą linków do plików dołączanych;

Liczba plików, z których budowane są systemy konfiguracyjne nie jest ustalona, więc można wykorzystać dowolną ich ilość; Nie zaleca się jednak tworzenia zbyt wielkich systemów - główny plik nie powinien linkować więcej, niż kilkanaście plików; Jeśli istnieć będzie potrzeba przechowywania dużo większych konfiguracji - rozwiązaniem jest stworzenie po prostu większej liczby głównych plików;


5. Dostęp do elementów drzew

Kolejnym atutem formatu jest dostęp do elementów drzew na podstawie standardowych ścieżek, na podobieństwo śieżek do elementów rejestru Windows; Ścieżki dostępu tworzone są z nazw elementów oraz znaków separatora - znaku \;

Ścieżki do elementów drzew posiadają zawsze taką samą formę; Zawsze - bez względu na to, czy odwołujemy się do elementu w tym samym drzewie, czy do elementu z drzewa linkowanego; A jeśli z drzewa linkowanego, to bez względu na poziom dowiązania (drzewo linkowane także może linkować następne, a następne także następne);

Dzięki takiemu rozwiązaniu, pliki formatu TreeStructInfo stają się bardziej przyjazne i jeszcze prostsze w użyciu we własnych programach;

Ścieżki dostępu nie są używane do budowy plików konfiguracyjnych - wykorzystywane sa jedynie w API, podczas zapisu lub odczytu danych;

Więcej: https://tsinfo.4programmers.n[...]ormat/1.0.htm#idElementsPaths


6. Podsumowanie

Powyższy, mocno skrócony opis formatu przedstawia tylko najważniejsze jego możliwości; Funkcjonalność formatu jest na tyle bogata, że pliki konfiguracyjne TreeStructInfo posiadają szeroki wachlarz zastosowań; Zastosowane zabiegi zależą głównie od potrzeb oraz wyobraźni;

Szczegółowy opis możliwości formatu przedstawiony jest specyfikacji pierwszej wersji formatu, do której link znajduje się na samej górze tego posta;


API do obsługi plików TreeStructInfo

Sam format miałby niewielką wartość, gdyby nie było żadnej możliwości jego wykorzystania we własnych programach; Dlatego też stworzyłem bibliotekę, która pozwala na wykorzystywanie plików konfiguracyjnych w obu formach, w pełnej zgodzie ze specyfikacją; Biblioteka ta umożliwia wykorzystanie wszystkich aspektów formatu;

Co umożliwia oficjalne API:

  1. ładowanie plików konfiguracyjnych w obu formach z różnych źródeł - z plików dyskowych, z list lub strumieni, a także z zasobów plików wykonywalnych lub bibliotek DLL, na podstawie nazwy lub ID;
  2. zapis i odczyt danych wszystkich opisanych w specyfikacji typów danych:
    1. wartości logiczne - różne łańcuchy,
    2. liczby całkowite - różne systemy liczbowe (dec, hex, oct i bin)
    3. liczby rzeczywiste - różne notacje,
    4. walutę - różna precyzja,
    5. pojedyncze znaki - wartość znaku lub jego kod w różnych systemach liczbowych,
    6. łańcuchy znaków - jednoliniowe lub wieloliniowe,
    7. data i czas - dowolny format, wraz z dodatkowymi, nieformatowanymi ciągami,
    8. współrzędne punktów - różne systemy liczbowe,
    9. listy - zawartość dowolnych list dziedziczących po klasie TStrings,
    10. strumienie - zawartości dowolnych strumieni dziedziczących po klasie TStream,
    11. dowolnych buforów - możliwość zapisu dowolnych danych w postaci mapy heksadecymalnej;
  3. obsługę dowolnych systemów konfiguracyjnych;
  4. znacznie, znacznie więcej;

Biblioteka ta napisana została w Lazarusie, pod FPC 2.6.2, ale ze względów na wykorzystane podstawowe elementy kodu, możliwe jest jej użycie we wcześniejszych wersajch FPC; Nie jest też uzależniona od platformy, więc nadaje się nie tylko dla Windows;

Do przygotowanego API stworzona została także dokumentacja, opisująca dosłownie każdy element API (od stałych, przez typy i wpólne procedury i funkcje, po klasy i ich składowe); Wszystkie informacje o API są w dokumentacji on-line, dlatego też nie było potrzeby komentowania kodu;

Oprócz samej dokumentacji przygotowany został tutorial, przedstawiający różne sposoby wykorzystania oficjalnej biblioteki; Opisuje on wszystkie metody i właściwości klas do obsługi plików - klasy TSimpleTSInfoFile z podstawową funkcjonalnością oraz TTSinfoFile, zawierającej metody dodatkowe, rzadziej używane;

Oficjalne API do pobrania: https://tsinfo.4programmers.net/pl/download/index.htm

Dokumentacja API: [link nieaktywny]
Tutorial API: [link nieaktywny]

Bibliotekę udostępniam na warunkach licencji GNU Lesser GPL 3, więc z otwartym źródłem i możliwością wykorzystania jej w dowolnych projektach - otwartych lub zamkniętych, darmowych lub komercyjnych; Korzystajcie więc jak Wam się podoba;


To tyle jeśli chodzi o ogólne informacje na temat projektu TreeStructInfo; Wszystkich zainteresowanych zachęcam do zapoznania się ze specyfikacją formatu, a Pascalowców programujących w Lazarusie, o zapoznanie się i przetestowanie oficjalnego API;

Mam nadzieję, że projekt przypadnie do gustu i że znajdą się chętni do jego wykorzystania we własnych aplikacjach czy grach;Pozostałych zachęcam do pomocy w rozwijaniu projektu - być może ktoś miałby czas i chciałby wspomóc projekt swoim API, napisanym w innym języku niż Object Pascal;

Przygotowałem ten format i API także dla siebie - z tego formatu będę korzystał w swoich przyszłych programach; No i grach, bo SnakeASCII już został przystosowany do tego formatu - dane dotyczące podstawowych plansz będą zapisane w plikach TreeStructInfo i wrzucone do zasobów pliku wykonywalnego, skąd API umożliwia odczyt plików w bardzo prosty sposób;


Przy okazji dziękuję wszystkim za pomoc przy pracy nad tym projektem, głównie @babubabu - który poświęcił czas na przetestowanie biblioteki;

Życzę więc miłej lektury specyfikacji i przyjemnego korzystania z oficjalnej biblioteki :]


edytowany 12x, ostatnio: furious programming, 2017-07-16 17:21
Pokaż pozostałe 6 komentarzy
Moze lepiej zamiast tworzyc nowy edytor sie zastanowic nad stworzeniem pluginow do edytorow, ktorych faktycznie ludzie uzywaja, typu sublime czy vim. - n0name_l 2014-07-13 16:48
@n0name_l - żaden obecny edytor nie pozwoli na tworzenie plików i zarządzanie nimi w obu formach - tekstowej i binarnej; Do samych plików tekstowych można użyć dowolnych, dlatego nad pluginami będę w najbliższym czasie pracował; - furious programming 2014-07-13 16:50
Z czasem trzeba by pomyśleć o angielskiej wersji strony. - several 2014-07-14 11:15
@several - owszem, wstępnie ikonki flag mam przygotowane (na stronie); Jednak co innego czytać dokumentacje po angielsku, a co innego je pisać; Z czytaniem nie mam problemów, jednak z poprawnym napisaniem może być kłopot; W każdym razie to dopiero początek - jeszcze dużo będzie się działo :) - furious programming 2014-07-14 18:15
Trzymam kciuki :) - several 2014-07-14 22:50

Pozostało 580 znaków

2014-07-21 11:33
4

Po tygodniowej przerwie, przyszedł czas na aktualizację; Wprowadziłem trochę usprawnień i modyfikacji, część elementów poszła do nila; Poniżej opis nowych rzeczy i lista tych, których już nie ma z nami;


1. Format TreeStructInfo

Główną zmianą w samym formacie (czyli w specyfikacji) jest zmiana strony kodowej plików w formie tekstowej i binarnej; Wcześniej pliki tekstowe musiały zawierać znaki o stałej szerokości (jednobajtowe), czyli zgodne z kodowaniem ASCII i ANSI; Problemem jednak był malutki i dynamiczny zakres możliwych do wykorzystania znaków, przez co nie było możliwości przechowywania łańcuchów ze znakami obcych języków lub innych-szczególnych znaków;

Dlatego też została wprowadzona możliwość wykorzystania strony kodowej UTF-8, zarówno dla plików w formie tekstowej, jak i łańcuchów zapisywanych w plikach w formie binarnej; Tak więc od kilku dni, domyślną stroną kodową dla formatu TreeStructInfo jest wspomniany UTF-8;

Zmiana strony kodowej plików nie powoduje niezgodności z poprzednią wersją; Pliki tekstowe kodowanej w ANSI nadal pozostają zgodne z obecnym kodowaniem, dlatego że UTF-8 jest w pełni zgodne z ASCII; Jedynym problemem mogą być wykorzystane znaki diakrytyczne i wszystkie inne spoza ASCII; W takim przypadku łańcuchy te należy przekonwertować odpowiednimi funkcjami z RTL na obecne kodowanie;

Kolejną modyfikacją formatu jest usunięcie znaku # ze zbioru znaków zarezerwowanych; Znak ten stanowił prefiks dla kodu znaku w wartości atrybutu; Z racji tej, że obecna strona kodowa posiada zmienną szerokość znaków - ułatwieniem jest możliwość zapisu takich znaków jako łańcuchów;

Ostatnią modyfikacją formatu jest zmiana wartości znaku, służącego do oznaczenia wartości atrybutu jako jednej pustej linii listy; Wcześniej tym znakiem był #255, jednak znak ten jest zabroniony do użytku w plikach kodowanych w UTF-8; Dlatego też do określenia listy bądź macierzy z jednym pustym elementem, wykorzystuje się znak tabulacji poziomej, czyli znaku #9;

Jeśli chodzi o sam format - to wszystkie zmiany; Reszta pozostaje w poprzedniej postaci;


2. Oficjalne API

Oficjalne API zostało przystosowane do obsługi nowej strony kodowej; Fizycznych zmian wiele nie było - nie trzeba było przerabiać całej biblioteki, aby móc korzystac z plików kodowanych w UTF-8; Poniżej lista wprowadzonych modyfikacji;

dodano:

  • ładowanie i zapis drzew w plikach ze stroną kodową UTF-8,
  • usuwanie znacznika BOM z plików źródłowych,
  • obsługę poprawnej konwersji wielkości znaków w łańcuchach zapisywanych do atrybutów metodą WriteString,
  • możliwość określenia wielkości znaków odczytywanego łańcucha z atrybutu za pomocą metody ReadString (dodatkowy parametr AFormat typu TFormatString),
  • funkcję ValueToString w module TSInfoUtils.pp, wykorzystywaną w metodzie ReadString;

usunięto:

  • stałe CHAR_PREFIX i CHARACTER_SYSTEMS z modułu TSInfoConsts.pp,
  • typ TFormatChar z modułu TSInfoTypes.pp,
  • funkcje CharacterToValue i ValueToCharacter z modułu TSInfoUtils.pp,
  • metody TSimpleTSInfoFile.WriteChar i TSimpleTSInfoFile.ReadChar z modułu TSInfoFiles.pp;

Czyli dodane i usunięte zostały wymienione elementy po to, aby API było zgodne z nową stroną kodową oraz całą specyfikacją formatu;


3. Strona projektu

Specyfikacja formatu oraz dokumentacja API na stronie projektu zostały zaktualizowane; Aktualne źródła oficjalnej biblioteki są dostępne przede wszystkim na stronie projektu w dziale pobierania; Źródła dostępne są także w serwisie GitHub:

https://github.com/furious-programming/TreeStructInfo

Readme oraz Wiki zostaną uzupełnione w najbliższych dniach; Natomiast pierwsza wersja release pojawi się nieco wcześniej, dlatego że jeszcze dwie rzeczy będą wprowadzone w API; No i muszę ogarnąć funkcję tagowania w GIT :]


4. Plany na najbliższą przyszłość

Jeśli chodzi o sam format i jego specyfikację to myślę, że w najbliższym czasie nie będzie nowych rzeczy ani usuwanych starych; W API natomiast pojawi się nowa funkcjonalność, usprawniająca odczyt danych z atrybutów i redukująca w małym stopniu ilość zapisywanych danych;

Otóż zostaną dodane do klasy TSimpleTSInfoFile nowe metody, które pozwolą na tokenizowanie atrybutów, bez konieczności zapisywania w osobnym atrybucie ich liczby i nazywania ich numerami; Metody te będą działać na zasadzie funkcji FindFirst i FindNext, dzięki czemu w prosty sposób będzie można odczytywać dane z atrybutów, nie znając ich liczby i identyfikatorów; Dzięki temu ułatwi się ich odczyt i zlikwiduje się konieczność użycia dodatkowego atrybutu, dlatego plik o poniższej treści:

<pre style="background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAL0lEQVQYV2NkwALevXuXJiQkNAtZinEAFb59+3YmuvWMjIxn////bzxY3Ej14AEA0LUraxfkjiYAAAAASUVORK5CYII=") rgba(234, 239, 242, 0.447);">
tsinfo version "1.0"
:: liczba atrybutów
attr Count "3"
:: atrybuty do odczytu
attr 0 "Value"
attr 1 "Value"
attr 2 "Value"
end tree

</pre>
będzie można zastąpić poniższym:

<pre style="background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAL0lEQVQYV2NkwALevXuXJiQkNAtZinEAFb59+3YmuvWMjIxn////bzxY3Ej14AEA0LUraxfkjiYAAAAASUVORK5CYII=") rgba(234, 239, 242, 0.447);">
tsinfo version "1.0"
:: atrybuty do odczytu
attr 0 "Value"
attr 1 "Value"
attr 2 "Value"
end tree

</pre>
Aby utrzymać zgodność z obecną formą odwoływania się do elementów drzewa, tokenizowanie atrybutów będzie opierać się o metodę TSimpleTSInfoFile.OpenChildNode, co umożliwi pracę także z elementami z drzew linkowanych; W przypadku gdy żaden węzeł nie zostanie otwarty - tokenizowane będą atrybuty z głównego węzła głównego drzewa konfiguracji;

Kolejną funkcją będzie możliwość ładowania drzewa bez linkwania zewnętrznych plików, jeśli w ładowanych drzewie znajdują się linki do plików dołączanych; To umożliwi zwiększenie szybkości ładowania plików do pamięci, korzystanie tylko z tego, z czego chcemy, a także umożliwi konwersję plików na binarne, jeśli taki plik znajduje się w systemie konfiguracji; Tym bardziej, jeśli taki plik jest linkowany i sam linkuje inne pliki;

Podsumowując, będzie to znaczne usprawnienie odczytu konfiguracji, które będzie miało szerokie zastosowanie (w tych szczególnych, wyżej wymienionych przypadkach);


5. Podsumowanie

Jeśli ktoś zechciał już skorzystać z formatu TreeStructInfo i oficjalnej biblioteki, to proszę sobie pobrać najnowsze źródła ze strony projektu; W chwili obecnej oficjalne API posiada status beta, jednak po wprowadzeniu funkcji tokeniozowania atrybutów, status ten zmieni się na release, a jego wersja oznaczona zostanie numerem 1.0, jako wersja finalna i stabilna; Oczywiście to nie oznacza, że prace nad projektem zostaną definitywnie zakończone;

Życzę miłego korzystania z API i formatu, a także zachęcam do przyłączenia się do prac nad rozwojem projektu, jeśli tylko znajdą się osoby z chęciami, umiejętnościami i oczywiście wolnym czasem;

Dziękuję za oceny - dzięki temu wiem, że projekt się podoba i że warto go rozwijać; Dziękuję również za sugestie, znajdujące się w komentarzach do poprzedniego posta; Jednak zachęcam do dyskusji w postach - nie bójcie się także krytykowania; To że jestem moderatorem nie oznacza przecież, że na krytykę mojego projektu odpowiem banami... :]


edytowany 12x, ostatnio: furious programming, 2017-07-16 17:23
Dodałem kolorowanie składni plików; - furious programming 2014-07-22 15:46
Dodałem tło do przykładowych zawartości plików; - furious programming 2014-07-30 18:52

Pozostało 580 znaków

2014-07-21 20:20
pytajnik123
1

niezbyt czytelnie to wygląda...
napisz może jakiś program demonstrujący użycie takiego formatu.

No ale szacun za chęci mimo wszystko :)

Pozostało 580 znaków

2014-07-22 14:11
1

niezbyt czytelnie to wygląda...

@pytajnik123 - ale dlaczego? Tu na forum niestety nie mam kolorowania składni, więc będę musiał sprawdzić jak to zrobić ręcznie; Na stronie projektu jest pokazana zawartość przykładowego pliku - tam jest kolorowanie składni, ale plik jest krótki i zawiera prawie wszystkie dozwolone elementy (łącznie z referencjonowanymi), więc może sprawiać wrażenie przesadzonego; Ale to jest tylko przykład - dedykowane pliki będą wyglądać lepiej, dlatego że nie będzie w nich "wszystkiego";

napisz może jakiś program demonstrujący użycie takiego formatu.

Piszę - SnakeASCII, czyli kultowy "wąż" w specyficznej tekstowej formie - jednak nie umiem jednocześnie rozwijać API, aktualizować GITa, uzupełniać dokumentację, tworzyć pluginy do edytorów i dedykowany edytor, rozwijać grę i pisać przykładowe programy... Najpierw wypuszczę stabilną wersję API i uzupełnię stronę projektu, a dopiero później będę myślał nad innymi rzeczami; W każdym razie nie martw się - póki co nie przewiduję zakończenia prac nad projektem :]

Pierwszym przykładowym programem będzie gra SnakeASCII, która już została przygotowana do obsługi plików TreeStructInfo i działa w ich oparciu, jednak aktualnych źródeł jeszcze nie udostępniałem; Nastąpi to jak wydzielę obsługę planszy i węża do osobnej klasy, aby można było ją wykorzystać w kilku miejscach (jedna klasa gry dla kilku jej trybów);

PS: Dodałem kolorowanie składni do przykładowych zawartości plików, podanych w poprzednim swoim poście.


edytowany 2x, ostatnio: furious programming, 2014-07-22 15:47

Pozostało 580 znaków

2014-07-28 02:36
1

Minął tydzień od ostatniej aktualizacji, więc czas na kolejną;

Tym razem wprowadzone zostały nowe-ostatnie funkcje, które zamierzałem wprowadzić, aby zwiększyć wygodę korzystania z plików konfiguracyjnych; Nic nie zostało usunięte, za to dodałem nowe typy i nowe metody bazowej klasy; Poniżej opis najprawdopodobniej ostatnich zmian - czas w końcu na wersję release;


1. Oficjalne API

Jeśli ktoś przeglądał repozytorium projektu TreeStructInfo na GitHub to pewnie zauważył nowe commity;

W module TSInfoConsts.pp dodana została stała CURRENT_NODE_SYMBOL ze znakiem ~, wykorzystywanym do oznaczania ścieżki aktualnie otwartego węzła za pomocą metody OpenChildNode; Dzięki temu można zwiększyć czytelność kodu, zawierającego odwołania do elementów po otwarciu danego węzła; Poniższe odwołania są równoznaczne:

tsiConfig.WriteInteger('Value',   $BADFACE);
tsiConfig.WriteInteger('~\Value', $BADFACE);

Przykład odwołania się do atrybutu z węzła potomnego względem węzła aktualnie otwartego:

tsiConfig.WriteInteger('Foo\Bald\Bar\Value',   $BADFACE);
tsiConfig.WriteInteger('~\Foo\Bald\Bar\Value', $BADFACE);

Jeśli w ścieżce znajduje się identyfikator ~ - metoda wyszukująca element (czyli metoda FindElement) po prostu pomija go;

Kolejną nowością jest dodanie do modułu TSInfoUtils.pp funkcji IsCurrentNodeSymbol, która po prostu sprawdza, czy dany ciąg znaków ścieżki lub identyfikatora oznacza odwołanie się do aktualnie otwartego węzła; Funkcja ta wykorzystywana jest teraz w kilkudziesięciu metodach, aby przystosować je do obsługi znaku ~;

Następną nowością jest wprowadzenie flagi ffNoLinking, możliwej do użycia w konstruktorach klasy TSimpleTSInfoFile; Umożliwia ona załadowanie drzewa bez linkowania ewentualnych drzew z innych plików; Użycie jej spowoduje, że linkowanie będzie pominięte, bez względu na to czy ładowany plik jest głownym plikiem konfiguracji, czy plikiem linkowanym;

Jednak największą zmianą są cztery nowe metody, umożliwiające tokenizowanie elementów drzewa:

  • FindFirstAttribute - pozwala wyszukać pierwszy atrybut w danym węźle,
  • FindNextAttribute - służy do wyszukiwania kolejnych atrybutuów w danym węźle,
  • FindFirstChildNode - umożliwia wyszukanie pierwszego węzła potomnego w danym węźle,
  • FindNextChildNode - pozwala wyszukiwać kolejne węzły potomne w danym węźle;

Metody te bazują na dwóch nowych typach obiektów - TTSInfoAttributeToken i TTSInfoChildNodeToken - do których wpisywane są informacje o znalezionych elementach; Typy te pozwalają na pobieranie informacji o elementach, umożliwiając zarówno odczyt danych jak i ich modyfikację, jednak nie udostępniają referencji do instancji klas elementów; Samo wyszukiwanie elementów nie jest uzależnione od ich stanu referencjonowania;

Jak wygląda tokenizowanie elementów? Bardzo prosto; Poniżej przykład tokenizowania atrybutów i węzłów potomnych, znajdujących się w głównym węźle drzewa lub w aktualnie otwartym węźle:

var
  attrToken: TTSInfoAttributeToken;
  nodeToken: TTSInfoChildNodeToken;
{ tokenizowanie atrybutów }
if tsiConfig.FindFirstAttribute(attrToken) then
repeat
  { wykorzystanie tokenu }
until not tsiConfig.FindNextAttribute(attrToken);
{ tokenizowanie węzłów potomnych }
if tsiConfig.FindFirstChildNode(nodeToken) then
repeat
  { wykorzystanie tokenu }
until not tsiConfig.FindNextChildNode(nodeToken);

a także przykład tokenizowania elementów zawartych w węźle potomnym względem głównego węzła drzewa lub względem aktualnie otwartego węzła:

{ tokenizowanie atrybutów }
if tsiConfig.FindFirstAttribute(attrToken, '~\Foo\Bald\') then
repeat
  { wykorzystanie tokenu }
until not tsiConfig.FindNextAttribute(attrToken);
{ tokenizowanie węzłów potomnych }
if tsiConfig.FindFirstChildNode(nodeToken, '~\Foo\Bald\') then
repeat
  { wykorzystanie tokenu }
until not tsiConfig.FindNextChildNode(nodeToken);

Jak widać proces tokenizowania jest bardzo prosty i przyjemny - coś jak wykorzystanie funkcji FindFirst i FindNext z modułu SysUtils;

Więcej informacji oczywiście w uzupełnionej dokumentacji API, a także w tutorialu dotyczącym obsługi klasy TSimpleTSInfoFile;


2. Format TreeStructInfo

Jedyną nowością jest wpis dotyczący częściowej rezerwacji znaku ~, oznajmiający, że łańcuch znaków zawierający tylko jeden znak ~ jest nieporawidłowym identyfikatorem; Pozostałe elementy bez zmian i mam nadzieję, że już więcej modyfikacji nie będzie (chyba, że ortografia itd.);


Podsumowanie

To by było na tyle zmian w projekcie; Oficjalne API jest już dopięte na ostatni guzik - stabilną wersję najnowszych źródeł można pobrać ze strony projektu (w dziale pobierz), a także z repozytorium na GitHub;

Zostało już niewiele do zrobienia:

  • otagować stabilną wersję źródeł w repo,
  • dodać binarki do repo i umożliwić ich pobranie ze strony projektu,
  • uzupełnić plik README.md w repo;

Mam nadzieję, że uda się to zrobić jeszcze przed końcem tego miesiąca; W każdym razie z biblioteki można już śmiało korzystać i nie bać się, że funkcjonalność bądź specyfikacja się zmieni;


To tyle - jeśli ktoś korzysta już z oficjalnego API, to polecam pobrać najnowsze źródła (są w pełni kompatybilne z poprzednią wersją); Oczywiście życzę miłego korzystania z API i plików konfiguracyjnych, a także proszę o ewentualny feedback, jeśli uznacie że coś nie gra :]


edytowany 5x, ostatnio: furious programming, 2017-07-16 17:24
Ta tylda to na pewno dobry pomysł? Linuxowcy mogą się spodziewać że tylda oznacza folder domowy użytkownika tj. /home/zellus/ etc... - Zellus 2014-07-28 07:42
Myślę, że to dobry pomysł, dlatego że ścieżki dotyczą tylko elementów drzew, nie plików dyskowych; Ten znak jest też używany w ścieżkach w Windows, ale jest także możliwy do użycia w nazwach plików; Sądzę, że Linuksiarzom łatwiej będzie go zrozumieć i zapamiętać, że ~ oznacza ścieżkę aktualną, od której się rozpoczyna się wyszukiwanie elementów (i nie tylko wyszukiwanie); - furious programming 2014-07-28 12:25
@Zellus - prosiłem wcześniej, aby dyskutować w postach, bo w komentarzach nie można napisać coś więcej i normalnie formatować tekstu... - furious programming 2014-07-28 12:26

Pozostało 580 znaków

2014-08-17 00:12
2

Minęło już trochę czasu od poprzedniej aktualizacji, więc czas na kolejną;


1. Składnia plików

Miało nie być znaczących zmian, jednak z racji niezrozumienia przeznaczenia części funkcjonalności formatu, głupich i nieuargumentowanych docinek i chamskiego feedbacku (niestety w zupełnie obcym serwisie, do którego trafiłem przez przypadek), postanowiłem nieco zmodyfikować składnię tekstowych plików konfiguracyjnych;

Pierwsza zmiana dotyczy słów i fraz kluczowych, wykorzystywanych do tworzenia deklaracji i definicji elementów referencjonowanych; Wcześniej stosowane były trzy słowa kluczowe:

  • &attr
  • &node
  • &end
    zostały one zamienione na bardziej intuicyjne i bardziej czytelne frazy kluczowe:

  • ref attr
  • ref node
  • end ref

Przykład zastosowania elementów referencjonowanych poniżej:

<pre style="background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAL0lEQVQYV2NkwALevXuXJiQkNAtZinEAFb59+3YmuvWMjIxn////bzxY3Ej14AEA0LUraxfkjiYAAAAASUVORK5CYII=") rgba(234, 239, 242, 0.447);">tsinfo version "1.0"
:: standardowy atrybut
attr Integer "0xBADFACE"
:: referencjonowany atrybut
ref attr Float
:: standardowy węzeł potomny
node First
end
:: referencjonowany węzeł potomny
ref node Second
end tree

:: referencjonowany atrybut
ref attr Float "3,14"

:: referencjonowany węzeł potomny
ref node Second
:: i jego zawartość
attr Referencing "True"
end ref</span></pre>

Druga modyfikacja składni dotyczy wartości i ilości flag, wykorzystywanych w linkach do plików dołączanych; Wcześniej istniały tylko dwie flagi:

  • "binary"
  • "updatable"

ich zakres został zwiększony do czterech, nazwanych bardziej intuicyjnie:

  • "text"
  • "binary"
  • "read"
  • "write"

Pierwsze dwie flagi stosuje się do określenia formy linkowanego pliku (plik tekstowy lub binarny), dwie kolejne do określenia trybu linkowania (tylko do odczytu lub do odczytu i zapisu); Deklaracje linków do plików dołączanych mogą teraz wyglądać następująco:

<pre style="background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAL0lEQVQYV2NkwALevXuXJiQkNAtZinEAFb59+3YmuvWMjIxn////bzxY3Ej14AEA0LUraxfkjiYAAAAASUVORK5CYII=") rgba(234, 239, 242, 0.447);">:: dowiązanie pliku tekstowego w trybie tylko do odczytu
link "FileName.ext" as "Virtual Node Name"
link "FileName.ext" as "Virtual Node Name" flags ""
link "FileName.ext" as "Virtual Node Name" flags "text"
link "FileName.ext" as "Virtual Node Name" flags "text" "read"

:: dowiązanie pliku tekstowego w trybie do odczytu i zapisu
link "FileName.ext" as "Virtual Node Name" flags "text" "write"

:: dowiązanie pliku binarnego w trybie tylko do odczytu
link "FileName.ext" as "Virtual Node Name" flags "binary"
link "FileName.ext" as "Virtual Node Name" flags "binary" "read"

:: dowiązanie pliku binarnego w trybie do odczytu i zapisu
link "FileName.ext" as "Virtual Node Name" flags "binary" "write"</span></pre>

Skrócona forma deklaracji linków jest nadal możliwa do zastosowania;


2. Oficjalne API

Biblioteka została przystosowana do nowych fraz kluczowych i nowego zbioru flag - były to małe poprawki; Oczywiście specyfikacja formatu, dokumentacja API i tutorial do jego obsługi zostały odpowiednio poprawione;


Podsumowanie

To były już ostatnie modyfikacje, związane zarówno z funkcjonalnością formatu, jak i z oficjalnym API do obsługi plików TreeStructInfo; Więcej już nic nie będzie poprawiane lub rozszerzane - to finalna forma; Sama specyfikacja może się jeszcze nieco zmienić, ale tylko jeśli chodzi o literówki czy poprawienie nieskładnych zdań (podobnie z dokumentacją API);

W dziale pobierania dostępna jest oficjalna biblioteka, do pobrania w formie archiwum .zip; Jedno archiwum zawiera same źródła (pliki .pp), a drugie zawiera standardową paczkę (package), możliwą do wykorzystania we własnych projektach; W serwisie GitHub znajduje się także pierwszy release biblioteki oraz skrócona wersja specyfikacji formatu w języku koślawo-angielskim;

To by było na tyle - specyfikacja formatu jest, wersja produkcyjna API jest, dekumentacja i tutorial są; W takim razie życzę miłego korzystania z biblioteki i przepraszam za ewentualne problemy, wynikłe z modyfikacji składni i API.


edytowany 6x, ostatnio: furious programming, 2017-07-16 17:26

Pozostało 580 znaków

2014-08-18 16:48
0

ref attr Float "3,14"

z kropka tez bedzie prawidlowe?

ref attr Float "3.14"


Pozostało 580 znaków

2014-08-18 17:22
1

@mca64 - tak, kropka też będzie poprawna, ale w szczególnym przypadku;

Metody zapisujące lub odczytujące liczby zmiennoprzecinkowe, walutę oraz datę i czas korzystają z rekordów typu TFormatSettings, więc znak separatora dziesiętnego zawsze brany jest z takiego rekordu; Jeśli korzystasz z podstawowej metody zapisu liczb zmiennoprzecinkowych, to znak separatora dziesiętnego brany jest z rekordu DefaultFormatSettings, czyli domyślnie znak przecinka;

Jeśli interesuje Cię inny znak separatora, to skorzystaj z rozszerzonej wersji metody zapisującej/odczytującej, do której podaje się rekord TFormatSettings - możesz uzupełnić ten rekord odpowiednią funkcją, która pobierze dane lokalizacyjne z systemu, albo uzupełnić go samemu, jeśli chcesz całkiem customowe wartości;

Te metody wykorzystują algorytmy konwersji z biblioteki standardowej, czyli funkcje FloatToStrF oraz TryStrToFloat, więc jeśli znasz te funkcje, to powinieneś wszystko zrozumieć bez problemu;

Przykład zapisu liczby zmiennoprzecinkowej w podstawowej formie:

var
  tsiConfig: TSimpleTSInfoFile;
begin
  tsiConfig := TTSInfoFile.Create('C:\Config.tsinfo', [ffLoadFile, ffWrite]);
  try
    tsiConfig.WriteFloat('Float', 3.14);
  finally
    tsiConfig.Free();
  end;
end.

oraz z własnym separatorem dziesiętnym:

var
  tsiConfig: TSimpleTSInfoFile;
  fsCustom: TFormatSettings;
begin
  tsiConfig := TTSInfoFile.Create('C:\Config.tsinfo', [ffLoadFile, ffWrite]);
  try
    fsCustom := DefaultFormatSettings;
    fsCustom.DecimalSeparator := '.';
    tsiConfig.WriteFloat('Float', 3.14, fsCustom);
  finally
    tsiConfig.Free();
  end;
end.

Pierwszy kod zapisze liczbę w postaci 3,14, a drugi już z innym separatorem - 3.14; Po więcej informacji odsyłam do odpowiedniego działu specyfikacji, w którym zawarta jest informacja dotycząca separatorów w liczbach zmiennoprzecinkowych:

liczby zmiennoprzecinkowe napisał(a)

Znakiem separatora dziesiętnego nie musi być znak ,, a separatora tysięcznego znak ` (znak spacji). Znaki te uzależnione są głównie od standardów zapisu liczb zmiennoprzecinkowych względem danej lokalizacji, stąd np. separatorem dziesiętnym może być znak.`.


Jeśli korzystasz z oficjalnej biblioteki i z czymś masz problem, to załóż wątek w odpowiedzim dziale - w nim udzielę Ci wszelkich informacji dotyczących danego zagadnienia.


edytowany 6x, ostatnio: furious programming, 2017-07-16 17:27

Pozostało 580 znaków

2014-08-18 17:27
0

ok juz rozumiem. Zastanawialem sie czy ten znak jest na sztywno czy z TFormatSettings


Pozostało 580 znaków

2014-08-18 17:31
1

Wszystko jest dynamicznie, dlatego że metody zapisujące/odczytujące korzystają z funkcji konwertujących z biblioteki standardowej; Właściwych funkcji konwertujących (w tym przypadku FloatToValue oraz ValueToFloat) nie pisałem w całości ręcznie; Jedynym wyjątkiem są funkcje do konwersji daty i czasu, dlatego że te z RTL nie obsługiwały w pełni tego, co narzuca specyfikacja.


edytowany 1x, ostatnio: furious programming, 2014-08-18 17:45

Pozostało 580 znaków

2014-08-22 16:44
1

Nie wiem jaki jest tego powód, ale już któryś raz z kolei zadawane jest mi pytanie, dlaczego sugerowany maksymalny rozmiar tekstowych i binarnych plików konfiguracyjnych jest taki mały; Jedni widzą w tym jakąś dziwną ułomność, inni dochodzą do wniosku, że oficjalna biblioteka nie poradzi sobie z większymi plikami;

Odpowiedź jest prosta - to sugerowany maksymalny romiar, a nie sztywny, po przekroczeniu którego komputer zapłonie...

Tak więc prostując dziwne mity i domysły trzeba jasno napisać, że maksymalny rozmiar plików konfiguracyjnych w obu formach nie jest ustalony - pliki mogą mieć teoretycznie dowolne rozmiary, bez względu na ich formę i przeznaczenie (samodzielne pliki lub wchodzące w skład systemów konfiguracyjnych);

Dlatego też wprowadziłem poprawkę w specyfikacji formatu, podciągając nieco sugerowane maksymalne rozmiary.


edytowany 1x, ostatnio: furious programming, 2017-07-16 17:27
Pokaż pozostałe 2 komentarze
Dodam jeszcze, że format zaprojektowałem do niedużych konfiguracji, więc jesli trzeba przechowywać ogromne ilości informacji, to lepiej skorzystać z nietekstowych mechanizmów, np. z baz danych; Pliki tekstowe nie nadają się do super-efektywnych zastosowań, bez względu na format; A skoro targetem z założenia mają być nieduże pliki, to API wykorzystuje DOM; A skoro wykorzystuje DOM, to głupotą było by tworzenie ogromnych plików, wbrew założeniom formatu; Dlatego też nie rozumiem dlaczego ktoś martwi się sugerowanymi limitami wagi plików; - furious programming 2014-09-11 14:36
Myślę, że to będzie najlepsze rozwiązanie, bo być może okaże się, że te sztucznie narzucone limity nijak nie mają się do faktycznej wydajności kodu i tylko sam sobie szkodzisz. - Bartosz Wójcik 2014-09-11 14:37
Ja już nie wiem jak mam Tobie to wytłumaczyć... Tobie też muszę tłumaczyć, co oznacza słowo "sugerowany"? Wydajność kodu jest mi znana, jego bezpieczeństwo też, szybkość parsowania jest wysoka - to sprawdzałem wielokrotnie; Nic sobie nie uroiłem - wykonałem setki testów każdej części API; A że oficjalnych wyników nie publikowałem, to ciągle jakieś dopowiedzenia widzę; Zrobię testy i je opublikuję, bo widzę, że nie będzie końca ciągłych pytań na temat "sugerowanych limitów"; Znajdę czas to zrobię testy - nie martw się o to ;) - furious programming 2014-09-11 14:44
Sugerowany na podstawie czego? Żadnych testów nie publikowałeś. Na oko? Na oko to chop zmarł :) - Bartosz Wójcik 2014-09-11 14:59
Sugerowany na podstawie założeń formatu, nie testów wydajnościowych; Po prostu - format ma służyć do niedużych konfiguracji, więc jakiś rozmiar trzeba było podać ;) - furious programming 2014-09-11 15:05

Pozostało 580 znaków

Odpowiedz
Liczba odpowiedzi na stronę

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0