Products



Stay in touch

Add your e-mail address here to receive the monthly TMS Software alerts.


    

Content:
Product releases
Product articles
Technical articles
Website changes
Software development

Products:

<< >>
August 2014



Tuesday, August 19, 2014

TMS XData v1.0 released

We're pleased to introduce today TMS XData, another important part in the TMS Business Subscription line-up of tools & components to let you write better & faster business logic for local, Windows-only, cross-platform and multi-tier solutions, in short, the entire spectrum of Delphi applications you can develop.

TMS XData is a full-featured Delphi framework that allows you to create HTTP/HTTPS servers that exposes TMS Aurelius, our Delphi ORM, objects through REST/JSON calls. With JSON being the defacto language for data communication via internet, these objects can be consumed by Delphi desktop or mobile clients but also any other client written in other languages.

TMS XData builds upon TMS Sparkle, the framework that offers classes for high performance HTTP/HTTPS client and server services for Windows, Mac-OSX, iOS, Android. TMS Sparkle is fully cross-platform but uses behind the scenes platform native APIs for the best possible performance.

To see how TMS XData can help you build multi-tier applications that consume TMS Aurelius ORM objects, suppose you have an Aurelius class mapped like the following.
[Entity, Automapping]
  TCustomer = class
  strict private
    FId: integer;
    FName: string;
    FTitle: string;
    FBirthday: TDateTime;
    FCountry: TCountry;
  public
    property Id: Integer read FId write FId;
    property Name: string read FName write FName;
    property Title: string read FTitle write FTitle;
    property Birthday: TDateTime read FDateTime write FDateTime;
    property Country: TCountry read FCountry write FCountry;
  end;
With just a few lines of code you can create an XData layer to expose those objects. Creating the XData HTTP server module is explained here. You could retrieve an existing TCustomer with id equals to 3 using the following HTTP request, for example:
GET /tms/xdata/Customer(3) HTTP/1.1
Host: server:2001
And the JSON representation the customer will be returned in the body of HTTP response:
{
  "$id": 1,
  "@xdata.type": "XData.Default.Customer",
  "Id": 3,
  "Name": "Maria Anders",
  "Title": "Sales Representative",
  "Birthday": "1980-05-20",
  "Country": null
}

You can perform changes to objects through the REST interface, using POST method to create new objects, DELETE to remove objects, and PUT or PATCH to update the objects. The following example will change the value of Title property of the customer resource specified in previous example:
PATCH /tms/xdata/Customer(1) HTTP/1.1
Host: server:2001
 
{ 
  "Title": "Marketing Manager" 
}
You can also perform queries on existing objects. The following example will retrieve all customers with country name equals to "USA", ordered by customer's name.
GET /tms/xdata/Customer?$filter=Country/Name eq 'USA'&$orderby=Name&$top=10 HTTP/1.1
Host: server:2001
And server will return with a JSON array of objects containing all the filtered objects. You can use query paging to restrict the number of objects returned in each request.

There is much more to explore in this exciting new framework. You can get started by downloading the trial version for Delphi XE2.. XE6 at http://www.tmssoftware.com/site/xdata.asp and check out the full documentation

Bookmarks: 

Bruno Fierens




This blog post has not received any comments yet.



Add a new comment:
Author:
Email:
  You will receive a confirmation mail with a link to validate your comment, so please use a valid email address.
Comment:
 
Change Image
Fill in the characters from the image above:
 

All fields are required.
 



Monday, June 02, 2014

Finding memory leaks in Delphi for iOS

Introduction

Delphi has a very high degree of compatibility between desktop and mobile code: with some little differences, code written for Win32 will run fine in iOS and Android.

Many of those differences are in strings, like not having UTF8 strings (which I hope they'll finally see the light and re-add some day), or having zero-based strings instead of 1-based (which if you are writing code for both mobile and desktop, and you are not into self infringed pain, you'll just want to make all strings 1-based by writing {$ZEROBASEDSTRINGS OFF} everywhere in your units).

But on this post I wanted to focus in what is probably the biggest difference between Delphi mobile and Delphi desktop: Automatic Reference Counting (ARC). As you will probably know, ARC is a "light" kind of garbage collection which works by keeping the number of objects which have a reference to another object. When the reference count drops to 0 (nobody is using the object), it is automatically destroyed. Most of the time ARC works fine and allows you to replace of thousands of lines like:

  Whatever := TWhatever.Create;
  try
     DoSomething(Whatever);
  finally
     Whatever.Free;
   end;

by simply
  DoSomething(TWhatever.Create);

