Alcinoe Component Library, desarrollado por Zeus64, es una biblioteca de componentes visuales y no visuales de código abierto para Delphi.
Reproductor de video OpenGL completo, wrapper de WebRTC para Delphi, TEdit nativo para iOS/Android, controles FireMonkey mejorados, Firebase cloud messaging, inicio de sesión con el SDK de Facebook para Android/iOS, analizador Json/Bson, wrapper de ImageMagick, cliente de MongoDB.
Alcinoe es compatible con Delphi Rio 10.3.3 y Delphi Sydney 10.4.2.
https://github.com/Zeus64/alcinoe
Con Delphi Alexandria 11.1, se admite la descarga de MOD (eliminado).
Alcinoe ahora es totalmente compatible con Delphi Athens 12.3..
Instalar Alcinoe.
Si no planea usar ningún componente visual de Alcinoe en tiempo de diseño, entonces no necesita instalar nada, simplemente agregue {alcinoe_rootdir}\source a la ruta de búsqueda de su proyecto.
Si planea usar componentes visuales en tiempo de diseño, entonces necesita instalar el BPL. Abra Delphi y vaya a Componentes > Instalar paquetes... y elija el archivo BPL ubicado en {alcinoe_rootdir}\lib\bpl\alcinoe\Win32\sydney\Alcinoe_sydney.bpl (si está en Delphi Sydney, de lo contrario, elija el directorio que corresponda a su versión de Delphi). Aún necesita agregar {alcinoe_rootdir}\source a su ruta de búsqueda.
Alcinoe también mejora ligeramente los códigos fuente originales de Delphi. De esta manera, deberá ir a {alcinoe_rootdir}\embarcadero\sydney\10_4_2 y ejecutar update.bat para recuperar y aplicar los parches al código fuente original de Delphi. El archivo por lotes asume que el código fuente original se encuentra en "c:\Program Files (x86)\Embarcadero\Studio\21.0\source" y que tiene GIT en su ruta. Después de que el archivo por lotes se haya copiado y aplicado, deberá incluir este código fuente en la ruta de búsqueda de su proyecto.
Para finalizar, cada vez más bibliotecas utilizan funciones de Java 1.8 (como webRTC, exoplayer, etc.). De esta manera, debemos realizar la desazúcarización (La desazúcarización le permite usar estas funciones en dispositivos más antiguos reemplazando nuevos códigos de bytes y API de lenguaje con versiones más antiguas durante el proceso de compilación). Con d8.bat (reemplazo de dx.bat), la desazúcarización se activa de forma predeterminada. Por lo tanto, ahora puede usar la mayoría de los cambios de lenguaje más recientes mientras apunta a dispositivos más antiguos. A la espera de que Embarcadero cambie a D8.bat, debemos hacer que DX.bat sea un "proxy" para D8.bat. Para ello, simplemente reemplace su archivo DX.bat original (el mío se encuentra en c:\SDKs\android\build-tools\30.0.3\d8.bat) por el que se encuentra en {alcinoe_rootdir}\tools\D8Proxy\dx.bat. Más detalles aquí: https://quality.embarcadero.com/browse/RSP-24155
Reproductor de video OpenGL completo para FireMonkey.
ALVideoPlayer renderizará un video en una TEXTURA. Esto es realmente importante porque puede integrar completamente el video en el formulario de Delphi y puede colocar cualquier control que desee encima, ya que admite el orden Z. Los reproductores de video oficiales de Delphi son simplemente una ventana de reproductor de video nativa en la parte superior del formulario y, por lo tanto, no admiten el orden Z.
En Android, utilizo ExoPlayer. ExoPlayer admite funciones como la transmisión adaptativa dinámica a través de HTTP (DASH), HLS, SmoothStreaming y el cifrado común, que no son compatibles con MediaPlayer. Está diseñado para ser fácil de personalizar y ampliar. En iOS, utilizo AVPlayer, que también admite HLS, al igual que ExoPlayer.
reproductor de video para FireMonkey reproductor de video para FireMonkey reproductor de video para FireMonkey
Wrapper de WebRTC para Delphi.
WebRTC (Web Real-Time Communications) es una tecnología que permite a las aplicaciones y sitios web capturar y, opcionalmente, transmitir audio y/o video, así como intercambiar datos arbitrarios entre navegadores y aplicaciones móviles sin necesidad de un intermediario. El conjunto de estándares que comprende WebRTC permite compartir datos y realizar teleconferencias peer-to-peer, sin que el usuario tenga que instalar complementos ni ningún otro software de terceros.
El componente TALWebRTC facilita la incorporación de chat de video y audio en sus aplicaciones, lo que abre un mundo completamente nuevo de interactividad.
Wrapper de WebRTC para Delphi.
Controles nativos de iOS/Android TEdit y TMemo para FireMonkey.
La idea es combinar controles de FireMonkey con controles nativos de la plataforma cuando la implementación de la funcionalidad en dichos controles se vuelve muy difícil (como webbrowser, edit, memo, datepicker, etc.). Pero no se trata de crear varias formas distintas para varias plataformas, como ofrece, por ejemplo, http://www.turbococoa.com/ (aunque esta opción también es una buena alternativa en cierto modo, depende de usted decidir).
En Delphi (berlin), ya existe un control de plataforma de iOS que está bastante bien implementado, pero casi no hay controles de plataforma de Android, por lo que comencé a crear controles nativos de Android/iOS como TEdit/TMemo. Estos controles funcionan principalmente como ventanas que se colocan encima del formulario (por lo tanto, no hay orden z con los controles de FireMonkey).
Dibujo
Dibujo
Controles FireMonkey con búfer rápido/doble y renderizado nativo.
Rectángulo
Círculo
Texto (También se puede dibujar texto HTML en iOS/Android/Windows/macOS)
Glifo
etc.
TALRectangle
TALRectangle
El hecho
La pintura de los controles de FireMonkey a veces puede ser lenta, o dicho de otra manera, no lo suficientemente rápida para un desplazamiento fluido. Por ejemplo, si simplemente observas un TRectangle básico con esquinas redondeadas, el procedimiento de pintura puede tardar alrededor de 3 ms. Entonces, si tienes alrededor de 20 TRectangles visibles en tu pantalla, te costará alrededor de 60 ms repintar toda la pantalla (y normalmente no solo tienes TRectangle, también tienes TLabel, TCheckbox, etc.). Después, es solo cuestión de matemáticas: tarda 100 ms en repintar la pantalla, por lo que solo puedes obtener alrededor de 10 fotogramas por segundo (en realidad tendrás mucho menos), por lo que el desplazamiento no puede ser fluido 🙁
La solución
No quería reconstruir los controles de FireMonkey, es un trabajo demasiado grande para mí, y en su lugar, intenté encontrar una solución intermedia. Esto es lo que encontré al agregar una propiedad "de doble buffer" a los controles de FireMonkey. En lugar de repintar y repintar (y repintar) los controles para cada movimiento de píxel de la barra de desplazamiento, primero dibujo el control en un "buffer" que almaceno directamente en la memoria de la GPU (a través de TTexture), y cuando el sistema me pide que repinte los controles, en lugar de llamar nuevamente al algoritmo de pintura, simplemente redibujo el buffer TTexture.
Los resultados
Como dije antes, tardaba 3 ms solo en pintar un TRectangle simple con esquinas redondeadas. Con mi propiedad de doble buffer, ahora tarda alrededor de 0.1 ms. ¡Así que ahora el desplazamiento se ve mucho más fluido!
OpenGL draw => Reemplazado por el método de dibujo nativo de iOS/Android.
La mayoría de las formas básicas (como TRectangle, TCircle, etc.) utilizan OpenGL para el dibujo, lo cual no es muy eficiente; por ejemplo, para dibujar un círculo con OpenGL, en realidad se dibujan 50 triángulos. Esto a menudo resulta en una calidad deficiente: https://quality.embarcadero.com/browse/RSP-15206. Para roundrect, es aún peor porque primero se debe calcular la ruta y luego dibujarla (mucho más lento que TCircle).
Otro problema es que todos estos dibujos dependen de Form.quality. Si estableces form.quality en highquality, todo lo que hagas en el lienzo será multisample, como dibujar una imagen, lo que podría ser problemático porque la imagen tendrá antialiasing. Si estableces form.quality en highperformance, el dibujo será muy tosco (sin antialiasing).
Para resolver esto, he creado el buffer de mi control utilizando las API NATIVAS DE ANDROID/IOS. De esta manera, obtendremos un dibujo de alta calidad y a alta velocidad, sin depender de form.quality.
TALCircle
Controles FireMonkey mejorados.
ScrollBox
TabControl
RangeTrackBar
RangeTrackBar
reproductor de video para FireMonkey reproductor de video para FireMonkey reproductor de video para FireMonkey
Animación de confeti que cae
ALConfetti es una biblioteca de Delphi que permite crear animaciones de confeti que caen, con alto rendimiento y opciones de configuración.
confeti
Firebase cloud messaging
Un método multiplataforma para usar Firebase Cloud Messaging (FCM) para recibir notificaciones push. Con FCM, puede notificar a una aplicación cliente que hay nuevos correos electrónicos u otros datos disponibles para sincronizar. Puede enviar mensajes de notificación para fomentar la participación y la retención de usuarios. Para casos de uso como la mensajería instantánea, un mensaje puede transferir una carga útil de hasta 4 KB a una aplicación cliente.
Inicio de sesión con el SDK de VKontakte/Facebook para Android/iOS.
El SDK de VKontakte/Facebook para Android permite a los usuarios iniciar sesión en tu aplicación con VKontakte/Facebook Login. Al iniciar sesión con VKontakte/Facebook, los usuarios pueden otorgar permisos a tu aplicación para que puedas recuperar información o realizar acciones en VKontakte/Facebook en su nombre.
Filtros de editor de fotos para Android/iOS.
Con TALColorAdjustEffect, obtén hermosos filtros de fotos con una función de mejora automática con un solo toque, y haz que tus fotos sean hermosas y expresivas en cuestión de minutos.
Reproductor de video para FireMonkey.
Analizador JSON.
TALJsonDocument es un analizador/escritor de Delphi para el formato de datos JSON/BSON. Admite analizadores DOM y SAX (aunque un nombre mejor podría ser SAJ para Simple API for JSON en lugar de SAX para Simple API for XML, pero como el concepto de SAX es bien conocido, mantengo este nombre), admite el formato BSON y utiliza una sintaxis similar a TALXMLDocument/TXMLDocument. TALJsonDocument también puede exportar datos JSON/Bson en TALStringList.
Al tratar con el análisis de algún contenido (textual), generalmente se contemplan dos direcciones. En el mundo JSON, normalmente debes elegir entre:
Un analizador DOM, que crea una estructura de árbol en memoria de objetos que mapea el contenido JSON;
Un analizador SAX, que lee el contenido JSON y luego llama a eventos predefinidos para cada elemento del contenido JSON.
De hecho, los analizadores DOM utilizan internamente un analizador SAX para leer el contenido JSON. Por lo tanto, debido a la sobrecarga de la creación de objetos y la inicialización de sus propiedades, los analizadores DOM suelen ser de tres a cinco veces más lentos que los analizadores SAX (y utilizan mucha más memoria para almacenar todos los nodos). Sin embargo, los analizadores DOM son mucho más potentes para manejar los datos: tan pronto como se mapean en objetos nativos, el código puede acceder a cualquier nodo sin tiempo, mientras que un acceso basado en SAX tendrá que leer todo el contenido JSON nuevamente.
La mayoría de los analizadores JSON disponibles en Delphi utilizan un enfoque similar a DOM. Por ejemplo, la unidad DBXJSON incluida desde Delphi 2010 o la biblioteca SuperObject crean una instancia de clase que mapea cada nodo JSON. Para lograr la mejor velocidad, TALJsonDocument implementa un analizador DOM y también un analizador SAX.
TALJsonDocument también puede admitir comentarios dentro de la fuente JSON, lo cual es una extensión de las especificaciones JSON.
La sintaxis de TALJsonDocument es muy similar a TALXMLdocument / TXMLDocument.
TALJsonDocument está disponible en 2 variantes: TALJsonDocument, que se basa en ansiString (por lo tanto, UTF-8), y TALJsonDocumentU, que se basa en una cadena Unicode (por lo tanto, UTF-16).
Ejemplo:
{
_id: 1, // comentarios
name: { first: “John”, last: “Backus” },
birth: new Date('1999-10-21T21:04:54.234Z'),
contribs: [ “Fortran”, “ALGOL”, “Backus-Naur Form”, “FP” ],
awards: [
{ award: “National Medal of Science”,
year: 1975,
by: “National Science Foundation” },
{ award: "Turing Award",
year: 1977,
by: "ACM" }
],
spouse: "",
address: {},
phones: []
}
Para acceder a los nodos del documento:
MyJsonDoc.loadFromJson(AJsonStr, False);
MyJsonDoc.ParseOptions := [poAllowComments]; // para permitir comentarios dentro de la fuente JSON.
MyJsonDoc.childnodes['_id'].int32;
MyJsonDoc.childnodes['name'].childnodes['first'].text;
MyJsonDoc.childnodes['name'].childnodes['last'].text;
MyJsonDoc.childnodes['birth'].datetime;
for i := 0 to MyJsonDoc.childnodes['contribs'].ChildNodes.count – 1 do
MyJsonDoc.childnodes['contribs'].childnodes[i].text;
for i := 0 to MyJsonDoc.childnodes['awards'].ChildNodes.count – 1 do begin
MyJsonDoc.childnodes['awards'].childnodes[i].childnodes['award'].text;
MyJsonDoc.childnodes['awards'].childnodes[i].childnodes['year'].text;
MyJsonDoc.childnodes['awards'].childnodes[i].childnodes['by'].text;
end;
O, si no está seguro de la existencia de los nodos antes de acceder a ellos, o no desea verificarlos, también puede hacer lo siguiente:
MyJsonDoc.GetChildNodeValueInt32(' _id', 0{valor predeterminado si el nodo no existe});
MyJsonDoc.GetChildNodeValueText(['name', 'first'], ""{valor predeterminado si el nodo no existe});
MyJsonDoc.GetChildNodeValueDateTime('birth', Now{valor predeterminado si el nodo no existe});
Para crear los nodos del documento:
MyJsonDoc.addchild('_id').int32 := 1;
with MyJsonDoc.addchild('name', ntObject) do begin
addchild('first').text := 'John';
addchild('last').text := 'Backus';
end;
MyJsonDoc.addchild('birth').dateTime := Now;
with MyJsonDoc.addchild('contribs', ntArray) do begin
addchild.text := ‘Fortran’;
addchild.text := ‘ALGOL’;
addchild.text := ‘Backus-Naur Form’;
addchild.text := ‘FP’;
end;
with MyJsonDoc.addchild(‘awards’, ntArray) do begin
with addchild(ntObject) do begin
addchild(‘award’).text := ‘National Medal of Science’;
addchild('year').int32 := 1975;
addchild('by').text := 'National Science Foundation';
end;
with addchild(ntObject) do begin
addchild('award').text := 'Turing Award';
addchild('year').int32 := 1977;
addchild('by').text := 'ACM';
end;
end;
MyJsonDoc.addchild('spouse');
MyJsonDoc.addchild('address', ntObject);
MyJsonDoc.addchild('phones', ntArray);
También puede crear/actualizar nodos de esta manera:
MyJsonDoc.SetChildNodeValueInt32('_id', 0);
MyJsonDoc.SetChildNodeValueText(['name', 'first'], 'John');
MyJsonDoc.SetChildNodeValueDateTime('birth', Now);
Para cargar y guardar desde BSON:
MyJsonDoc.LoadFromFile(aBSONFileName, False{saxMode}, True{BSON});
MyJsonDoc.SaveToFile(aBSONFileName, False{saxMode}, True{BSON});
Para analizar un documento JSON en modo SAX:
MyJsonDoc.onParseText := procedure (Sender: TObject;
const Path: AnsiString;
const name: AnsiString;
const Args: array of const;
NodeSubType: TALJSONNodeSubType) -> NodeSubType: TALJSONNodeSubType)
begin
case NodeSubType of -> case NodeSubType of
nstFloat: Writeln(Path + ‘=’ + ALFloatToStr(Args[0].VExtended^, ALDefaultFormatSettings)); -> nstFloat: Writeln(Path + ‘=’ + ALFloatToStr(Args[0].VExtended^, ALDefaultFormatSettings));
nstText: Writeln(Path + ‘=’ + ansiString(Args[0].VAnsiString)); -> nstText: Writeln(Path + ‘=’ + ansiString(Args[0].VAnsiString));
nstObjectID: Writeln(Path + ‘=’ + ‘ObjectId(“‘+ALBinToHex(ansiString(Args[0].VAnsiString))+'”)’); -> nstObjectID: Writeln(Path + ‘=’ + ‘ObjectId(“‘+ALBinToHex(ansiString(Args[0].VAnsiString))+'”)’);
nstBoolean: Writeln(Path + ‘=’ + ALBoolToStr(Args[0].VBoolean,’true’,’false’)); -> nstBoolean: Writeln(Path + ‘=’ + ALBoolToStr(Args[0].VBoolean,’true’,’false’));
nstDateTime: Writeln(Path + ‘=’ + ALFormatDateTime(”’ISODate(“”yyyy”-”mm”-”dd”T”hh”:”nn”:”ss”.”zzz”Z”)”’, Args[0].VExtended^, ALDefaultFormatSettings)); -> nstDateTime: Writeln(Path + ‘=’ + ALFormatDateTime(”’ISODate(“”yyyy”-”mm”-”dd”T”hh”:”nn”:”ss”.”zzz”Z”)”’, Args[0].VExtended^, ALDefaultFormatSettings));
nstNull: Writeln(Path + ‘=’ + ‘null’);
nstRegEx: Writeln(Path + ‘=’ + ansiString(Args[0].VAnsiString));
nstBinary: Writeln(Path + ‘=’ + ‘BinData(‘+inttostr(Args[1].VInteger)+’, “‘+ansiString(ALBase64EncodeStringNoCRLF(ansiString(Args[0].VAnsiString)))+'”)’);
nstJavascript: Writeln(Path + ‘=’ + ansiString(Args[0].VAnsiString));
nstInt32: Writeln(Path + ‘=’ + ‘NumberInt(‘+inttostr(Args[0].VInteger)+’)’);
nstTimestamp: Writeln(Path + ‘=’ + ‘Timestamp(‘+inttostr(int64(cardinal(Args[0].VInteger)))+’, ‘+inttostr(int64(cardinal(Args[1].VInteger)))+’)’);
nstInt64: Writeln(Path + ‘=’ + ‘NumberLong(‘+inttostr(Args[0].VInt64^)+’)’);
end;
end;
MyJsonDoc.LoadFromJSON(AJsonStr, true{saxMode});
Wrapper de ImageMagick para Delphi.
Utilice ImageMagick® para crear, editar, componer o convertir imágenes de mapa de bits. Puede leer y escribir imágenes en una variedad de formatos (más de 200), incluidos PNG, JPEG, GIF, HEIC, TIFF, DPX, EXR, WebP, Postscript, PDF y SVG. Utilice ImageMagick para cambiar el tamaño, voltear, reflejar, rotar, distorsionar, sesgar y transformar imágenes, ajustar los colores de las imágenes, aplicar varios efectos especiales o dibujar texto, líneas, polígonos, elipses y curvas de Bézier.
Ejemplo:
var aWand: PMagickWand;
begin
//Crear la biblioteca ImageMagick.
alCreateImageMagickLibrary({alcinoe_rootdir} + ‘\lib\dll\imagemagick\win32\imagemagick’, min(2, System.CPUCount){aThreadLimit});
try
//crear el puntero wand
aWand := ALImageMagickLib.NewMagickWand;
try
//cargar la imagen
if ALImageMagickLib.MagickReadImage(aWand, pansiChar(aInputFilename)) <> MagickTrue then RaiseLastMagickWandError(aWand);
//establecer la calidad de compresión
si ALImageMagickLib.MagickSetImageCompressionQuality(aWand,80) <> MagickTrue entonces RaiseLastMagickWandError(aWand);
//ajusta automáticamente la imagen
si ALImageMagickLib.MagickAutoOrientImage(aWand) <> MagickTrue entonces RaiseLastMagickWandError(aWand);
//Redimensiona la imagen usando el filtro Lanczos
si ALImageMagickLib.MagickResizeImage(aWand, 640, 480, LanczosFilter) <> MagickTrue entonces RaiseLastMagickWandError(aWand);
//guarda la imagen
ALImageMagickLib.MagickWriteImage(aWand, pansiChar(aOutputFilename));
finally
ALImageMagickLib.DestroyMagickWand(aWand);
end;
finally
alFreeImageMagickLibrary;
end;
end;
Cliente de MongoDB
Cliente de Delphi para la base de datos MongoDB. Un controlador de Delphi (con pool de conexiones) para acceder a un servidor mongoDB. Un pool de conexiones es una caché de conexiones de base de datos que se mantiene para que las conexiones puedan reutilizarse cuando se requieran futuras solicitudes a la base de datos. En el pool de conexiones, después de que se crea una conexión, se coloca en el pool y se reutiliza para que no sea necesario establecer una nueva conexión. Si todas las conexiones están en uso, se crea una nueva conexión y se agrega al pool. El pool de conexiones también reduce el tiempo que un usuario debe esperar para establecer una conexión con la base de datos.
Ejemplo:
aJSONDoc := TALJSONDocument.create;
aMongoDBClient := TAlMongoDBClient.create;
try
aMongoDBClient.Connect("", 0);
aMongoDBClient.SelectData('test.exemple',
'{fieldA:123}', // la consulta
‘{fieldA:1, fieldB:1}’, // los campos de retorno
aJSONDoc.node);
aMongoDBClient.disconnect;
for i := 0 to aJSONDoc.node.childnodes.count – 1 do
with aJSONDoc.node.childnodes[i] do
writeln(aJSONDoc.node.childnodes[i].nodename + ‘=’ + aJSONDoc.node.childnodes[i].text)
finally
aMongoDBClient.free;
aJSONDoc.free;
end;
Ejemplo con pool de conexiones:
aMongoDBConnectionPoolClient := TAlMongoDBConnectionPoolClient.create(aDBHost, aDBPort);
try
::Thread1::
aMongoDBConnectionPoolClient.SelectData('test.example',
'{fieldA:123}', // la consulta
‘{fieldA:1, fieldB:1}’, // los campos de retorno
aLocalVarJSONDOC.node);
::Thread2::
aMongoDBConnectionPoolClient.SelectData('test.example',
'{fieldA:999}', // la consulta
‘{fieldA:1, fieldB:1}’, // los campos de retorno
aLocalVarJSONDOC.node);
finally
aMongoDBClient.free;
end;
Ejemplo de monitoreo de cola:
aMongoDBTailMonitoringThread := TAlMongoDBTailMonitoringThread.Create(
aDBHost,
aDBPort,
‘test.cappedCollectionExemple’
‘{}’, // la consulta
‘{fieldA:1, fieldB:1}’, // los campos de retorno
Procedimiento (Sender: TObject; JSONRowData: TALJSONNode)
begin
writeln('Nuevo elemento añadido en cappedCollectionExemple: ' + JSONRowData.childnodes['fieldA'].text);
end,
procedimiento (Sender: TObject; Error: Exception)
begin
writeln(Error.message);
end);
….
aMongoDBTailMonitoringThread.free;
Cliente WebSocket
Cliente WebSocket para Delphi implementado sobre WinHTTP. WebSocket es un protocolo de comunicación que permite abrir una sesión de comunicación interactiva bidireccional entre el navegador del usuario y un servidor. Con esto, puede enviar mensajes a un servidor y recibir respuestas basadas en eventos sin tener que consultar al servidor para obtener una respuesta.
TStringList rápido
TALStringList funciona igual que TStringList de Delphi, excepto que permite buscar un nombre=valor utilizando un algoritmo de ordenamiento rápido cuando la lista está ordenada. Además, TALStringList utiliza un algoritmo independiente de la configuración regional (basado en el valor ordinal de 8 bits de cada carácter) en lugar de AnsiCompareText y AnsiCompareStr utilizados por el TStringList de Delphi. Finalmente, el ordenamiento en TALStringList es hasta 10 veces más rápido que en TStringList de Delphi. Además, TALStringList no es un TStringList Unicode, sino una lista de cadenas Ansi 100%.
TALNVStringList (NV para NombreValor) es igual a TALStringList (también utiliza un algoritmo de ordenamiento rápido), excepto que aquí la optimización está orientada a una lista de nombre/valor en lugar de una lista de cadenas.
TALHashedStringList TALHashedStringList es igual a TALStringList, excepto que utiliza una tabla hash interna en lugar de un algoritmo de ordenamiento rápido. Al utilizar TALHashedStringList en lugar de TALStringList, puede mejorar el rendimiento cuando la lista contiene una gran cantidad de cadenas (de lo contrario, si su lista no contiene muchas cadenas, el rendimiento es menor que TALStringList debido al costo de calcular el hash).
Ejecutor de PHP
ALPHPRunnerEngine es un componente simple pero útil para usar fácilmente PHP (cualquier versión) como lenguaje de scripting en aplicaciones de Delphi. ALPHPRunnerEngine permite ejecutar scripts de PHP dentro del programa de Delphi sin un servidor web. ALPHPRunnerEngine utiliza la interfaz CGI/FastCGI de PHP (php-cgi.exe) para comunicarse con el motor de PHP.
Cliente de Memcached.
Cliente de Delphi para la base de datos memcached.
¿Qué es Memcached? Es un sistema de caché de objetos en memoria, de código abierto y de alto rendimiento, genérico en su naturaleza, pero diseñado para acelerar las aplicaciones web dinámicas al reducir la carga de la base de datos.
Memcached es un almacén de pares clave-valor en memoria para pequeñas cantidades de datos arbitrarios (cadenas, objetos) provenientes de llamadas a bases de datos, llamadas a API o renderizado de páginas.
Memcached es simple pero potente. Su diseño simple promueve una implementación rápida, facilidad de desarrollo y resuelve muchos problemas que enfrentan las grandes cachés de datos.
Componente GSM.
El componente TAlGSMComm implementa el envío de mensajes SMS a través de la interfaz de texto definida en la especificación técnica GSM 07.05, versión 5.1.0, fechada en diciembre de 1996. Existen varias variaciones de esta especificación, utilizadas en modelos de Nokia, Siemens, Ericsson, etc. Hemos probado internamente el Nokia 6230, pero los modelos Nokia 7190, 8890, 6210 y 9110 también deberían funcionar. Los teléfonos de otros fabricantes también funcionarán, siempre y cuando implementen la interfaz de texto. Aproximadamente 1/4 de los teléfonos actuales son capaces de conectarse a una PC (a través de IR o cable serial), aproximadamente 1/3 de esos son solo de modo texto, 1/3 son solo de modo PDU y el otro 1/3 admiten tanto el modo texto como el modo PDU. Algunos teléfonos (como el Nokia 5190) admiten SMS, pero utilizan un protocolo propietario, que TALGSMComm no admite.
Para probar su teléfono, conéctelo a su PC mediante el cable serial o el dispositivo IR (consulte la documentación de su teléfono para obtener detalles sobre cómo conectarlo). Introduzca "AT" en una ventana de terminal para verificar que la conexión se haya establecido (debería recibir "OK" del teléfono), luego introduzca "AT+CMGF=?". La respuesta debe contener un "1", lo que indica que admite el modo de texto. Si ambas pruebas se aprueban, entonces su teléfono cumple con los requisitos básicos.
Cliente de SQLite3
Consulta la base de datos de Sqlite3 y obtén el resultado en formato XML o en formato JSON/BSON.
Y mucho más.
Ejecutor CGI
Cliente HTTP (WinInet/WinHTTP)
Cliente de MySQL
Cliente NNTP
Cliente POP3
Cliente SMTP
Analizador XML
WIN64
Lamentablemente, en win64, perdimos toda la herencia de FastCode (que se basaba principalmente en ensamblador). Esto significa que la mayoría de las funciones serán de 2 a 10 veces más lentas. Puede intentar ejecutar /demo/ALStringBenchMark/ en win64 y Win32 para ver la diferencia de velocidad.