RadPHP XE: A first look

RadPHP

I received my license for RAD Studio XE yesterday and I was quite excited to take a look at RadPHP XE. I had not formerly tried Delphi For PHP 1 and 2 and honnestly, I haden’t heard any good things about them either.

A first thing I noticed was that RadPHP does not come as a part of RAD Studio itself. Though the product does integrate into the IDE flawlessly, it is not accessible from RAD Studio itself, neither is it included in the RAD Studio installer. You have to download RadPHP separately and open it separately from the main RAD Studio IDE.

As advertised by Embarcadero, the RadPHP experience feels very much like working with Delphi, it uses the same layout, you create projects the same way etc. The most noticeable projects are the Facebook application and RPCL application. Both of these use the RadPhp Component Library.

When creating a new project some of the differences quickly become obvious. As expected your form designer does not show a form, rather a page, with the same grid layout. The tool palette has a fairly large selection of available components of which many look very familiar. However, this is the point some things started to disappoint me. Though Embarcadero has certainly succeeded at creating a very convenient way to create PHP applications, there’s several things I’m certainly missing. Components do not come with properties like Align, Anchors, Margins and more. A lot of innovative VCL features that were added after Delphi 7 like the ability to use imagelists for buttons are also nowhere to be found in RadPHP. Overall I would say, even though the experience is similar to working with Delphi, the product still has some issues that should be addressed.

RadPHP does seem to have some interesting features nonetheless, such as integration of several 3rd party APIs like Google Maps, the Facebook API, jQuery, etc… Though I would like to have seen some additional Google APIs in there. The product currently seems mostly targeted at the development of Facebook applications.

One thing I checked for was if it came with an OpenTools API like RAD Studio itself, and it does, so it is extensible, maybe we will see some interesting 3rd party tools appearing in the future.

A final thing worth mentioning is that none of the new tools added to RAD Studio such as BeyondCompare are not integrated into the RadPHP IDE, neither is the subversion integration. This may be the result of having installed RadPHP after RAD Studio, but I doubt that is the case.

Conclusion
After having a first look at RadPHP I would have to say it seems it was just added to RAD Studio to have an additional feature in the package. However, with some work it could become a very powerful development tool and hopefully it will in the future.

Read More

RAD Studio XE

I visited the launch event for RAD Studio XE in Brussels yesterday, we got a 4 hour presentation about the new features in RAD Studio XE including a set of demos and there was some very tasty Delphi Cake. The cake wasn’t a lie…

I’m going to give you a small summary of what’s new in RAD Studio XE.

What does XE stand for? It stands for Heterogeneous Embarcadero and Toolcloud Enabled. All Embarcadero products will now be named XE, next year RAD Studio 2012 will be named RAD Studio XE 2 and so on.

A lot of focus now goes out to the Embarcadero All-Access product which allows you to access all Embarcadero products instantly including older versions of the products for testing backwards compatibility of your code. All-Access allows you to run these products without installing them and they run using a sort of visualization technology so it’s completely sandboxed.

For the future Embarcadero plans to create a new Delphi compiler which will be more flexible and will be easier to adapt to other platforms. Aside from that they plan to create a new better VCL library, move EDN up to the next level using new modern technologies and more. The x64 and xPlatform support that was going to be in RAD Studio XE has been moved up to the next release because it simply was not ready for release, so that’s certainly something to look out for.

“We do not want to publish another Delphi 8.”

Embarcadero is currently also working on a “Starter” edition of RAD Studio/Delphi which will be free or available for a low price, targeting students and hobbyists.

Inside the IDE we find the new Subversion integration as one of the main new features. It allows you to easily add a project to subversion and work with it, the IDE will only commit files you actually need to have in your repository, being the source files, dfm files, etc… The entire subversion integration has been open-sourced in the open tools api which allows 3rd party developers to modify or even add support for other version control systems into the IDE, however this is not done by default as Subversion is the most popular version control system available today. Subversion support is available in all products in RAD Studio including Delphi Prism. Another addition is improved support for code formatting. The code formatting has been improved upon and now works with profiles which you can import/export so you can format on a project-basis. You can now also format an entire project at once. Command-line support for the formatter has now also been included. A small addition to the form designer is that you now have the ability to copy a form and paste an image of it in for example paint. A last addition that was discussed is the ability to rename threads in the threads debugging view.

The Delphi language itself has gotten no extra additions, only the VCL library has gotten a few improvements and generics have been tweaked further. Embarcadero has however put a lot of effort in making C++ Builder comply with the ISO standards for the language.