Delphi will take care of destroying whatever for you when it is not used anymore, and generally this is a good thing (™), since in most cases the more work the compiler does for you the better. The compiler will never forget to free an object. But ARC comes with some disadvantages too: Not only it will be slower since it has to increase and decrease the reference counting of the objects in a thread safe way (most likely involving locks), but even worse, code that runs without leaks in "Classic Delphi" might start to leak when compiled with ARC.. This is a very serious problem, because it won't manifest itself immediately. The converted desktop code will work fine in mobile, but under the hood memory usage will grow continually until the app crashes because it runs out of memory. So we need a way to catch and fix those memory leaks.

ARC and Circular References

The problem with ARC is simple: Classes that directly or indirectly reference themselves (think in double linked lists, or any cache scheme where the main objects keep a reference to the cache, and the cache to the main object). In those cases you have a situation like the following:


"Parent" has 2 references (one from the root object which created it, the other from the child). Child has 1 reference from the parent. When we exit the method, "Parent" reference count will drop to 1 and child reference count will stay at 1 too. Neither parent or child will be destroyed, and they will leave forever happily ever after: each one of them keeping the other alive.

And note that even if you explicitly call Parent.Free, it still won't be destroyed. In ARC, Free just sets the object to nil, breaking the reference from Root to Parent and decreasing the reference count to 1, but the reference from the child will still be there, keeping the Parent alive. You would have to call Parent.DisposeOf to explicitly call the parent destructor, and in the parent destructor set Child to nil. Code that used to run fine in Desktop (where you call Parent.Free) stops working when you use it in ARC. And this is a problem. For this particular case, ARC not only didn't remove any existing leak, but it introduced one.

So how do we fix it?Delphi has a [WEAK] attribute that you can use to "break" those reference loops. By marking the child reference as weak, it won't count towards the parent's reference count.



With the [weak] reference now parent reference count will be 1 and not 2, and when the reference from root is broken, parent and child will be destroyed. And this should be enough theory for now: time to get our hands dirty with some real code.

Creating the memory leak

Let's start with two simple classes that reference themselves:
type
TChild = class;

TParent = class
  public
  FChild: TChild;
  constructor Create;
  destructor Destroy; override;
end;

TChild = class
  public
  FParent: TParent;
  constructor Create(const aParent: TParent);
  destructor Destroy; override;
end;

The classes do just the bare minimum: When you create a TParent it will create and keep a reference to a TChild, and the Child will keep a reference to its parent. Just to know when those classes are being destroyed, we'll add messages in the destructor:
{ TParent }

constructor TParent.Create;
begin
  FChild := TChild.Create(self);
end;

destructor TParent.Destroy;
begin
  ShowMessage('Parent destroyed!');
  inherited;
end;

{ TChild }

constructor TChild.Create(const aParent: TParent);
begin
  FParent := aParent;
end;

destructor TChild.Destroy;
begin
  ShowMessage('Child destroyed!');
  inherited;
end;
And finally, let's add a button on the form, and create an instance of the parent class:
procedure TForm1.Button1Click(Sender: TObject);
var
  Parent: TParent;
begin
  Parent := TParent.Create;
end;
Let's try and run the application. Launch it and press the button. If everything goes as expected, no message "Parent destroyed!" or "Child destroyed!" should appear. Even when we have ARC, Parent and Children aren't being destroyed.

If we aren't fully convinced yet, one way to verify it is to place a breakpoint under the Parent := TParent.Create line, and look at the reference count of the object:


As you can see, refcount is 2: One for the "Parent" variable and the other from the child. When we exit the method, refcount will go down to 1, but it will never be 0 and the object will never be destroyed.

So now the question is: How can we find leaks in a big project? We can't go logging all destructors and we can't check all the refcounts of all the objects. When writing Win32/Win64 code, we have an invaluable tool: FASTMM. Either by writing ReportMemoryLeaksOnShutdown := True; in your app startup code, or by using the full FASTMM debug options, you can easily find the objects that have leaked in your app.

But there is no FASTMM for iOS; iOS memory allocations requests go directly to the iOS memory allocator. One idea could be to target "Win32" for our mobile application and try to use our Win32 leak detection techniques there:



But alas, the "Win32" target doesn't have ARC, so no objects will be destroyed at all. We'll have to try a different approach: We'll try the native OSX tools instead. XCode comes with a very helpful tool not so helpfully named "Instruments", which can be used to profile and look at leaks in objective-C apps. Given that Delphi in OSX uses the same LLVM backend and Debug information as XCode, it would be expected that we can use the same tools as in XCode. And it turns out we can.

