Teknisk artikkel

Alcinoe og Delphi 11.1 Alexandria: Installasjon 11.1 Alexandria

Alcinoe er et åpen kildekode-komponentbibliotek for Delphi og C++Builder, vedlikeholdt på GitHub av Zeus64. Det dekker områder som VCL og FireMonkey RTL overlater til tredjeparter: en GPU-akselerert videospiller, en WebRTC-innpakning, opprinnelige iOS- og Android-redigeringskontroller, en dual-mode JSON/BSON-parser, en MongoDB-klient med tilkoblingspooling, en ImageMagick-innpakning, og en samling av FireMonkey-kontroller som omgår standard gjengivelsespipeline helt. Biblioteket bygde sitt rykte på Rio (10.3.3) og Sydney (10.4.2), og har siden sporet hver Embarcadero-utgivelse. I skrivende stund er det fullt kompatibelt med Delphi 11.1 Alexandria og Delphi Athens 12.3

Å få Alcinoe inn i et prosjekt

Installasjonen deles på ett spørsmål: trenger du designtidsstøtte for Alcinoes visuelle kontroller? Hvis ikke, hopp over BPL-en helt. Legg til {alcinoe_rootdir}\source i prosjektets biblioteksøkebane og du er ferdig. Hver ikke-visuelle komponent, inkludert parsere, databaseklienter og strengverktøy, kompileres fra kildekode uten å registrere noe

Når du trenger designtidsstøtte, er banen litt lengre. Åpne Component > Install Packages i Delphi-IDE-en, bla til BPL-en som samsvarer med versjonen din (for eksempel {alcinoe_rootdir}\lib\bpl\alcinoe\Win32\alexandria\Alcinoe_alexandria.bpl), installer den, og legg deretter fortsatt til {alcinoe_rootdir}\source i søkebanen. BPL-en registrerer komponentene; kildekatalogen er det kompilatoren finner når den kompilerer prosjektet ditt

Alcinoe leveres med valgfrie feilrettinger til Embarcadero RTL-kildene. Hvis du vil ha dem, naviger til {alcinoe_rootdir}\embarcadero\, velg underkatalogen for din versjon, og kjør update.bat. Skriptet forventer GIT i PATH og forutsetter en standard Embarcadero-installasjonsplassering. Det henter den opprinnelige RTL-kildekoden og anvender rettelsene. Når du er ferdig, legger du den korrigerte kildekatalogen til prosjektets søkebane slik at kompilatoren plukker den opp før den skrivebeskyttede kopien i Embarcadero-installasjonstreet. Ingenting av dette kreves for å komme i gang; det har bare betydning hvis du støter på feil som rettelsene adresserer

Android og D8 desugaring-proxyen

Flere Alcinoe-komponenter (WebRTC, ExoPlayer-støttet video) avhenger av Java-biblioteker som bruker Java 8-språkfunksjoner. Android-verktøykjeden som leveres med eldre Delphi-versjoner bruker dx.bat for DEX-konvertering, som ikke kan håndtere disse bytekodene på API-nivåer under 26. Løsningen er desugaring, som D8 håndterer automatisk når det påkalles direkte. Alcinoe gir et proxy-skript på {alcinoe_rootdir}\tools\D8Proxy\dx.bat som videresender anrop fra Delphi-byggesystemet til D8, noe som gjør desugaring transparent. Erstatt den opprinnelige dx.bat i din Android SDK build-tools-katalog (typisk C:\SDKs\android\build-tools\30.0.3\) med denne proxyen. Embarcadero sporet det underliggende problemet på RSP-24155; senere versjoner av SDK-verktøyene adresserte det direkte, så sjekk om din nåværende verktøykjede fortsatt trenger omveien

FireMonkey-gjengivelsesproblemet og Alcinoes svar

FireMonkeys standard tegnesyklus blir en flaskehals i rulle-tunge brukergrensesnitt. Et enkelt TRectangle med avrundede hjørner kan ta rundt 3 ms å tegne på nytt fordi standardimplementasjonen omberegner banen for hver ramme. Med 20 slike kontroller synlige, summeres det til 60 ms per rammepass, noe som begrenser den effektive bildefrekvensen godt under terskelen for flytende rulling

Alcinoe adresserer dette med en GPU-residerende buffer per kontroll. Den første tegningen gjengir kontrollen til en TTexture lagret i GPU-minne. Påfølgende nytegninger blitter den teksturen i stedet for å utføre tegnealgoritmen på nytt. Det målte resultatet på samme avrundede rektangel faller fra rundt 3 ms til rundt 0,1 ms. Utover bufringen erstatter Alcinoe OpenGL bane-tegning for grunnleggende former med opprinnelige Android- og iOS-tegne-API-er, og unngår avveiningen mellom kvalitet og ytelse knyttet til Form.Quality. De relevante kontrollene er TALRectangle, TALCircle og et sett med forbedrede layout-beholdere inkludert en ScrollBox og TabControl

