Ваш экземпляр TEntity должен зарегистрироваться в экземпляре TMesh, чтобы при освобождении экземпляра TMesh он изменил экземпляр TEntity.
Если ваши классы являются производными от класса TComponent, то этот механизм уже реализован для вас; каждый экземпляр TComponent имеет метод FreeNotification и метод Notification. Любой экземпляр TComponent может зарегистрироваться в другом компоненте, вызывая его метод FreeNotification и передавая себя в качестве параметра. Всякий раз, когда компонент уничтожается, он проверяет список компонентов, зарегистрированных для его бесплатного уведомления, и вызывает метод уведомления каждого зарегистрированного компонента. Таким образом, компонент регистра будет уведомлен всякий раз, когда другой компонент будет уничтожен.
Если один экземпляр TComponent является владельцем другого (в вашем случае TEntity может быть владельцем экземпляра TMesh), то он будет уведомляться автоматически при каждом удалении экземпляра TMesh. Все, что вам нужно сделать, это переопределить его метод уведомления и делать все, что вы хотите сделать внутри этого метода.
Если вы не хотите выводить ваши классы из класса TComponent или по какой-либо причине не хотите использовать реализацию Delphi, вы можете реализовать то же поведение в ваших собственных классах. Вам нужен внутренний список в вашем классе TMesh, который содержит список классов, о которых следует уведомлять. Вам также нужен метод для регистрации класса в вашем классе TMesh, и в конечном итоге вам нужен метод в вашем классе TEntity, который TMesh должен вызывать всякий раз, когда он освобождается.
Вот простой исходный код только для демонстрации общей идеи. Обратите внимание, что этот пример кода не является потокобезопасным и может не содержать некоторых других проверок. Я просто написал это быстро, чтобы показать вам, как реализовать такую идею:
unit Unit1;
interface
uses
Classes, Generics.Collections;
type
TBaseClass = class
private
FNotificationList : TList<TBaseClass>;
protected
procedure Notify(AClass: TBaseClass); virtual;
public
procedure RegisterForNotification(AClass: TBaseClass);
procedure UnregisterNotification(AClass: TBaseClass);
constructor Create;
destructor Destroy; override;
end;
TMesh = class(TBaseClass)
end;
TEntity = class(TBaseClass)
private
FMesh : TMesh;
FOnMeshRemoved : TNotifyEvent;
procedure SetMesh(Value: TMesh);
protected
procedure Notify(AClass: TBaseClass); override;
procedure DoMeshRemoved; virtual;
public
constructor Create;
destructor Destroy; override;
property Mesh : TMesh read FMesh write SetMesh;
property OnMeshRemoved : TNotifyEvent read FOnMeshRemoved write FOnMeshRemoved;
end;
implementation
{ TBaseClass }
constructor TBaseClass.Create;
begin
inherited;
FNotificationList := TList<TBaseClass>.Create;
end;
destructor TBaseClass.Destroy;
var
AClass: TBaseClass;
begin
if Assigned(FNotificationList) then
begin
if (FNotificationList.Count > 0) then
for AClass in FNotificationList do
AClass.Notify(Self);
FNotificationList.Free;
FNotificationList := nil;
end;
inherited;
end;
procedure TBaseClass.Notify(AClass: TBaseClass);
begin
end;
procedure TBaseClass.RegisterForNotification(AClass: TBaseClass);
begin
if not Assigned(AClass) then
Exit;
if FNotificationList.IndexOf(AClass) < 0 then
FNotificationList.Add(AClass);
end;
procedure TBaseClass.UnregisterNotification(AClass: TBaseClass);
begin
if not Assigned(AClass) then
Exit;
if FNotificationList.IndexOf(AClass) >= 0 then
FNotificationList.Remove(AClass);
end;
{ TEntity }
constructor TEntity.Create;
begin
inherited;
end;
destructor TEntity.Destroy;
begin
if Assigned(FMesh) then
FMesh.UnregisterNotification(Self);
inherited;
end;
procedure TEntity.DoMeshRemoved;
begin
if Assigned(FOnMeshRemoved) then
FOnMeshRemoved(Self);
end;
procedure TEntity.Notify(AClass: TBaseClass);
begin
inherited;
FMesh := nil;
DoMeshRemoved;
end;
procedure TEntity.SetMesh(Value: TMesh);
begin
if Assigned(FMesh) then
begin
FMesh.UnregisterNotification(Self);
FMesh := nil;
end;
if Assigned(Value) then
begin
FMesh := Value;
FMesh.RegisterForNotification(Self);
end;
end;
end.
В этом коде TEntity и TMesh являются производными от TBaseClass, который обеспечивает механизм уведомления. TEntity изначально не создает ни одного экземпляра TMesh, но вы можете назначить созданный экземпляр TMesh его свойству Mesh. Это заставит TEntity присвоить это значение своему полю FMesh и вызвать его класс RegisterForNotification, чтобы он мог получать уведомления о разрушении сетки.
Когда сетка уничтожается, она перебирает все объекты, зарегистрированные в ней, и вызывает их метод Notify. Здесь это будет метод Notify класса TEntity. Внутри метода Notify объекта TEntity он сначала устанавливает в своем поле FMesh значение nil, поскольку этот объект уничтожается и нет необходимости сохранять ссылку на мертвый объект. Затем он вызывает метод DoMeshRemove, который вызывает события для события OnMeshRemove.