Finding the leak

First steps first, we'll start by launching Instruments. You can do it by launching XCode, then go to Menu->XCode->Open Developer Tool->Instruments:



Of course, once it opens you might want to keep it in the dock to be able to open it faster next time. While in this post we will be only showing how to find memory leaks, Instruments is a very powerful tool which includes a CPU profiler, memory diagnostics, I/O activity and much more. If you are doing serious iOS work, you are likely to spend a lot of time in Instruments.

You should be greeted by a screen similar to this one:



From here, we will select "iOS" at the left (Leak detection won't work in the iOS simulator), and then "Leaks" at the right. Once in the main Instruments screen, we need to choose the app to profile. We'll select the iOS device (again, leak detection won't work in the simulator) and then select our app from the "Choose target" menu inside the "Choose target" combobox:



In the short video below, I'll show how profiling the app looks like. I've marked some interesting parts on it:

1) Choose a target. This is where we select the app that we have previously deployed to the device. Make sure to deploy it in DEBUG mode so symbols are loaded.

2) Record. When we press "Record" the app starts in the device, and the profiler starts running. At first the "Allocations" profiler is selected, and while it has a lot of interesting information on its own, for this article we are interested in the leaks. So we select "Leaks" from the left sidebar.

3) Snapshot. On the lower left pane, we have the "Snapshots" section. By default it takes a memory snapshot every 10 seconds, but we can select the interval or manually trigger one. In this video we pressed the button on the device, then pressed the "Snapshot Now" button in Instruments, and a memory leak is shown. After that we pressed the button twice more, and then "Snapshot Now" again. You can see the leak count increases to 3. You can also see the red bars in timeline showing when the leaks where created.

4) Inspect the call stack. By pressing the button to show the right pane in Instruments, we can take a look at the stack trace that lead to the leak. You can see that even when this is a delphi app, the debug information is all there, and you can see the actual delphi class names like "TParent", and the method names like "Button1Click". This makes it really easy to pinpoint the troubling parts.

5)Inspect the cycles. Finally, we can also look at a view that is helpful to see the cycles. In this case the cycles are very simple so the diagram doesn't add much, but in a more complex case this can also help finding the element that is leaking.



Fixing the code

Now that we have find the offending code, the last step is to fix it. To do that, just add a [WEAK] attribute to the child reference to the parent.

The child class will end up as follows:

TChild = class
  public
  [Weak]FParent: TParent;
  constructor Create(const aParent: TParent);
  destructor Destroy; override;
end;


If we run the application now, we should finally be able to see the messages in the destructor:



And Instruments should show no cycles or leaks. Also if you debug the application and inspect the reference count for parent, it should never be 2.
Ok, I think this should be it. Have a happy leak hunting, and don't forget to explore the other "Instruments" available in "Instruments" like the allocation or cpu profilers. Most instruments work just fine with Delphi apps, and there are a couple of jewels waiting for you on there.

Bookmarks: 

Adrian Gallero




This blog post has received 1 comment.


1. Monday, June 02, 2014 at 6:27:18 PM

For more Information we have added in March 2013 a 30 Min Video also about Instruments and Delphi.

Perhaps helpful for more Informations :-)

https://www.youtube.com/watch?v=9s3iOML_0T4&list=UU8cmxRNEOaSxhFjf3oRzT1A

Daniel Magin




Add a new comment:
Author:
Email:
  You will receive a confirmation mail with a link to validate your comment, so please use a valid email address.
Comment:
 
Change Image
Fill in the characters from the image above:
 

All fields are required.
 



Monday, April 14, 2014

The story of a teenage scripter

Last week I was just browsing the TMS site, looking at the version numbers of existing products, when I saw TMS Scripter current version: 6.3. I see those numbers often and I’m used to them, but this time, I was a little bit shocked. Just like a father whose son is born and, in the blink of an eye, watches this son going to college in his eighteen, I was astonished to see how far TMS Scripter went, and for so long. It’s true that my oldest son is just about to turn 5 years-old, but for that my eyes didn’t even have to blink – they were wide open – so I can imagine how it might be for a father of a grown-up son. My second son is only 12 days old, and got me so worried last week to the point I went to the gym with a different tennis shoe in each foot and only noticed it when I came back home. I’m trying not to blink an eye. But I digress.

Thing is TMS Scripter is already a teenager. I have to face it. First version was released in 2001, but it was being already used in internal projects for at least three years. It’s interesting to see old family pictures, and the following one shows version 1.5 from November, 2001, when it was still called TatPascalScripter and had just a new featured added: COM interfaces support.



