import { Observable } from '@babylonjs/core/Misc/observable';
/**
 * Creates a property change observable object from a existing object.
 * The observable object has a additional property `onPropertyChanged` which is an observable that can be subscribed to.
 * Any changes to properties on the object can be observed by subscribing to the `onPropertyChanged` observable.
 *
 * @template T - The type of the object being observed.
 * @param target - The object to observe.
 * @returns The property change observable object.
 */
export function makePropertyChangeObservable(target) {
    const onPropertyChanged = new Observable();
    return new Proxy(target, {
        get: (target, key, receiver) => {
            if (key === 'onPropertyChanged')
                return onPropertyChanged;
            return Reflect.get(target, key, receiver);
        },
        set: (target, key, newValue, receiver) => {
            const currentVal = Reflect.get(target, key, receiver);
            const wasSet = Reflect.set(target, key, newValue, receiver);
            if (currentVal !== newValue)
                onPropertyChanged.notifyObservers({
                    type: 'set',
                    sender: receiver,
                    property: key,
                    oldVal: currentVal
                });
            return wasSet;
        },
        deleteProperty: (target, p) => {
            const oldVal = Reflect.get(target, p);
            const wasDeleted = Reflect.deleteProperty(target, p);
            if (wasDeleted) {
                onPropertyChanged.notifyObservers({ type: 'delete', sender: target, property: p, oldVal });
            }
            return wasDeleted;
        },
        defineProperty: (target, p, attributes) => {
            const wasDefined = Reflect.defineProperty(target, p, attributes);
            if (wasDefined) {
                onPropertyChanged.notifyObservers({
                    type: 'define',
                    sender: target,
                    property: p,
                    oldVal: undefined
                });
            }
            return wasDefined;
        }
    });
}
//# sourceMappingURL=PropertyChangeObservable.js.map