Frequently Asked Questions about the changes, introduced in version 0.99.12 of PTCPas Q: My code uses only the ptcgraph and ptccrt (TP7 compatibility) units. Is it affected by the changes? A: No. Only code that uses the ptc unit is affected. Q: Were the changes necessary? A: Yes, I believe so. Using certain objects like events, areas, and formats was tedious because of the need to manually manage and free them. You had to be aware of their lifecycle, e.g. when getting an event from the console you had to free it once you were done with it, but, when getting the format of the console, you had to know that you must not free it and that you must not change it with .Assign (otherwise things would break in the console, etc.) With the new interfaces, suddenly you don't have to worry about all that. The original C++ library OpenPTC was much easier to work with, thanks to C++'s automatic destructors, copy constructors and operator overloading. However, when PTC was ported to Pascal for the first time, FPC was still at version 1.0.x and didn't support interfaces, so it wasn't possible to do at the time. I was planning this change for a long time but I kept postponing it until now :) Q: Are you planning any more changes that break backward compatibility? A: No. I promise :) Q: Was it possible to introduce the changes, without breaking backward compatibility with existing code? A: Basically, it was hard to do without having to maintain a full set of wrapper classes with the old interface for compatibility and that is a lot of extra work I wouldn't like to do. I'd rather help people migrate their code to the new version. :) I documented the necessary changes, most of them can be done with just a series of search & replace and you can also email me your code if you have any trouble - I'll do my best to help. Q: How about keeping the old methods around and adding new overloaded ones? A: I considered doing that for a while, but I figured it wasn't an option, because it would make a huge mess out of PTCPas' interface. Also mixing reference counted interfaces and ordinary classes is dangerous and prone to errors (see next question for details). If you really cannot justify the effort needed to upgrade your code, old PTCPas versions are available on sourceforge forever. :) Q: Why were constructors replaced with factory methods? A: I wanted to hide the old classes completely and force the use of interfaces everywhere. One of the reason for this was that if I kept the old classes, in certain cases, that would make old code compile without errors, but crash at runtime. Here's an example: var format: TPTCFormat; // bug: this should be changed to IPTCFormat ... begin format := TPTCFormat.Create(8); // object created, ref count = 0 surface := TPTCSurface.Create(320, 200, format); // the reference count of // 'format' is increased (i.e. becomes 1) before the constructor call and // decreased afterwards back to 0 and then the object is freed. // If format was declared of type IPTCFormat, it would keep the reference // count one higher until the variable goes out of scope. console := TPTCConsole.Create; console.Open(320, 200, format); // here we try to use format for the second // time, but it has been freed and we get a crash at runtime :( ... end. The problem occurs when mixing direct references to the object with access to it via interfaces. To prevent this type of error, I made the TPTCFormat type private (i.e. hidden in the implementation part of the ptc unit) and only IPTCFormat public. This way, when trying to compile this code, you'll get a compile error in the declaration of 'format: TPTCFormat;' and you'll know that you need to fix it (by changing the type to IPTCFormat). However, this has the side effect of making the call to TPTCFormat.Create impossible (because TPTCFormat isn't public). IPTCFormat.Create sounds like the logical alternative, but it's also not possible, as IPTCFormat is an interface and interfaces cannot have constructors. That's why I introduced factory class methods (in this case: TPTCFormatFactory.CreateNew)