Since then, it had fourty-six – fourty-six! – releases, which added the following main features (in chronological order) that transformed TMS Scripter over the years:

  • Support for COM Interfaces
  • Basic Syntax
  • Delphi classes import tool
  • Debugger
  • Syntax highlight memo with breakpoints, etc.
  • Events support
  • Code completion
  • WebScripter
  • Watches
  • Thread support
  • Script-based libraries
  • DLL importing from script
  • Source explorer
  • Script-based forms
  • Complete IDE with form designer and object inspector
  • Automatic class import using new RTTI
  • Parameter hints
  • Script-based classes
  • Undo/Redo in form designer
  • Windows 64-bit support
  • Firemonkey Forms
  • Mac OS support


Besides, of course, constant language improvements, introduced over the releases, and support to all the new Delphi versions released, until the latest one, XE6, with no exception.

Over all those years and versions, full backward compatibility was kept, regression bugs were minimized and fixed, and I believe most of TMS Scripter users had a safe and peaceful life like, with full support and compatibility – including the famous migration from ANSI to UNICODE.

But what brings more satisfaction is to see the different way TMS Scripter affects many users. Yes, TMS customers are overall satisfied, enjoy the high number of features in our products, and appreciate the support we provide. But TMS Scripter is, of the products I manage, the one that receives more “emotional” comments. Users mention to be surprised every day with it, and comment how it constantly opens new doors in their applications. I believe one of the reasons for that is the fact that TMS Scripter is an “open” product, with so many different ways to use and applications, that it often requires (and allows) a great amount of creativity from its users, making them a kind of “artist” of their own software.

Yes, TMS Scripter is already a teenager. But more exciting things will come and its story doesn’t end here.


Bookmarks: 

Wagner Landgraf




This blog post has received 2 comments.


1. Friday, June 06, 2014 at 4:12:10 AM

When will the form designer and object inspector support firemonkey as VCL?

Zhong wenqing


2. Friday, June 06, 2014 at 8:36:22 AM

We don''t have a short-term plan for that. Scripting itself will work cross-platform, but currently, no plans for form designer/object inspector.

Wagner Landgraf




Add a new comment:
Author:
Email:
  You will receive a confirmation mail with a link to validate your comment, so please use a valid email address.
Comment:
 
Change Image
Fill in the characters from the image above:
 

All fields are required.
 



Monday, April 07, 2014

Hello, TMS Sparkle

TMS Sparkle is a brand new product released by TMS Software. It is a Delphi framework for network, Internet programming.

As stated in the online documentation, TMS Sparkle is the core building block for several other TMS products and technologies, such as upcoming TMS RemoteDB and TMS XData. Such products needed to be built from scratch, and to rely on a robust framework for which TMS could have 100% control and also responsibility. For such products to work flawlessly, we needed to be sure to build such products in a framework that must be properly tested, and have fast response in performance improvement and bug fixing.

It is trustworthy, fresh, modern, cross-platform (Windows, Mac, iOS, Android) and most of it, as much platform native as it can be.

TMS Sparkle is part of TMS Business Subscription, which contains many other products, like TMS Aurelius and TMS Scripter, and will also receive the mentioned upcoming products TMS RemoteDB and TMS XData.

For detailed information you can refer to TMS Sparkle product page and online documentation. In the meanwhile, to illustrate its usage, here is the full source code for a minimal Http Server using TMS Sparkle:

program HelloWorldServer;

{$APPTYPE CONSOLE}

uses
  System.SysUtils,
  Sparkle.HttpServer.Context,
  Sparkle.HttpServer.Module,
  Sparkle.HttpSys.Server;

type
  THelloWorldModule = class(THttpServerModule)
    public procedure ProcessRequest(const C: THttpServerContext); override;
  end;

procedure THelloWorldModule.ProcessRequest(const C: THttpServerContext);
begin
  C.Response.StatusCode := 200;
  C.Response.ContentType := 'text/plain';
  C.Response.Close(TEncoding.UTF8.GetBytes('Hello, World!'));
end;

const
  ServerUrl = 'http://localhost:2001/tms/business/hello';
var
  Server: THttpSysServer;
begin
  Server := THttpSysServer.Create;
  try
    Server.AddModule(THelloWorldModule.Create(ServerUrl));
    Server.Start;
    WriteLn('Hello World Server started at ' + ServerUrl);
    WriteLn('Press Enter to stop');
    ReadLn;
  finally
    Server.Free;
  end;