TALJsonDocument: DOM og SAX i én type

TALJsonDocument er Alcinoes JSON- og BSON-parser. Den støtter to gjennomgangsmoduser. DOM-modus bygger et objekt-tre i minnet, noe som gir tilfeldig tilgang til enhver node på bekostning av minne proporsjonalt med dokumentets størrelse. SAX-modus fyrer av hendelser når parseren leser hver token uten å beholde noe tre, som er det riktige valget når du trenger å filtrere et stort dokument og bare holde et håndfull verdier. DOM-parsere i Delphi (DBXJSON, SuperObject og de andre) er vanligvis tre til fem ganger tregere enn en SAX-tilnærming for det samme innholdet, fordi hver node-allokering medfører objektopprettelses-overhead i tillegg til selve parsingsarbeidet

Typen følger samme node-navigeringsmønster som TALXMLDocument. En minimal DOM-lesning ser slik ut:

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);

For SAX-modus, tilordne en anonym prosedyre til OnParseText før du kaller LoadFromJSON med det andre argumentet satt til True. Tilbakekallet mottar nodestien, navnet, verdien og en TALJSONNodeSubType som identifiserer JSON-typen (streng, heltall, flyttall, boolsk, og så videre). Denne modusen produserer ingen heap-allokeringer for noder, så den skalerer til vilkårlig store dokumenter uten å sprenge minnebudsjettet

TALJsonDocument leser og skriver også BSON direkte; send True som BSON-flagg til LoadFromFile eller SaveToFile. En andre variant, TALJsonDocumentU, bruker UnicodeString (UTF-16) internt i stedet for AnsiString (UTF-8) for kontekster der den omkringliggende koden fungerer i Unicode tvers igjennom

MongoDB-klient og tilkoblingspooling

Alcinoes MongoDB-driver dekker de vanlige spørringsoperasjonene og håndterer tilkoblingspooling direkte. Den enkle klienten, TAlMongoDBClient, åpner og lukker én enkelt tilkobling per operasjon. Den poolede varianten, TAlMongoDBConnectionPoolClient, opprettholder et sett med aktive tilkoblinger og overleverer en til hver anropende tråd fra poolen, og returnerer den når anropet fullføres. Den modellen forhindrer at flere tråder blokkerer hverandre under tilkoblingsoppsett, noe som betyr noe når bakgrunnsarbeidere søker i den samme databasen samtidig. For tailable cursors på capped collections overvåker TAlMongoDBTailMonitoringThread for nye dokumenter og fyrer av et tilbakekall når de ankommer, som er standardmønsteret for loggstrømming eller endringsvarsling uten polling

Andre komponenter verdt å kjenne til

ALVideoPlayer gjengir video til en TTexture snarere enn et overleggsvindu, slik at andre FireMonkey-kontroller kan sitte over det i Z-rekkefølge. Android-bakenden bruker ExoPlayer, som legger til DASH, HLS og SmoothStreaming-støtte utover det Androids innebygde MediaPlayer håndterer. iOS-bakenden bruker AVPlayer med tilsvarende HLS-støtte

TALWebRTC pakker inn WebRTC-stakken for node-til-node lyd og video. Det krever ikke en nettleser eller en plugin, og tilkoblingen går gjennom NAT via den standard ICE/STUN/TURN-forhandlingen som det underliggende biblioteket håndterer

TALStringList erstatter TStringLists AnsiCompareText-baserte sortering med en lokalitets-uavhengig ordenssammenligning og en quicksort som er opptil 10x raskere på store lister. Den hashede varianten, TALHashedStringList, legger til en intern hashtabell for O(1)-oppslag på bekostning av litt høyere overhead på små lister. Merk at TALStringList er en 8-bits AnsiString-liste, ikke en Unicode-liste; den passer godt i kode på serversiden der UTF-8 er arbeidskodingen og rå gjennomstrømming betyr mer enn lokalitets-bevisst sammenligning

På 64-biters Windows overføres ikke FastCode-arven som ga mange av Alcinoes strengrutiner ytelsesfordelen deres (for det meste håndskrevet x86 assembly). Win64-byggene faller tilbake på Pascal-implementasjonene, som kjører merkbart tregere på strengintensive arbeidsbelastninger. demo\ALStringBenchMark-prosjektet lar deg måle gapet på maskinvaren din før du forplikter deg til et 64-biters bygg der strenggjennomstrømming er en flaskehals

Hele kildekoden er på github.com/Zeus64/alcinoe