Beruflich Dokumente
Kultur Dokumente
BLAISE PASCAL
PASCAL MAGAZINE
MAGAZINE
D E L P H I, L A Z A R U S, O X Y G E N E, S M A R T M O B I L E,
A N D P A S C AL
A N D R O I D, I O S,
R E L A T E D
M A C,
L A N G U A G E S
W I N D O W S & L I N U X
40
D E L P H I - S T E P H E N B A L L
- I N T E R B A S E C H A N G E V I E W S
D E L P H I XE 8 - P A W E L G L O W A C K I
- I N T R O D U C T I O N T O F L A T B O X 2D
D E L P H I - D E T L E F O V E R B E E K
F R O M D E L P H I T O D E L P H I
W H Y T H E N A M E D E L P H I
D E L P H I - C A R Y J E N S E N - C L I E N T D A T A S E T S
A N D FD M E M T A B L E S C O M P A R E D: P A R T 2
S T A R T W I T H F U N C T I O N T E S T I N G (M A X B O X)
- M A X K L E I N E R
D E L P H I - J E R E M Y N O R T H
W O R K I N G W I T H B E A C O N S I N D E L P H I XE 8
P R I N T E D I S S U E P R I C E 1 5, 0 0
D O W N L O A D I S S U E P R I C E 5, 0 0
BLAISE
BLAISE PASCAL MAGAZINE 40
PASCAL MAGAZINE
D E L P H I, L A Z A R U S, S M A R T M O B I L E S T U D I O,
A N D P A S C A L R E L A T E D L A N G U A G E S
F O R A N D R O I D, I O S, M A C, W I N D O W S & L I N U X
CONTENTS
Articles
MOTION
BLAISE
BLAISE PASCAL
PASCAL MAGAZINE
MAGAZINE
Advertisers
Barnsten 11
BetterOffice 36
BLAISE PASCAL MAGAZINE 4
Cary Jensen (Jensen Data Sytems) 30
Components 4 Developers 48
Computer Math & Games 4
Daniel Teti 12
FAST REPORT 22/23
Raize Software 39 Publisher: Foundation for Supporting the Pascal Programming Language
in collaboration with the Dutch Pascal User Group (Pascal Gebruikers Groep)
Visuino MITOV 45 Stichting Ondersteuning Programmeertaal Pascal
Kim Madsen
www.component4developers
Please note: extra space characters have been deliberately added around the @ symbol in
these email addresses, which need to be removed if you use them.
editor @ blaisepascal.eu
Authors - Christian name in alphabethical order
A Alexander Alexeev, L Wagner R. Landgraf, Sergey Lyubeznyy
B Stephen Ball, Peter Bijlsma, Dmitry Boyarintsev K Max Kleiner
C Michal Van Canneyt, Marco Cant, M Kim Madsen, Felipe Monteiro de Cavalho
D David Dirkse, Daniele Teti N Jeremy North,
F Bruno Fierens O Tim Opsteeg, Inoussa Ouedraogo
G Primo Gabrijeli, Mattias Gaertner P Howard Page-Clark,
H Fikret Hasovic S Rik Smit, Bob Swart,
J Cary Jensen Z Siegfried Zuhr
Editor - in - chief
Detlef D. Overbeek, Netherlands Tel.: +31 (0)30 890.66.44 / Mobile: +31 (0)6 21.23.62.68
News and Press Releases email only to editor@blaisepascal.eu
Editors
Peter Bijlsma, W. (Wim) van Ingen Schenau, Rik Smit,
Correctors
Howard Page-Clark, James D. Duff
Trademarks
All trademarks used are acknowledged as the property of their respective owners.
Caveat Whilst we endeavour to ensure that what is published in the magazine is correct, we cannot accept responsibility for any errors or omissions.
If you notice something which may be incorrect, please contact the Editor and we will publish a correction where relevant.
Subscriptions ( 2013 prices )
1: Printed version: subscription 65.-- Incl. VAT 6 % (including code, programs and printed magazine,
10 issues per year excluding postage).
2: Electronic - non printed subscription 45.-- Incl. VAT 21% (including code, programs and download magazine)
Subscriptions can be taken out online at www.blaisepascal.eu or by written order, or by sending an email to office@blaisepascal.eu
Subscriptions can start at any date. All issues published in the calendar year of the subscription will be sent as well.
Subscriptions run 365 days. Subscriptions will not be prolonged without notice. Receipt of payment will be sent by email.
Subscriptions can be paid by sending the payment to:
ABN AMRO Bank Account no. 44 19 60 863 or by credit card: Paypal
Name: Pro Pascal Foundation-Foundation for Supporting the Pascal Programming Language (Stichting Ondersteuning Programeertaal Pascal)
IBAN: NL82 ABNA 0441960863 BIC ABNANL2A VAT no.: 81 42 54 147 (Stichting Programmeertaal Pascal)
Subscription department Edelstenenbaan 21 / 3402 XA IJsselstein, The Netherlands / Tel.: + 31 (0) 30 890.66.44 / Mobile: + 31 (0) 6 21.23.62.68
office@blaisepascal.eu
Copyright notice
All material published in Blaise Pascal is copyright SOPP Stichting Ondersteuning Programeertaal Pascal unless otherwise noted and may
not be copied, distributed or republished without written permission. Authors agree that code associated with their articles will be made
available to subscribers after publication by placing it on the website of the PGG for download, and that articles and code will be placed on
distributable data storage media. Use of program listings by subscribers for research and study purposes is allowed, but not for commercial
purposes. Commercial use of program listings and code is prohibited without the written permission of the author.
procedure ;
var
begin
for i := 1 to 9 do
begin
end;
end;
6
Issue Nr 2 2015 BLAISE PASCAL MAGAZINE 7
OVERVIEW OF DELPHI TO DELPHI HISTORY
DELPHI XE8
On February 8, 2006 Borland announced that it was looking for a
buyer for its IDE and database line of products, including Delphi, to
concentrate on its ALM line. On November 14, 2006 Borland transferred
the development tools group to an independent subsidiary company
named CodeGear, instead of selling it. Borland sold CodeGear to
Embarcadero Technologies in 2008.
Embarcadero Technologies in 2008. Embarcadero retained the
CodeGear division created by Borland to identify its tool and database Codegear Delphi 2007.
offerings, but identified its own database tools under the DatabaseGear
DELPHI 7 released in August 2002
DELPHI
released February 14, 1995
The roots of Turbo Pascal v1.0 started in Denmark.
The first step, in 1981, was the Blue Label Software Pascal Compiler Turbo Pascal
- BLS Pascal Compiler v1.2, copyright 1981 by Poly-Data microcenter ApS, Developer(s) Anders Hejlsberg while
Strandboulvarden 63, DK 2100 Copenhagen - working at Borland
written by Anders Hejlsberg for the NASCOM kit computer. Operating system CP/M, CP/M-86, DOS,
Windows 3.x, Macintosh
Lisa - Pascal was a Pascal implementation for the Apple Lisa workstation. Platform 8080/Z80, 8085, x86
It was an extension of the earlier Apple Pascal for Apple II machines,
but generated object code for 68000 processors that had to be linked
against the required libraries in the Lisa OS workshop. Windows
Lisa Pascal laid the foundation for the development of Clascal and Mac Pascal
the first implementations of Object Pascal.
Archimedes Mathematician
Roman Empire 700 BC
Archimedes of Syracuse was an Ancient
Greek mathematician, physicist, engineer,
inventor, and astronomer.
He is regarded as one of the leading scientists
in classical antiquity. Wikipedia
Born: 287 - 212 BC, Syracuse, Italy
Euclid Mathematician
Born Mid-4th century BC - 3rd century BC
Residence Alexandria, Hellenistic Egypt
Fields Mathematics Known for
Euclidean geometry / Euclid's Elements
Euclidean algorithm
Pythagoras Philosopher
Thales Philosopher
Thales of Miletus was a pre-Socratic Greek philosopher Difference Engine No. 1, portion,1832
from Miletus in Asia Minor and one of the
Seven Sages of Greece. Many, most notably Aristotle,
regard him as the first philosopher in the Greek tradition.
Born: 624 BC - 546
DELPHI
The cult of Apollo at
You can enlarge this yourself to view the information in greater detail.
Delphi probably
dates back to
the 700s B . C .,
Our authors plan to address each section of this timeline in future magazine articles.
WATER CLOCK - CHINA - BEGINNING OF TIME (BC 4000)
Some authors claim that water clocks appeared in China
as early as 4000 BC
Babbage Difference Engine No. 2
OVERVIEW OF DELPHI TO DELPHI HISTORY
DELPHI XE8
On February 8, 2006 Borland announced that it was
looking for a buyer for its IDE and database line of products,
including Delphi, to concentrate on its ALM line. On November
14, 2006 Borland transferred the development tools group to
Embarcadero Technologies in 2008.
an independent subsidiary company named CodeGear,
instead of selling it. Borland sold CodeGear to Embarcadero Codegear Delphi 2007.
Technologies in 2008. Embarcadero retained the CodeGear DELPHI 7 released in August 2002
division created by Borland to identify its tool and database
offerings, but identified its own database tools under the
DatabaseGear name. DELPHI
The roots of Turbo Pascal v1.0 started in Denmark. The first step,
released February 14, 1995
in 1981, was the Blue Label Software Pascal Compiler - BLS Pascal Turbo Pascal
Compiler v1.2, copyright 1981 by Poly-Data microcenter ApS, Developer(s) Anders Hejlsberg while
Strandboulvarden 63, DK 2100 Copenhagen - written by Anders working at Borland
Hejlsberg for the NASCOM kit computer. Operating system CP/M, CP/M-86, DOS,
Windows 3.x, Macintosh
Lisa - Pascal was a Pascal implementation for the Apple Lisa workstation. Platform 8080/Z80, 8085, x86
It was an extension of the earlier Apple Pascal for Apple II machines,
but generated object code for 68000 processors that had to be linked
against the required libraries in the Lisa OS workshop. Windows
Lisa Pascal laid the foundation for the development of Clascal and Mac Pascal
the first implementations of Object Pascal.
Archimedes Mathematician
Roman Empire 700 BC
Archimedes of Syracuse was an Ancient
Greek mathematician, physicist, engineer,
inventor, and astronomer.
He is regarded as one of the leading scientists
in classical antiquity. Wikipedia
Born: 287 - 212 BC, Syracuse, Italy
Euclid Mathematician
Born Mid-4th century BC - 3rd century BC
Residence Alexandria, Hellenistic Egypt
Fields Mathematics Known for
Euclidean geometry / Euclid's Elements
Euclidean algorithm
Pythagoras Philosopher
Pythagoras of Samos was an
Ionian Greek philosopher, mathematician,
and founder of the religious movement
called Pythagoreanism.
Born: 571 - 495 BC,
Thales Philosopher
Thales of Miletus was a pre-Socratic Greek philosopher Difference Engine No. 1, portion,1832
from Miletus in Asia Minor and one of the
Seven Sages of Greece. Many, most notably Aristotle,
regard him as the first philosopher in the Greek tradition.
Born: 624 BC - 546
DELPHI
The cult of Apollo at
Delphi probably
dates back to
the 700s B . C .,
Delphi Cookbook
HOICE A
SC
50 hands-on recipes to master the power of Delphi for R BLAISE
M
TO
AZING
cross-platform and mobile development on Windows, PASCAL
DI
Mac OS X, Android, and iOS MAGAZINE
E
Daniele Teti
is both an archaeological site and a modern town Others relate that it was named Pytho and that
in Greece on the south-western spur of Mount Pythia, the priestess serving as the oracle, was
Parnassus in the valley of Phocis. In myths chosen from their ranks by a group of priestesses
dating to the classical period of Ancient Greece who officiated at the temple.
(510-323 BC), the site of Delphi was believed to Apollo's sacred precinct in Delphi was a
be determined by Zeus when he sought to find panhellenic sanctuary, where every four years,
the centre of his "Grandmother Earth" (Ge, Gaea, starting in 586 BC athletes from all over the Greek
or Gaia). He sent two eagles flying from the world competed in the Pythian Games, one of the
eastern and western extremities, and the path of four panhellenic (or stephanitic) games, precursors
the eagles crossed over Delphi where the of the Modern Olympics. The victors at Delphi
omphalos, or navel of Gaia was found. were presented with a laurel crown (stephanos)
which was ceremonially cut from a tree by a boy
who re-enacted the slaying of the Python. Delphi
was set apart from the other games sites because it
hosted the mousikos agon, musical competitions.
Borland (for a time Inprise), was the company How do you talk to an oracle?
that first developed Delphi. It later moved "The oracle at Delphi" was the word association
Delphi development to its CodeGear division, that occurred to Danny Thorpe during one of
which was acquired by Embarcadero many conversations in Gary's office about the
Technologies in 2008. Embarcadero continues to best codename.
develop the Delphi XE product line.
His suggestion wasn't an instant hit. It's an old
Borland considered that name, an old place, a pagan temple in the ruins
a new product codename of a dead civilization. Not exactly an inspiring
should have no obvious association for a new product! As some press
connection to the product, articles later noted, the Delphic Oracle was
so that if an eavesdropper famous for giving out cryptic or ambiguous
overheard the name in answers - not a great association for a data
conversation it would be management tool. Asking a question of the oracle
unclear which product was free to all, but having the oracle's answer
was being discussed. interpreted cost the enquirer many drachmas
One of the most memorable (although the marketing guys liked that part).
product codenames coined
at the company was Buddha (the insiders' Overall, though, the "Delphi" codename had a
alias for Quattro Pro 4.0, a direct 1-2-3 classier ring to it than most of the other
competitor). This was because Quattro Pro had suggestions that were offered. Pascal is a classic
to assume the Lotus position! programming language, so it felt appropriate to
associate a Pascal-based development tool with a
"Delphi" started out as a beta codename for a classical Greek brand. Many codenames were
closely guarded, innovative research project at used during the development of that version 1.0
Borland: a next-generation visual development product, a new one being coined for each press
environment for Windows based on Borland's or corporate briefing of the beta product, in the
Object Pascal programming language (until then hope of limiting rumours and allowing Borland
known as Turbo Pascal). to track the source of any leaks. The aim was to
Gary Whizin, the Borland R&D Manager for Microsoft to discover what Borland was up to
favoured the codename Oracle, since by mid- as late as possible.
1993 the strategic decision had been taken to
make database tools and connectivity a central
part of this new Pascal product,
which by then had six months of
intensive research, market
analysis and proof-of-concept
exercises behind it.
FlatBox2D
Delphi XE8, C++Builder XE8 and RAD
Studio XE8 are introducing support for
a 2D physics engine based on Box2D.
You can find a new FlatBox2D folder
under Source in the default XE8
installation directory.
It contains some C++ header and source files and
five Object Pascal units:
Box2D.Common.pas
Box2D.Collision.pas
Box2D.Dynamics.pas
Box2D.Rope.pas
Box2DTypes.pas
Dynamic Body (b2_dynamicBody). First we need to create and initialize the ground
It has a mass. Forces have impact on it. It can be body definition. The default type of a body is
put into linear and angular movement. It may static, so we do not need to change it. We only
collide with other dynamic and static bodies. If a specify the position of the body to be 10 meters
dynamic body has zero mass then it behaves below zero.
differently and it always has zero angular velocity. b2BodyDef is a record type. We need the @
In a game dynamic bodies are typically moving operator to pass a pointer to this record, rather than
objects like vehicles, bullets, balls and everything the record itself. The call to Set is prepended with
else that can move through the world and collide. the & operator. This is because set is an Object
Static Body (b2_staticBody). Pascal keyword and to use it as an identifier it
It does not have a mass. Forces do not influence it. needs to be escaped.
It cannot be put into a linear or angular The Box2D body is an abstract notion. It does
movement. Dynamic bodies collide with it. In a not have a shape, mass or any physical properties
typical game static bodies are used to define of the material it simulates. The class that has these
borders and limits of the game, like walls, ground, properties is called a fixture. Fixtures belong to a
bands in a hockey game and so on. body and are created using the CreateFixture
Kinematic Body (b2_kinematicBody): method of a body.
Forces do not influence it. It can be put into The CreateFixture method has two variants.
linear or angular movement. It may collide with One that takes a fixture definition as an argument
dynamic bodies, but it does not collide with other and the other that takes an instance of a shape
kinematic bodies. Collisions between dynamic and class and the density.
kinematic bodies do not
change the movement of b2BodyWrapper = record
FHandle: b2BodyHandle;
a kinematic body. //
For example they can be function CreateFixture(def: Pb2FixtureDef): Pb2Fixture; overload; cdecl;
used in a game as function CreateFixture(shape: b2ShapeHandle; density: Single):
moving platforms that Pb2Fixture; overload; cdecl;
do not react to heavy //
bodies that collide with
them. The movement of
a kinematic body is controlled by vectors of linear There are four different descendants from the
and angular velocity. b2Shape class that defines a shape.
Circle shape (b2CircleShape):
In order to create a body we need to call Circle shapes have a position and radius. Circles
CreateBody factory method of the world object are solid. You cannot make a hollow circle using
and in the parameter we pass an object that the circle shape.
contains the body definition. This is a common Polygon shape (b2PolygonShape):
pattern in Box2D. Factory methods typically Polygon shapes are solid convex polygons.
accept definition objects that provide a lot of A polygon is convex when all line segments
useful defaults (which means there is less for you connecting two points in the interior do not cross
to code). any edge of the polygon. Polygons are solid and
Let's add the ground body to our Hello World never hollow. A polygon must have three or more
simulation. vertices. Polygon vertices are stored with a counter
clockwise winding.
Edge shape (b2EdgeShape):
var
groundBodyDef: b2BodyDef; Edge shapes are line segments.
groundBody: b2BodyWrapper; These are provided to assist in
making a free-form static
// environment for your game.
A major limitation of edge shapes
// Define the ground body
groundBodyDef := b2BodyDef.Create(); is that they can collide with circles
groundBodyDef.position.&Set(0.0, -10.0); and polygons but not with
themselves.
// Call the body factory which allocates memory for the ground body Edge shapes have no volume,
groundBody := world.CreateBody(@groundBodyDef);
so edge-edge collision is not
possible.
Test Bed
The FlatBox2D Test Bed demo is a very
convenient application that acts a framework for
plugging in different tests into a common
codebase for rendering graphics, providing the
game loop and processing user input. This the
Object Pascal version of the original C++ Test
Bed. You can find FlatBox2D Test Bed in
C:\Users\Public\Documents\Embarcadero\
Studio\16.0\Samples\Object
Pascal\Mobile Samples\Physics\TestBed
\TestBed.dpr
You can learn a lot by playing with one of the six
predefined test cases that experiments with
These are the very basics. To use FlatBox2D in different aspects of the engine. You can create your
applications we need to create the world object own tests by extending the TTest class and
first, add all bodies, shapes and joints to it, build registering your test with the application's main
our own game loop that would call our world's form. Out of the box you got the following tests:
Step method to advance the simulation and we Chain
would also need to provide our own graphics Varying Restitution
rendering. Tiles
In the default Delphi XE8 installation there are two Add Pair
more demo projects that go deeper into using Apply Force
different bodies, shapes and joints to create more
Basic Slider Crank
complex simulations than this Hello World
which has just two boxes.
Here is how Tiles test looks like in action:
By pressing space you shoot bullets into your The AddControl method is called for every
simulation. That is fun! control on the form to create a box representing
this control inside the world.
Adding physics to apps
The third demo that comes installed with Delphi
Summary
XE8 demonstrates how to add physics to a common
The FlatBox2D physics engine is a great new
FireMonkey multi-device app which uses standard
feature included in the new version of
user interface elements such as buttons, scroll bars, Embarcadero Delphi XE8, C++Builder XE8 and
check boxes and the like. This demo is located RAD Studio XE8. Based on a well-known open
inC:\Users\Public\Documents\Embarcader source C++ Box2D implementation it adds a
o\Studio\16.0\Samples\Object Pascal
solid foundation for building new generation
\FireMonkey Desktop\Physics
apps with realistic graphics user interfaces.
\FormWithBox2D\FMSimplePhysics.dpr
The FlatBox2D demos discussed in this article
When you open the FMSimplePhysics project it
cover the basics of using Box2D
looks like a regular FireMonkey Controls demo.
(Hello World), playing with
more complex combinations of
bodies, shapes, joints (Test
Bed) and adding physics to a
Delphi XE8 multi-device
application (FMSimplePhysics).
The next step is to build a
complete game with its own
graphics, but this I'm going to
leave to the reader!
Calling ApplyUpdates on a ClientDataSet clears FireDAC datasets flag records in the cache by
each applied record from the cache (assuming that exposing a property named RowError. When the
MaxErrors is not exceeded). If all updates are current record of the dataset is one whose cached
successfully applied, the change cache will be value raised an error, this property holds the
empty when ApplyUpdates returns. If errors are exception raised during the call to ApplyUpdates,
encountered, and MaxErrors is not exceeded, the otherwise the property is nil.
applied records are cleared from the cache, with
the records that produced errors remaining. FireDAC datasets also support a filter flag (used
with the FilterRecord and StatusFilter properties)
By comparison, following a call to ApplyUpdates named rtHasErrors. You can use this flag to filter
on an FDMemTable, the cache is cleared the FDMemTable records on those for which an
unconditionally. In other words, if AMaxErrors error was raised during ApplyUpdates.
(the name of the parameter passed to ClientDataSets do not support the RowError
property and do not support the rtHasErrors flag.
ApplyUpdates in FireDAC is different), all records
are removed from the cache, including the errors.
However, these values are only useful if the cache is
Yes, ApplyUpdates will return a non-zero value if
intact, and from my tests, calling apply updates to
errors are encountered, but those errant records
an FDMemTable always clears the cache.
are removed from cache. Apparently, if you want
This means that if you are going to try to handle
to process those errors, you must do so by catching
errors in the call to ApplyUpdates, you must do so
them using the OnReconcileError event handler.
from the OnReconcileError event handler of the
FDMemTable.
I mentioned earlier that FireDAC's other datasets,
such as FDQuery, handle ApplyUpdates Regardless, following a call to ApplyUpdates on a
differently, both from ClientDataSets and FireDAC dataset, you must deal with the errors, on
FDMemTables. With an FDQuery, a call to a record by record bases, before flushing the cache.
ApplyUpdates doesn't clear the cache at all, even if In my opinion, the ClientDataSet way of doing this
all changes can be applied. If ApplyUpdates is much easier to deal with.
returns 0, indicating that all updates are applied,
you must then call CommitUpdates to flush the Applying Updates to
cache of all records. If ApplyUpdates returns a Master/Detail Relationships
positive value, indicating that one or more records A ClientDataSet can apply updates to its data, via
could not be applied, you have to manually handle a DataSetProvider, through a single call to
those records before flushing the cache. ApplyUpdates. If the ClientDatasSet includes one
or more nested datasets whose data has changed,
Fortunately, there are easy ways to identify the call to ApplyUpdates on the ClientDataSet
records in cache that could not be applied. applies changes to the nested dataset data as well.
This is the mechanism used by ClientDataSets to You must either apply the updates (using
apply updates to master/detail relationships. ApplyUpdates, and in the case of non-
FDMemTable FireDAC datasets, CommitUpdates)
FireDAC uses another method for caching updates or cancel them (using either CancelUpdates or
to master/detail relationships, something that CommitUpdates) before you can exit the cached
FireDAC refers to as centralized cached updates. updates mode.
With centralized cached updates, two or more STATUSFILTER DEFAULT VALUE
FireDAC datasets, related in a master/detail Another difference is that the
relationship, point to a single FDSchemaAdapter. ClientDataSet.StatusFilter property and the
While the FireDAC datasets are placed in a cached FDMemTable.FilterRecords property (the
update mode manually, the FDSchemaAdapter is FDMemTable equivalent of
used to apply the updates to all of the associated ClientDataSet.StatusFilter) operate differently.
FireDAC datasets. The default value for StatusFilter in a
ClientDataSet is an empty set of TUpdateStatus
The use of the centralized model of cached updates flags. For an FDMemTable, it is a set that includes
is demonstrated in the project named usUnmodified, usModified, and usInserted.
CentralizedCachedUpdates. The main form of this Granted, the way that FDMemTable does this is
application is shown in Figure 1, on page23. more intuitive, but it is a difference nonetheless.
Figure 2. A ClientDataSet loads linked detail tables from a DataSetProvider into nested dataset fields
Note the OrdersQuery field in the top grid. This is data source, typically a database, and passes it to
the nested dataset. When the ellipsis is clicked on a client application. If the client application
the OrdersQuery field, the nested data is display makes changes to that data, a delta is passed
in a dynamically created grid. Also note that the from the ClientDataSet on the client to a
lower DBGrid displays these orders as well, which DataSetProvider on the server, which in turn
was accomplished by pointing another applies those changes to the underlying database.
ClientDataSet to the dataset field
(OrdersQuery).While FDMemTables support the The key to making this work, from a
creation of nested datasets, these can only be the ClientDataSet perspective, is embodied in the
result of creating the FDMemTable based on ClientDataSet/DataSetProvider interaction. The
defined FieldDefs or TFields of the type DataSetProvider resides on the DataSnap server,
DataSetField. An FDMemTable that loads its data and the ClientDataSet interacts with it by way of
from the master table of a dynamic master-detail several client-side components. In the latest
relationship does not obtain a nested dataset field incarnation of DataSnap, those components are a
representing the detail table. dbExpress SQLConnection (employing its
DataSnap driver), and a DSProviderConnection.
Similarly, while FDMemTable supports nested
datasets, these cannot be used to apply cached There are three aspects of ClientDataSets that
updates in the same manner as ClientDataSets. make DataSnap work smoothly. First, opening a
ClientDataSets can apply updates to master-detail ClientDataSet that points to a DataSetProvider on
relationships using nested datasets, FDMemTable a DataSnap server retrieves data, and calling
cannot. ApplyUpdates sends the change cache back to
the DataSetProvider for resolution. Second, the
Nested datasets play an important role in the use of nested datasets permits changes made to
ClientDataSet's ability to support cached updates related data (in a master/detail sense) to be
with master-detail relationships. As I've updated with a single call to ApplyUpdates.
mentioned already, FireDAC datasets support Finally, the Params and CommandText
cached updates directly, meaning that properties of the ClientDataSet permit the
FDMemTables are not necessary is all the only ClientDataSet to effortlessly pass parameter
feature you need from the FDMemTable is cached values, and even entire queries, to the
updates. For FireDAC datasets that need to cache DataSetProvider, permitting a great deal of
updates on master-detail relationships, the flexibility from the client-side of the DataSnap
datasets can employ an FDSchemaAdapter. equation.
DataSnap
ClientDataSets were designed for MIDAS, which The use of ClientDataSets in a DataSnap
was released with Delphi 3. While the name has client/server interaction is demonstrated in a set
subsequently changed to DataSnap, the essential of projects located in the DataSnap directory.
model is the same. A middle-tier server (the Figure 3 shows how the server methods unit
DataSnap server) retrieves data from a looks in the designer.
Lets start with a first function and how to improve and debugging tool that many programmers overlook,
test it: primarily because of a general lack of discussion on
the subject.
function CountPos(const subtxt: string; Text: string): Integer;
begin
if (Length(subtxt)= 0) or (Length(Text)= 0) or
(Pos(subtxt,Text)= 0) then
result:= 0 OutputDebugString(inttoStr(CountPos('max',TESTTEXT))+
else 'CountPos runs..');
result:= (Length(Text)-
Length(StringReplace(Text,subtxt,'',
[rfReplaceAll]))) div Length(subtxt);
end;
This function counts all sub-strings in a text or That's all you have to do. Because Delphi, Lazarus
string. The point is that the function uses another or Free Pascal is installed as the system debugger,
functions like Pos() and StringReplace(). any strings sent using OutputDebugString will
Do we have to test it also? show up in the Event Log. You can place calls to
No, but we need a reference value: OutputDebugString anywhere you want in your
PrintF('CountPos: %d',[CountPos('max','this is max of maXbox a max numbermax')]) code.
To view the value
The result is 3, so we better extract our test-string of a variable, you must format a string and send
in a constant: that string to OutputDebugString, for example:
Const TESTTEXT = 'this is max of maXbox a max numbermax'; procedure GetOutputDebugString;
PrintF('CountPos: %d',[CountPos('max',TESTTEXT)]) var
x : Integer; S : string;
begin
And with Assert we do automate that reference { Some code here...}
value (more on page 34): x:= CountPos('max',TESTTEXT);
with procedure Assert(expr: Boolean; const S:= Format('X := %d', [X]);
OutputDebugString(PChar(S));
msg: string); you set an expression value which
writeln(S)
you expect to be true: end;
Assert(CountPos('max',TESTTEXT)=3, 'count pos assert') // OutputDebugString(PChar(Format('[%s][%s]
%s',[aCaption, GetFormatDT(StartDT), aText])));
When you use Event Viewer to troubleshoot or Analytic or test events are published in high
track a problem, you need to locate events related volume. They describe program operation and
to the problem, regardless of which event log they indicate problems that can't be handled by user
appear in. Event Viewer enables you to filter for tasks or intervention.
specific events across multiple logs as of maXbox.
We need values in
WriteToOSEventLog(const logName, logCaption, logDetails: String; const logRawData: Str);
In a shortlink
%windir%\system32\eventvwr.msc /s
you start the eventlog:
32
maXbox Issue Nr 1 2015 BLAISE PASCAL MAGAZINE
START WITH FUNCTION TESTING (CONTINUATION 2) maXbox
Lets go back to our function to test and build Or you will look at the web and ask to a search
a test function too. machine: How do I find and count the total
function CountPos(const subtxt: string; Text: string): Integer; amount of times that a
begin particular word
if (Length(subtxt)= 0) or (Length(Text)= 0) or (Pos(subtxt,Text)= 0)
appears?
then result:= 0
else result:= (Length(Text)- Length(StringReplace(Text,subtxt,'', Often, as programmers
[rfReplaceAll]))) div Length(subtxt); gain experience in
end; building applications,
they develop a sixth sense
Such a small function like above contains another for locating the cause of in-correctness or access
3 functions (yellow) and before testing we should violations.
also check the understanding and the design of With asserts you can support that feeling what
the function. For example StringReplace() could crash. An assert function is used to make
which replace one or more substrings found sure that certain conditions which are assumed to
within a string does have more parameters to test be true are never violated. Assert provides an
like the [rfReplaceAll].On the other side we opportunity to intercept an unexpected condition
can trust in a stable function of the runtime library and halt a program rather than allow execution to
otherwise we loose time not to mention the continue under unanticipated conditions.
frustration caused by a bug that is difficult to find.
If you encounter problems using any feature of
I asked a few lines above if the function to test
Event Viewer, first ensure that the Windows Event
is case-sensitive or not, do you remember? Yes it is
Log service is running. If you are working
and we do have to consider that in our test-string
with event subscriptions, ensure that the Windows
and test-function with Uppercase too.
Event Collector service is running.
function CountPosTest: boolean; With this call in maXbox you can run the
begin
result:= false; event log from the script:
if CountPos(Uppercase('max'),Uppercase(TESTTEXT))= 4 ExecuteCommand('cmd','/c %windir%\
then result:= true; system32\eventvwr.msc /s ')
end;
Next we go to the topic of Unit Testing but
Each time we test (or change) our function we call not to generate units (this is another story)
the test-function with a test-string and check the but consuming as a test-function or protocol e.g. in
reference value which must be 4. Normally you maXbox I do have some unit tests to check
test a function by creating a test application or unit conditions before running a script!:
and if something goes wrong or crashes you will // test routines with assert or assert2 builds
run the test application under the debugger and SelftestPEM;
watching the values. SelfTestCFundamentUtils;
A debugger helps you find bugs or errors in SelfTestCFileUtils;
SelfTestCDateTime;
your program at runtime. But the debugging SelfTestCTimer;
process isn't just for finding and fixing bugs - it's a SelfTestCRandom;
development and test tool as well. Another great
way to test a function is to compare the result with Writeln(' 6 Units Tested with success ')
ShowMessageBig(' 6 Units Tests with
a already well known standard function, for
success!');
example CountStr():
Function CountStr(const ASearchFor, ASearchIn: string): Integer;
or check with a subroutine which both of them A unit is the smallest testable part of software. It
uses: Function Unit SysUtils usually has one or a few inputs and usually a
StringReplace: Replace one or more single output. In procedural programming a unit
substrings found within a string may be an individual program, function, routine,
function CountStr(const ASearchFor, ASearchIn: string): Integer; procedure, etc. In object-oriented
var Start: Integer; programming, the smallest unit is
begin a method, which may belong to a
Result:= 0;
base/ super class, abstract class or
Start:= Pos(ASearchFor, ASearchIn);
while Start > 0 do begin derived/ child class.
Inc(Result);
Start:= PosEx(ASearchFor, ASearchIn, Start+ 1);
end;
end;
SelfTestCFileUtils;
SelfTestCDateTime; //as an extract in test-cases:
34
maXbox Issue Nr 1 2015 BLAISE PASCAL MAGAZINE
START WITH FUNCTION TESTING (CONTINUATION 4) maXbox
maXbox
point is displayed as it would be if you had
stopped at a breakpoint.
You can or must restart the program again by
clicking the Run button, or you can step through
your code.
// WriteToOSEventLog
By Jeremy North
With the release of Delphi XE8 one of the new There is an attempt to have a global database of
features added to the RTL is support for proximity UUID allocated to a company to help
Bluetooth beacons. This includes support for prevent collisions
both iBeacon and AltBeacon specifications. - https://openuuid.lime-company.eu/.
Mode
This is the kind of Beacon that will be
monitored. There are two beacon standards,
iBeacon (referred to as Standard in the
Embarcadero framework) and Alternate.
AltBeacon is a competing specification with
iBeacon however fortunately for us
Embarcadero supports both with their
beacon framework.
Enabled OnBeaconEnter
Must be set to True to ensure monitoring of The event is called when a beacon has been
specified regions occur. identified in the region specified. The event
parameters include a reference to the IBeacon
CalcMode interface of the internally stored beacon as well as a
This determines how the distance is calculated. full list of beacons within the region.
The default value of Stabilized means the beacon
framework will use a common distance calculation OnBeaconExit
for you. The other value is Raw and this means no The event signature is the same as the
calculation is done. OnBeaconEnter event. The IBeacon parameter
references the beacon that is no longer available, as
SPC well as the full list of beacons within the region.
This is the signal processing constant which is
used when calculating the distance. This property OnBeaconProximity
is not used for iOS deployed apps. This event is called when a monitored beacon has
changed its proximity. In other words you are
Properties of special note either getting closer to the beacon, or further from
The following properties are not used for iOS apps it. This event provides access to the beacon via the
but are important because both affect battery life IBeacon interface as well as the new proximity
and one may be too short depending on the signal value.
frequency of your beacon. It would have been nice if it also provided the
previous proximity value.
ScanningTime
This is the time spent scanning a region. Other Events
The default value of 500ms might be too low if The OnCalcDistance event is called to allow you to
your beacons are setup to only transmit every provide your own distance calculation of the
1000ms. The Estimote beacons default signal beacon. If you are finding the default distance
interval is 950ms. They will still be located, but it calculation is inaccurate with your beacon, you
might take a couple of scans to discover so if speed might try an alternate calculation available on the
is an issue, increasing this value will help. internet. Note: Not many SDK providers publish
the formula used to calculate distance. Estimote do
ScanningSleepingTime not publish the formula used.
This is the elapsed time in milliseconds between
scans. The OnParseManufacturerData event is called once
a beacon is located to allow interpreting the
Events manufacture specific data available from the
A number of events are provided with the TBeacon beacon. Many manufacturers provide additional
component. Three of the events provide the most information apart from the required values which
use. These are OnBeaconEnter, OnBeaconExit and are usually read by using their SDK. If you know
OnBeaconProximity. the layout of the signal data, this event is called to
allow you to interpret this additional data.
Public Methods
There are only three public methods available.
They are StartScan, StopScan and Nearest. The first
two are called internally when changing the
Enabled property so you don't need to call them
directly. The Nearest method could be of use
depending on the app you are creating.
Below is a device capture when running the app Using a Manufacturers SDK
on my iPhone 5. It is important to point out that depending on the
beacon manufacturer, additional data outside of the
required information may be broadcasted. Estimote
have a connectivity mode (which is an
authenticated communication) where additional
information can be retrieved from the beacon.
For an Estimote beacon, this includes temperature,
battery life, firmware updates and also the
frequency at which the beacon signals. This
information can only be used with using the official
Estimote SDK with your app. This is not something I
have attempted to do with Delphi yet.
Conclusion
Beacons are an interesting addition to the world
and definitely show promise in the areas of
home automation and retail advertising. As
beacons become more powerful, smaller
(Estimote are releasing sticker Nearables soon)
and additional sensors are added the
possibilities for developers to take advantage of
them will increase.
Hopefully I've provided a little insight into the
world of beacons and have convinced you to
acquire some to play around with.
For those people who are not strong on writing code then designing, compiling and creating
Arduino programs has never been easier! Why waste time on creating code when we have done
all the hard work for you already? You have your Arduino board, and great hardware design,
see it running in minutes, not hours!
Currently we are running a Beta program which you can be part of by joining our Google group.
Join the group now to download and test the software or send an email to mitov@mitov.com.
www.visuino.com
Delphi XE8
The Fastest Connected App Platform
for Windows and Beyond
Embarcadero Delphi XE8 is the fastest way for designing, coding, and extending connected apps across
Windows, Mac, iOS, Android and IoT. Build industrial strength and Business ready solutions incorporating multi-
ple native client platforms, mobile extensions, smart devices, cloud services, Enterprise and embedded data.
Easily add proximity and location awareness Easily connect to popular cloud services
to your apps with component level Beacon with REST as well as BaaS providers for push
support. notifications, authentication, storage and
more!
Use the FireUI Multi-Device Designer to Quickly deploy Enterprise Mobility Services
build user interfaces once for multiple (EMS) to publish and manage custom APls,
device form factors and OSs with native Enterprise data, services, and analytics.
fidelity, capabilities, and uniqueness.
Tel: +31 23 542 22 27
Features Architect Ultimate Enterprise Pro Starter
Features
MULTI-DEVICE APPLICATION DEVELOPMENT
The most productive integrated visual development environment (IDE) with UI designers,
code editor, Code Insight, build and debugging tools X X X X X
Develop natively compiled apps for Android and iOS (now Optional
including 64-bit and Universal iOS apps) X X X
Single-source, mobile app development for Android and iOS with the FireMonkey framework X X X Optional
iOS (now including 64-bit andUniversal iOS apps)
Client/Server database connectivity for leading database servers including Microsoft SQL Server,
X X X Optional
Oracle, Sybase, DB2, Informix, InterBase, ODBC and more
DataSnap n-tier middleware SDK for building application and data services X X X
Enterprise Mobility Services, a turnkey set of integrated services including user authentication,
middleware database connectivity, custom REST API management and analytics* X X X Optional
*Requires separate per-user runtime agreement
REST client library and Back-end as a Service Components for Parse and Kinvey X X X Optional
LICENSING
For developing 64-bit Windows applications For developing Mac OS X applications For developing iOS applications Supported Deployment Platforms
PC running a 64-bit version of Windows or PC running Windows connected with PC running Windows connected with an PCs and tablets with Intel/AMD processors
a 32-bit development PC connected with a an Intel-based Mac or a Mac running Intel-based Mac or a Mac running Win- running Windows 7, 8, 8.1, Server 2008,
PC running a 64-bit version of Windows. Windows in a VM, with 2 GB RAM or more, dows in a VM, with 2 GB RAM or more, or Server 2012. Macs running OS X 10.9
running OS X 10.10 (Yosemite) or 10.9 running OS X 10.10 or 10.9 with Xcode 6 or 10.10. iPhone, iPad, or iPod Touch
(Mavericks). An Apple Developer account is required running iOS 7. Android phones and tablets:
to deploy iOS apps to physical devices. ARMv7 devices with NEON support, running
Ice Cream Sandwich (4.0.3-4.0.4), Jelly Bean
(4.1.x, 4.2.x, 4.3.x) or KitKat (4.4.x) and
Lollipop (5.x).
DownloadDownload
a Free Triala Now! Visitatwww.embarcadero.com/trial
free Trial www.barnsten.com
- Added AMQP 0.91 client side gateway Supports Delphi/C++Builder/RAD Studio 2009
support and sample. to XE7 (32 bit, 64 bit and OSX where applicable).
- Updated StreamSec TLS transport plugin kbmMW for XE5 to XE7 includes full support for
component (by StreamSec). Android and IOS (client and server).!
- Improved performance on Indy TCP/IP
kbmMemTable is the fastest and most feature rich
Client messaging transport for large number in memory table for Embarcadero products.
of inbound messages.
- Easily supports large datasets
- Native high performance 100% developer with millions of records
defined application server with support for - Easy data streaming support
loadbalancing and failover - Optional to use native SQL engine
- Native high performance JSON and XML - Supports nested transactions and undo
- Native and fast build in M/D,
(DOM and SAX) for easy integration with
aggregation /grouping,
external systems range selection features
- Native support for RTTI assisted object - Advanced indexing features for
marshalling to and from XML/JSON, now also extreme performance
with new fullfeatured XML schema
(XSD) import Warning!
- High speed, unified database access kbmMemTable and kbmMW
(35+ supported database APIs) with
connection pooling, metadata and
are highly addictive!
Once used, and you are hooked for life!
data caching on all tiers
- Multi head access to the application server,
via AJAX, native binary, Publish/Subscribe,
SOAP, XML, RTMP from web browsers,
embedded devices, linked application
servers, PCs, mobile devices, Java systems
COMPONENTS
4
and many more clients
- Full FastCGI hosting support.
Host PHP/Ruby/Perl/Python applications in
kbmMW! DEVELOPERS
EESB, SOA,MoM, EAI TOOLS FOR INTELLIGENT SOLUTIONS. kbmMW IS THE PREMIERE N-TIER PRODUCT FOR DELPHI /
C++BUILDER BDS DEVELOPMENT FRAMEWORK FOR WIN 32 / 64, .NET AND LINUX WITH CLIENTS RESIDING ON WIN32 / 64,
.NET, LINUX, UNIX MAINFRAMES, MINIS, EMBEDDED DEVICES, SMART PHONES AND TABLETS.