end.



Bookmarks: 

Wagner Landgraf




This blog post has received 2 comments.


1. Friday, June 06, 2014 at 9:30:30 AM

Bacana, bem legal e simples de se implementar requisições ao servidor. Remonta o tempo de implementação dos CGIs só que bem mais simples porque cada URI representa um classe/módulo no servidor, sendo prático a organização e clareza de codigo/manutenção uma vez que o todo o servidor é implementado em um único executável. Isso é bom por um lado, porém ao colocar novos recursos(módulos) há que se tirá-lo do ar e recolocá-lo. Interessante implementar em novas versões do Sparkle como uma opção alternativa, a colocação de novos módulos sem precisar retirá-lo do ar (DLLs talvez). O que é chamado de manutenção "on-the-fly". Mas parabéns pelo produto, gostei !

Claudio Ferreira


2. Friday, June 06, 2014 at 10:19:16 AM

Claudio, a arquitetura é aberta, nada impede de se usar dll''s. Dentro um módulo você pode fazer uma "subdivisão" e chamar funções de dll se for o caso. Nada impede também de você criar vários serviços diferentes (criar um outro servidor/executável sem parar o anterior). Mas estamos abertos a sugestões, se tiver algum exemplo específico, é só dizer. Pode enviar para o nosso e-mail (aba suporte) ou, se for usuário registrado, usar nosso fórum.

Wagner Landgraf




Add a new comment:
Author:
Email:
  You will receive a confirmation mail with a link to validate your comment, so please use a valid email address.
Comment:
 
Change Image
Fill in the characters from the image above:
 

All fields are required.
 



Thursday, February 06, 2014

Get device independent, put your settings in the iCloud

On the road, we carry a smartphone, in a couch we grab the tablet and in the office we sit behind the desk and use a desktop computer. In all scenarios though, we want to use applications that give us access to the same data and functions. Therefore, it is also logical that when we change our parameters for access to this data and functions via the desktop machine application, these same parameters and settings will be reflected (automatically) when we use the smartphone or tablet specific application and vice versa. In the Apple world, the answer to this scenario is persisting our parameters / settings on the iCloud.

As a Delphi developer, we typically like it when we can persist this information with a minimum amount of code so we can focus on the business logic instead of all technical complexities of using the iCloud. Delivering this promise, we've now released two new non-visual components: TTMSFMXNativeiCloud and TTMSFMXNativeMaciCloud. With these components, putting key/value pairs on the iCloud and retrieving them becomes as simple as using a method
 procedure AddKey(AKeyName: String; AKeyValue: TValue);
to create a key/value pair and using the property:
 
 property KeyValues[AKeyName: String]: TValue
to get and set the value of the key.

So, when in one application, the user would change a setting, this can be done with:
var
  FName: strring;

FName := 'TMS';
TMSFMXNativeiCloud.KeyValues['MyAmount'] := 1234;
TMSFMXNativeiCloud.KeyValues['MyName'] := FName;
Thanks to the magic of the iCloud and these non-visual components, the key/value pairs will now automagically be synchronised between applications on different devices coupled to the same iCloud account. If the app wants to react immediately to iCloud pushed value changes, the event TTMSFMXNativeiCloud.OnKeyUpdate is triggered and can be handled like:
procedure TMSFMXNativeiCloud.KeyUpdate(Sender: TObject; AKeyName: String; APreviousValue, ACurrentValue: TValue);
begin
   if (AKeyName = 'MyName') then
     FName := ACurrentValue;
end;
Note that the value is of the type TValue and supports strings, booleans, integers, double and a TMemoryStream. Of course, the component offers several more options like deleting a key/value pair, programmatically forcing a synchronisation of the values on the iCloud, receiving events when iCloud pushed updates to values etc...

TTMSFMXNativeiCloud is available now in the newest TMS iCL update and TTMSFMXNativeMaciCloud is available now in the newest TMS mCL. A FireMonkey iOS demo in TMS iCL and a FireMonkey Mac OS-X demo in TMS mCL demonstrate this concept by having a customizable set of key/value pairs shared via the iCloud between these applications as shown in the screenshot above.

Bookmarks: 

Bruno Fierens




This blog post has not received any comments yet.



Add a new comment:
Author:
Email:
  You will receive a confirmation mail with a link to validate your comment, so please use a valid email address.
Comment:
 
Change Image
Fill in the characters from the image above:
 

All fields are required.
 




Previous  |  Next  |  Index


Copyright © 1995 - 2014 TMS Software v4.0