UML support in Delphi has been extended, most people do not use the UML integration, but it is quite extensive, it can automatically reverse engineer your project and create an UML diagram for it, you can also add classes and more to your project from the UML diagrams. You now have the ability to generate sequence diagrams of your code in UML which allows you to visually inspect how your code works. Aside from this you can now also easily add ancestors of your classes to the diagrams.

The main focus of the XE release is the DataSnap technology and the newly added support for cloud computing with Windows Azure and Amazon EC2. It is now possible to create DataSnap servers in C++ Builder. Clients can be created in Delphi, C++ Builder, RadPHP, and so on. Extra wizards to create web servers have also been added to the program and the REST protocol for communication between server and client. Furthermore the Windows Azure support is component based, which will allow you to easily interact with the Windows Azure cloud. The cloud computing support for Azure is also very powerful and will let you easily execute functions inside of your server that is running in the cloud from clients as if they were running locally.

I’ll be receiving my own copy of RAD Studio XE Professional in a few days and will share my thoughts about it then.

Read More

Delphi: FileSystem Searching

The windows api comes with several functions to search through files in a computer’s filesystem such as FindFirstFile, FindNextFile, … The RTL library in Delphi encapsulates these functions in 3 easy to use functions. These are FindFirst, FindNext and FindClose. Unlike what you may be used to from the win32 api, these functions return 0 not if something went wrong, but if they were successful. You have to pass the function a mask for the files, this consists out of a filemask to search in the current directory or a filemask including a folderpath. An example would be “c:\*”, this would return all files or folders in c:\ depending on what flags you pass to the FindFirst function. Note that the functions are not recursive, so they will only return the content of a folder and not it’s subfolders. The second parameter of the FindFirst function specifies flags that tell the functions what it is searching for. A few flags are faNormal, faHidden, faSysFile, faDirectory, … These can also be combined to select several types of files/directories. The following example shows you how to loop through all files and directories in the c:\ folder:

program FindTest;

{$APPTYPE CONSOLE}

uses
  SysUtils;

var
  sRec: TSearchRec;
begin
  if FindFirst('c:*', faNormal or faDirectory, sRec) = 0 then
  begin
    repeat
      WriteLn(sRec.Name + ' - ' + IntToStr(sRec.Size));
    until FindNext(sRec) <> 0;
    FindClose(sRec);
  end;
  ReadLn; // Prevent window from closing
end.

If you would for example change your mask to “c:\*.txt”, it would only return the txt files.

Some of you will also want to be able to recurse this, this can easily be achieved by setting it up in a recursive algoritm:

program FindTest;

{$APPTYPE CONSOLE}

uses
  SysUtils;

procedure RecurseFileSystem(const Folder, Mask: string);
var
  sRec: TSearchRec;
  t: string;
begin
  t := IncludeTrailingPathDelimiter(Folder);
  if FindFirst(t + Mask, faNormal or faDirectory, sRec) = 0 then
  begin
    repeat
      if ((sRec.Attr and faDirectory) <> 0) and (sRec.Name <> '.') and
        (sRec.Name <> '..') then
        RecurseFileSystem(t + sRec.Name, Mask)
      else
        WriteLn(t + sRec.Name + ' - ' + IntToStr(sRec.Size));
    until FindNext(sRec) <> 0;
    FindClose(sRec);
  end;
end;

begin
  RecurseFileSystem('c:', '*');
  ReadLn; // Prevent window from closing
end.

This example will loop through the entire filesystem on the c drive and show you all of the regular files including their path and size.

Read More

Delphi: Collections

Like Java and other languages, Delphi supports collections. This support was however only added after Delphi 7. You can find all of the included generic collection classes in the unit Generics.Collections. In this post I’ll show you 2 collectiontypes from the unit which are commonly used. You can use these in your applications to easily manage various types of data.

The TList class is an item collection which uses integer indices as keys for your collectionitems. The TList class allows you to perform any variety of actions on your collections such as inserting, deleting, moving and finding items. The TList class like all collection classes in the unit is a generic class, this means it’s not specific to a certain type, you have to bind it to a certain type while defining the instance of the collection. Any type can be used with these collections including basetypes. Here’s an example that stores and outputs integer values:

program CollectionsTest;

{$APPTYPE CONSOLE}

uses
  SysUtils, Generics.Collections;

var
  Items: TList<Integer>;
  i, l: Integer;
begin
  Items := TList<Integer>.Create;
  Items.Add(5);
  Items.Add(9);
  Items.Add(1);
  Items.Add(52);
  Items.Add(24);
  l := Items.Count;
  for i := 0 to l - 1 do
    WriteLn(Items[i]);
  Items.Free;
  ReadLn; // Prevent window from closing.
