„Alcinoe“ yra atvirojo kodo komponentų biblioteka, skirta „Delphi“ ir „C++Builder“, kurią portale „GitHub“ prižiūri naudotojas „Zeus64“. Ji apima sritis, kurias VCL ir „FireMonkey“ RTL palieka trečiosioms šalims: GPU paspartintą vaizdo grotuvą, WebRTC apvalkalą (wrapper), vietinius (native) „iOS“ ir „Android“ įvesties laukų valdiklius, dvigubo režimo JSON/BSON analizatorių, „MongoDB“ klientą su jungčių telkimu (connection pooling), „ImageMagick“ apvalkalą ir „FireMonkey“ valdiklių rinkinį, kuris visiškai aplenkia standartinį atvaizdavimo konvejerį. Biblioteka pelnė pripažinimą su „Rio“ (10.3.3) ir „Sydney“ (10.4.2) versijomis, o nuo to laiko buvo atnaujinama sulig kiekvienu „Embarcadero“ leidimu. Šio teksto rašymo metu ji yra visiškai suderinama su „Delphi 11.1 Alexandria“ ir „Delphi Athens 12.3.“
Alcinoe įtraukimas į projektą
Diegimas skiriasi priklausomai nuo vieno klausimo: ar jums reikia vizualinių „Alcinoe“ valdiklių palaikymo projektavimo metu (design-time)? Jei ne, visiškai praleiskite BPL. Pridėkite nuorodą {alcinoe_rootdir}\source prie projekto bibliotekų paieškos kelio (library search path) ir viskas. Kiekvienas nevizualinis komponentas, įskaitant analizatorius, duomenų bazių klientus ir eilučių pagalbines priemones, susikompiliuoja iš pirminio kodo nieko neregistruojant.
Kai jums reikia palaikymo projektavimo metu, kelias yra šiek tiek ilgesnis. „Delphi“ IDE atidarykite Component > Install Packages, susiraskite jūsų versiją atitinkantį BPL failą (pavyzdžiui, {alcinoe_rootdir}\lib\bpl\alcinoe\Win32\alexandria\Alcinoe_alexandria.bpl), įdiekite jį ir vis tiek pridėkite {alcinoe_rootdir}\source prie paieškos kelio. BPL įregistruoja komponentus, o pirminio kodo katalogas yra tai, ką kompiatorius randa kompiliuodamas jūsų projektą.
„Alcinoe“ pateikia pasirinktinius „Embarcadero“ RTL pirminio kodo pataisymus (patches). Jei norite juos pritaikyti, eikite į {alcinoe_rootdir}\embarcadero\, pasirinkite savo versijos pakatalogį ir paleiskite update.bat. Scenarijus tikisi, kad GIT yra sistemos kelyje (PATH), ir numato numatytąją „Embarcadero“ diegimo vietą. Jis atsisiunčia originalų RTL pirminį kodą ir pritaiko pataisas. Tai atlikę, pridėkite tą pataisytą pirminio kodo katalogą prie savo projekto paieškos kelio, kad kompiliatorius jį parinktų anksčiau nei tik skaitymui skirtą kopiją „Embarcadero“ diegimo medyje. Nieko iš to nereikia norint tiesiog pradėti; tai svarbu tik tuo atveju, jei susidursite su klaidomis, kurias ištaiso šie pataisymai.
Android ir D8 sintaksinio cukraus pašalinimo (desugaring) įgaliotasis serveris
Keli „Alcinoe“ komponentai (WebRTC, „ExoPlayer“ palaikomas vaizdas) priklauso nuo „Java“ bibliotekų, naudojančių „Java 8“ kalbos funkcijas. „Android“ įrankių rinkinys, pateikiamas su senesnėmis „Delphi“ versijomis, naudoja dx.bat failą DEX konvertavimui, kuris negali apdoroti šių baitinių kodų žemesniuose nei 26 API lygiuose. Sprendimas yra sintaksinio cukraus pašalinimas (desugaring), kurį D8 atlieka automatiškai, kai yra iškviečiamas tiesiogiai. „Alcinoe“ pateikia įgaliotąjį scenarijų adresu {alcinoe_rootdir}\tools\D8Proxy\dx.bat, kuris nukreipia iškvietimus iš „Delphi“ konstravimo sistemos į D8, todėl sintaksinio cukraus pašalinimas vyksta skaidriai. Pakeiskite originalų dx.bat failą savo „Android SDK“ „build-tools“ kataloge (paprastai C:\SDKs\android\build-tools\30.0.3\) šiuo įgaliotuoju failu. „Embarcadero“ stebėjo šią problemą pranešime RSP-24155; vėlesnės SDK įrankių versijos ją išsprendė tiesiogiai, oro patikrinkite, ar jūsų dabartiniam įrankių rinkiniui vis dar reikia šio sprendimo.
FireMonkey atvaizdavimo problema ir Alcinoe atsakymas
„FireMonkey“ numatytasis piešimo ciklas tampa kliūtimi sąsajose su intensyviu slinkimu. Vieno suapvalintų kampų TRectangle perpiešimas gali užtrukti apie 3 ms, nes standartinė realizacija perskaičiuoja kelią (path) kiekviename kadre. Kai matomi 20 tokių valdiklių, tai sudaro 60 ms vienam kadrui, o tai apriboja faktinį kadrų dažnį gerokai žemiau sklandaus slinkimo ribos.
„Alcinoe“ tai išsprendžia naudodama kiekvienam valdikliui GPU esantį buferį. Pirmojo piešimo metu valdiklis atvaizduojamas į GPU atmintyje saugomą TTexture. Vėlesni perpiešimai perkelia (blit) šią tekstūrą, užuot iš naujo vykdę piešimo algoritmą. Išmatuotas to paties suapvalinto stačiakampio rezultatas sumažėja nuo maždaug 3 ms iki maždaug 0,1 ms. Be buferizavimo, „Alcinoe“ pakeičia OpenGL kelio braižymą pagrindinėms figūroms vietinėmis „Android“ ir „iOS“ braižymo sąsajomis (API), taip išvengdama kokybės ir našumo kompromiso, susijusio su Form.Quality. Svarbūs valdikliai yra TALRectangle, TALCircle ir patobulintų išdėstymo konteinerių rinkinys, įskaitant ScrollBox ir TabControl.
TALJsonDocument: DOM ir SAX viename tipe
TALJsonDocument yra „Alcinoe“ JSON ir BSON analizatorius. Jis palaiko du apdorojimo režimus. DOM režimas sukuria objektų medį atmintyje, suteikdamas atsitiktinę prieigą prie bet kurio mazgo, tačiau sunaudodamas atminties kiekį, proporcingą dokumento dydžiui. SAX režimas sukelia įvykius, kai analizatorius nuskaito kiekvieną leksinį vienetą (token), neišsaugodamas jokio medžio – tai yra teisingas pasirinkimas, kai reikia filtruoti didelį dokumentą ir pasilikti tik kelias reikšmes. DOM analizatoriai „Delphi“ aplinkoje (DBXJSON, SuperObject ir kiti) paprastai yra nuo trijų iki penkių kartų lėtesni nei SAX metodas tam pačiam turiniui, nes kiekvienog mazgo išskyrimas sukelia objekto kūrimo sąnaudas, papildomai prie paties analizavimo darbo.
Šis tipas naudoja tą patį mazgų naršymo šabloną kaip ir TALXMLDocument. Minimalus DOM skaitymas atrodo taip:
MyJsonDoc.LoadFromJSON(AJsonStr, False {dom mode});
MyJsonDoc.ParseOptions := [poAllowComments];
// read scalar values
ShowMessage(MyJsonDoc.ChildNodes[‘name’].ChildNodes[‘first’].Text);
ShowMessage(IntToStr(MyJsonDoc.ChildNodes[‘_id’].Int32));
// iterate an array
for I := 0 to MyJsonDoc.ChildNodes[‘contribs’].ChildNodes.Count - 1 do
Writeln(MyJsonDoc.ChildNodes[‘contribs’].ChildNodes[I].Text);
SAX režimui priskirkite anoniminę procedūrą įvykiui OnParseText prieš kviesdami LoadFromJSON su antruoju argumentu, nustatytu į True. Atgalinis iškvietimas (callback) gauna mazgo kelią, pavadinimą, reikšmę ir TALJSONNodeSubType, kuris nurodo JSON tipą (eilutę, sveikąjį skaičių, slankiojo kablelio skaičių, loginę reikšmę ir t. t.). Šis režimas neišskiria atminties krūvoje (heap) mazgams, todėl jis tinka bet kokio dydžio dokumentams, neviršijant atminties biudžeto.
TALJsonDocument taip pat natūraliai skaito ir rašo BSON; perduokite True kaip BSON vėliavėlę į LoadFromFile arba SaveToFile. Antrasis variantas, TALJsonDocumentU, viduje naudoja UnicodeString (UTF-16) vietoj AnsiString (UTF-8) tais atvejais, kai aplinkinis kodas visur naudoja Unicode.
MongoDB klientas ir jungčių telkimas
„Alcinoe“ „MongoDB“ tvarkyklė apima įprastas užklausų operacijas ir pati atlieka jungčių telkimą. Paprastas klientas, TAlMongoDBClient, atidaro ir uždaro po vieną jungtį kiekvienai operacijai. Telkiamas variantas, TAlMongoDBConnectionPoolClient, palaiko aktyvių jungčių rinkinį ir išduoda po vieną jungtį kiekvienai besikreipiančiai gijai (thread) iš telkinio, o pabaigus darbą ją grąžina. Šis modelis neleidžia kelioms gijoms blokuoti viena kitos jungiantis prie duomenų bazės, o tai ypač svarbu, kai foniniai darbininkai (background workers) vienu metu teikia užklausas tai pačiai duomenų bazei. Stebimiems žymekliams (tailable cursors) riboto dydžio kolekcijose (capped collections) TAlMongoDBTailMonitoringThread stebi naujus dokumentus ir sukelia atgalinį iškvietimą jiems pasirodius – tai yra standartinis žurnalų srautinio perdavimo arba pakeitimų pranešimo be apklausos (polling) šablonas.
Kiti komponentai, kuriuos verta žinoti
ALVideoPlayer vaizdą atvaizduoja į TTexture, o ne į perdangos langą (overlay window), todėl kiti „FireMonkey“ valdikliai gali būti išdėstyti virš jo pagal Z tvarką (Z-order). „Android“ programinė dalis naudoja „ExoPlayer“, kuri prideda DASH, HLS ir „SmoothStreaming“ palaikymą, viršijantį tai, ką apdoroja integruotas „Android“ MediaPlayer. „iOS“ programinė dalis naudoja AVPlayer su lygiaverčiu HLS palaikymu.
TALWebRTC apgaubia WebRTC dėklą (stack), skirtą tiesioginiam (peer-to-peer) garso ir vaizdo perdavimui. Jam nereikia naršyklės ar papildinio, o ryšys kerta NAT per standartines ICE/STUN/TURN derybas, kurias apdoroja pagrindinė biblioteka.
TALStringList pakeičia TStringList rūšiavimą, pagrįstą AnsiCompareText, nuo lokalės nepriklausomu eiliškumo palyginimu ir greitojo rūšiavimo (quicksort) algoritmu, kuris dideliuose sąrašuose yra iki 10 kartų spartesnis. Maišos variantas, TALHashedStringList, prideda vidinę maišos lentelę O(1) paieškai, nedidelių sąrašų atveju reikalaujant šiek tiek didesnių pridėtinių sąnaudų. Atkreipkite dėmeses, kad TALStringList yra 8 bitų „AnsiString“ sąrašas, o ne „Unicode“ sąrašas; jis puikiai tinka serverio kodo kontekste, kur UTF-8 yra darbinis kodavimas ir žalia sparta yra svarbesnė už lokalės reikalavimus atitinkantį palyginimą.
64 bitų „Windows“ sistemoje „FastCode“ palikimas, suteikęs daugeliui „Alcinoe“ eilučių procedūrų greičio pranašumą (daugiausia ranka rašyta x86 asamblerio kalba), nepersikelia. Win64 versijos naudoja „Pascal“ realizacijas, kurios veikia pastebimai lėčiau atliekant daug eilučių apdorojimo reikalaujančias užduotis. Projektas demo\ALStringBenchMark leidžia išmatuoti šį skirtumą jūsų įrangoje prieš apsisprendžiant kurti 64 bitų versiją, kurioje eilučių pralaidumas gali tapti kliūtimi.
Visą pirminį kodą galima rasti adresu github.com/Zeus64/alcinoe.