[Lazarus] Improper initialization of manged types

Anthony Walter sysrpl at gmail.com
Tue Jul 9 23:56:13 CEST 2013

The actual backing storage IDependencyProperty is handled by a class (an
object). Records types are used to manage references back to a shared copy
of the property (perhaps a Storyboard has a copy of the Alpha value of a
color component being animated), or to hold an unlinked (no backing
IDependencyProperty) vector.

For example, Sprite class has:

property Color: TVec4Prop read FColor write SetColor;
property Origin: TVec2Prop read FOrigin write SetOrigin;
property Size: TVec2Prop read FSize write SetSize;
property Position: TVec3Prop read FPosition write SetPosition;
property Rotation: TVec3Prop read FRotation write SetRotation;
property Angle: TVec1Prop read GetAngle write SetAngle;

Any of these properties can be animated or if you prefer changed directly.
You could say ...

var P: TVec3Prop;
P := PlayerSprite.Position;
P.X := 100;

And PlayerSprite moves to the X location 100, assuming it is not
overwritten by a currently running Animation or Storyboard. You could say
Animations.Remove(P.X) or Animations.Remove(PlayerSprite.Position.X) to
remove any animations of the property.

{ Animate PlayerSprite Y position to a target of 50, delay the start by 1
  complete in 0.5 seconds, infinitely loop the animation reversing the
  and use the Extend easing when moving between the start value and target
value }
Animations.Add(P.Y, 50)
  .Looping(loopReverse, loopInfinite)

Alternately you could write:

Animations.Add(P, Vec2(100, 50))

Where Animations.Add (and Storyboard as well, they share a common inherited
class) is overloaded to look like this:

{ Store a vec1 property animation returning customization arguments }
function Add(const Prop: TVec1Prop; const Target: TVec1): TAnimationArgs;
{ Store a vec2 property animation returning customization arguments }
function Add(const Prop: TVec2Prop; const Target: TVec2): TAnimationArgs;
{ Store a vec3 property animation returning customization arguments }
function Add(const Prop: TVec3Prop; const Target: TVec3): TAnimationArgs;
{ Store a vec4 property animation returning customization arguments }
function Add(const Prop: TVec4Prop; const Target: TVec4): TAnimationArgs;

Animations can only occur if a TVec(n)Prop is backed by an

P := Vec3(100, 50, 0);

Would overwrite the local TVec3Prop variable so that it no longer
references a the IDepenencyProperty held by PlayerSprite.Position. To
maintain the reference to the PlayerSprite.Position you could say:

P.Value := Vec3(100, 50, 0);

Which is what the property setter SetPosition does through an implicit
conversion from a TVec3 (Vec3 is a 3 component record and is used to create
geometry, surface normals, rotation matricies, 3d stuff) to a TVec3Prop
(TVec(n)Prop allow an array of floating point values to be shared by
reference, and thus are good for storage for animation).

So using assigning Vec3(100, 50, 0) to a property causes an implicit
conversion to an unlinked (a TVec(n)Prop where the IDepenencyProperty is
nil) property.

class operator TVec3Prop.Implicit(const Value: TVec3): TVec3Prop;
  Result.FProp := nil;
  Result.FIndex := 0;
  Result.FValue := Value;

And this is the type of situation where I get access violations, because
coming into the methods like the ones above Result.FProp is not nil and the
compiler tries to call release on a garbage value.

Regarding deleting object files, yes I done that and the same errors occur.

Unfortunately I do not have a simple example where I can reproduce these
errors as they typically happen randomly, but often enough that the my test
programs crash right away. And again I don't have this problem with the
same compiler sources and same library on 64-bit Linux.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.lazarus-ide.org/pipermail/lazarus/attachments/20130709/b1193b6e/attachment-0003.html>

More information about the Lazarus mailing list