end.

The next collection type I would like to discuss is the dictionary. The dictionary collection is the same as a hashmap in Java. It uses hashes and lineair probing to find items, You can use many different types as a key to bind to your data, the most commonly used type for keys are strings. Here’s an example:

program CollectionsTest;

{$APPTYPE CONSOLE}

uses
  SysUtils, Generics.Collections;

var
  Items: TDictionary<string, string>;
  Enum: TDictionary<string, string>.TPairEnumerator;
begin
  Items := TDictionary<string, string>.Create;
  Items.Add('first', 'item1');
  Items.Add('second', 'item2');
  Items.Add('third', 'item3');
  Enum := Items.GetEnumerator;
  while Enum.MoveNext do
    WriteLn('Key: ' + Enum.Current.Key + ' - Value: ' + Enum.Current.Value);
  Items.Free;
  ReadLn; // Prevent window from closing.
end.

As you can see in this last example, collections also allow you to use various enumerators to access their data in a convenient way. Also take note that the TDictionary type does not keep the stored data in the order it was entered.

Read More

Delphi: FastShareMem

FastShareMem is a very lightweight memory manager for Delphi that was designed to replace the default memory manager that required the inclusion of a dll with applications. However, due to the addition of unicode support to Delphi 2009/2010, the include is no longer compatible with dlls compiled with older versions of Delphi using it. So I’ve written a copy that that will work in Delphi 2009/2010 and still is compatible with the older versions. Due take in mind this version of the include isn’t written for older versions of Delphi. For an older version use the original you can find here: http://www.codexterity.com/fastsharemem.htm

unit FastShareMem;

// By Frederic Hannes (http://ibeblog.com)
// Based on FastShareMem by Emil M. Santos (http://www.codexterity.com)

interface

var
  GetAllocMemCount: function: Integer;
  GetAllocMemSize: function: Integer;

implementation

uses Windows;

const
  ClassName = '_com.codexterity.fastsharemem.dataclass';

type
  TFastShareMem = record
    MemoryManager: TMemoryManagerEx;
    _GetAllocMemSize: function: Integer;
    _GetAllocMemCount: function: Integer;
  end;

function _GetAllocMemCount: Integer;
var
  State: TMemoryManagerState;
  i: Integer;
begin
  GetMemoryManagerState(State);
  Result := 0;
  for i := 0 to High(State.SmallBlockTypeStates) do
    Inc(Result, State.SmallBlockTypeStates[i].AllocatedBlockCount);
  Inc(Result, State.AllocatedMediumBlockCount + State.AllocatedLargeBlockCount);
end;

function _GetAllocMemSize: Integer;
var
  State: TMemoryManagerState;
  i: Integer;
begin
  GetMemoryManagerState(State);
  Result := 0;
  for i := 0 to High(State.SmallBlockTypeStates) do
    Inc(Result, State.SmallBlockTypeStates[i].AllocatedBlockCount *
      State.SmallBlockTypeStates[i].UseableBlockSize);
  Inc(Result, State.TotalAllocatedMediumBlockSize +
    State.TotalAllocatedLargeBlockSize);
end;

var
  wc: TWndClassA;
  IsHost: Boolean;
  ShareMem: TFastShareMem;

initialization
  if not GetClassInfoA(HInstance, ClassName, wc) then
  begin
    GetMemoryManager(ShareMem.MemoryManager);
    ShareMem._GetAllocMemCount := @_GetAllocMemCount;
    ShareMem._GetAllocMemSize := @_GetAllocMemSize;
    GetAllocMemCount := @_GetAllocMemCount;
    GetAllocMemSize := @_GetAllocMemSize;

    FillChar(wc, SizeOf(wc), 0);
    wc.lpszClassName := ClassName;
    wc.style := CS_GLOBALCLASS;
    wc.hInstance := HInstance;
    wc.lpfnWndProc := @ShareMem;

    if RegisterClassA(wc) = 0 then
    begin
      MessageBox(0, 'Shared Memory Allocator setup failed: Cannot register class.',
        'FastShareMem', 0);
      Halt;
    end;

    IsHost := True;
  end else begin
    SetMemoryManager(TFastShareMem(wc.lpfnWndProc^).MemoryManager);
    GetAllocMemCount := TFastShareMem(wc.lpfnWndProc^)._GetAllocMemCount;
    GetAllocMemSize := TFastShareMem(wc.lpfnWndProc^)._GetAllocMemSize;
    IsHost := False;
  end;
