I then have a global variable which will point to the actual class
type to instantiate.
DefaultCanvasClass: TfpgCanvasBaseClass = nil;
Then somewhere early on in your project you can define which Canvas
class to use by simply doing the following...
DefaultCanvasClass := TfpgCanvas;
DefaultCanvasClass := TAgg2D;
Here is the simple factory method that the Window class uses to
instantiate a new Canvas object.
Excuse the Writeln() statements and comment - they are for debugging purposes.
function TfpgWindow.CreateCanvas: TfpgCanvasBase;
writeln(' DefaultCanvasClass = ' + DefaultCanvasClass.ClassName);
// result := TAgg2D.Create(self);
// result := TfpgCanvas.Create(self);
Result := DefaultCanvasClass.Create(self);
I then have Writeln() statements in each Canvas constructor outputting
the name of that class. So when a TfpgCanvas instance is created, the
output should be similar to the class hierarchy listed above.
Now the problem...
Using the DefaultCanvasClass to create an instance, it seems to leave
out the latest class in the hierarchy. So if DefaultCanvasClass =
TfpgCanvas, I see console output as follows;
NOTE the missing TfpgCanvas. Needless to say my program crashes instantly.
The same happens when DefaultCanvasClass = TAgg2D. The console output is then.
Again, the actual TAgg2D class constructor is by-passed somehow?? Yet
the writeln() statement inside the CreateCanvas() method, which asks
for the ClassName of DefaultCanvasClass, DOES output the correct class
name. TfpgCanvas or TAgg2D.
Now if I change CreateCanvas() to create a instance of a Canvas class
directly - without the usage of DefaultCanvasClass... One of the two
commented out lines of code, then everything works fine. But
obviously, I don't want to hard-code which canvas class to use.
Can anybody see what I am doing wrong? I've tested with FPC 2.6.0,
2.6.1 and 2.7.1 under 64-bit Linux. All compilers give the same
results. Like I've said, I have used the Factory Method pattern many
times (though a bit more advanced than what I did here - normally
using a mapping class), and it always works well.
I took this global variable idea from the fptimer implementation,
which is part of FPC. I assume the fptimer implementation works
On 15 March 2012 11:36, Mattias Gaertner wrote:
> Is the constructor virtual?
I owe you a beer! :-)
The original constructor in TfpgCanvasBase was virtual, but some
descendant classes did a 'reintroduce' of the constructor which wasn't
virtual. Looking at the code now, the reintroduce isn't needed any
more and thus removed.
It works perfectly now, thanks!! fpGUI developers can now easily
switch between X11, GDI and AggPas canvas's. :-D
> From: Graeme Geldenhuys <[hidden email]>
>To: FPC-Pascal users discussions <[hidden email]>
>Sent: Thursday, March 15, 2012 7:11 AM
>Subject: Re: [fpc-pascal] class of - instance created is wrong
>On 15 March 2012 11:36, Mattias Gaertner wrote:
>> Is the constructor virtual?
>It works perfectly now, thanks!! fpGUI developers can now easily
>switch between X11, GDI and AggPas canvas's. :-D
Hi Graeme, this is completely off topic. Does AggPas works in 64bits Linux? I remember it didn't compile last year.
On 18 March 2012 08:03, Zaher Dirkey wrote:
> Would u push it to new repository (under ur account).
I'm planning to publish it to the fpGUI repository today.
> And why there is many of AggPas, what happened to the original one?
The original AggPas author only released AggPas as a zip / tarball
archive. There never was any public source code repository. The
original author also moved on, and created a commercial venture from
AggPas, now called CrossGL (Cross platform Graphics Library), so he
doesn't work on the original AggPas version any more.
Also, fpGUI can now use AggPas as the graphics library (instead of
XLib or GDI) - see the screenshot in the fpgui.development newsgroup.
Once fully tested, it will become the default graphics library for
fpGUI, so a copy of AggPas must be included with fpGUI to compile.
As for Lazarus including a copy of AggPas - I have no idea what was
the plans behind that. They will never use AggPas as a graphics
library for LCL, because it is not "native". Lazarus's AggPas package
is also not a default installed package in Lazarus IDE as far as I
know. So it seems the thinking was to supply an optional and more
powerful Canvas class, compared to the default LCL Canvas, for those
developers that need it in specialised projects.