finalization
  if IsHost then
    UnregisterClassA(ClassName, HInstance);
end.

Read More

JNI For Delphi Preview

I’m currently developing a new modernized JNI wrapper for Delphi 2010 and up.  The old wrappers found here and here do work, but my wrapper requires less work to set up and uses a lot of new Delphi language features to ensure it works smoothly. The wrapper has been rewritten from scratch to include all features of JNI in JDK 1.6. Note that this wrapper is NOT backwards compatible with the old JNI wrappers, but switching to this one shouldn’t be too hard. At the moment the wrapper itself is far from complete, but it’s a preview including a small sample application. Afterwards I might also be wrapping JVMTI and create a bigger more user-friendly framework to encapsulate JNI. You can download the preview here: http://ibeblog.com/files/JNIForDelphi%200.1.rar

Read More

Delphi: Converting color values to HTML colors

Delphi uses a decimal representation for colors, the way these are built up is simply like integer values which means that in the memory the colors are stored not as RGB, but BGR. If we want to convert these color values to HTML hex colors, we need to take these into account as those are represented as RGB. Here are some methods to perform the conversion:

function ColorToHtml(const Color: Integer): AnsiString;
const
  Hex = '0123456789ABCDEF';
var
  b, s: Byte;
begin
  Result := '#';
  s := 0;
  repeat
    b := (Color shr s) and $FF;
    Result := Result + Hex[b div 16 + 1] + Hex[b mod 16 + 1];
    Inc(s, 8);
  until s = 24;
end;

function HtmlToColor(const Html: AnsiString): Integer;
const
  Hex = '0123456789ABCDEF';
var
  p, s: Byte;
begin
  Result := 0;
  s := 0;
  p := 1;
  if Html[1] = '#' then
    Inc(p);
  repeat
    Result := Result or (((Pos(Html[p], Hex) - 1) * 16 +
      Pos(Html[p + 1], Hex) - 1) shl s);
    Inc(p, 2);
    Inc(s, 8);
  until s = 24;
end;

Read More

Delphi <=> Java: Datatypes

So you know Delphi or Java and want to learn the other language? A very important thing to know is what datatypes you are using, as these differ in each language.

As you may know, Java does not have any unsigned datatypes, Delphi however has both signed and unsigned datatypes. Because of this the unsigned types are not listed in the table below, but in order for the integer types these are Byte/UInt8, Word/UInt16, Cardinal/LongWord/UInt32, UInt64. Delphi also has ansi strings/chars, these can be stores in string and Char but those can also hold unicode versions, the actual ansi types are AnsiString and AnsiChar. And of course Delphi also comes with a Pointer type as well as it has the ability to create types that hold pointers to specific types.

JavaDelphiTypeData
byteShortInt, Int88-bit signed integer-128 to 127
shortSmallInt, Int1616-bit signed integer-32768 to 32767
intInteger, LongInt, Int3232-bit signed integer-2147483648 to 2147483647
longInt6464-bit signed integer-9223372036854775808 to 9223372036854775807
floatSingle32-bit floating point value
doubleDouble64-bit floating point value
booleanBooleanboolean valuetrue or false
charChar (stores both ansi and unicode chars), WideChar, UnicodeChar16-bit unicode charactera single unicode character
Stringstring (stores both ansi and unicode strings), Widestring, UnicodeStringunicode stringa string consisting out of unicode characters
ObjectTObjectan objectobject pointer

Read More

RAD Studio XE Preview #3

Today Embarcadero released the 3rd and final preview of RAD Studio XE, the preview shows the new ability to generate DataSnap servers in C++ Builder, connectivity to DataSnap servers from C++ Builder, Delphi and RadPHP, the new support for Microsoft Azure cloud computing and more. I’m don’t use most of these technologies myself so I won’t go into detail about them.


Read More

Java: ShellSort

ShellSort is not a comparison-based sorting algorithm like those previously shown on this blog, it uses the property of InsertionSort that nearly sorted arrays of values are sorted very quickly. It has a performance of O(n log² n) which makes it a lot faster than a lot of other algorithms, certainly the O(n²) ones, but not entirely the fastest.

public static void shellSort(int[] ia) {
	int l = ia.length;
	if (l == 1)
		return;
	int inc = l / 2;
	while (inc != 0) {
		for (int i = inc; i != l; i++) {
			int t = ia[i];
			int j = i;
			while (j >= inc && ia[j - inc] > t) {
				ia[j] = ia[j - inc];
				j = j - inc;
			}
			ia[j] = t;
		}
		inc = (int) (inc / 2.2);
	}
}

Read More