From d27611881bb4ac70dca9863547fe508f94b67946 Mon Sep 17 00:00:00 2001 From: badcel <1218031+badcel@users.noreply.github.com> Date: Thu, 16 May 2024 21:07:20 +0200 Subject: [PATCH 1/2] Object: Remove INotifyPropertyChanged interface Implementing INotifyPropertyChanged seems not to be helpful currently. The interface was implemented since the very beginning of GirCore but the PropertyChanged event was never raised. As there were no complaints there is probably no need for this interface. Implementing it would mean that every object has 2 different ways of notifying about property changes (1. Notify event, 2. PropertyChanged) which seems a bit odd in the first place. As the notify event is the native system it should be preferred. While considering a possible implementation it came to mind that the PropertyChanged event should contain the managed name of the property. This would be the only sensible way for a C# dev, so the instance could potentially be compatible to other frameworks which require an instance of INotifyPropertyChanged and access the property via reflection. To raise the PropertyChanged event every object would always be required to subscribe to the Notify signal and forward it to PropertyChanged (after some property name mapping happend, which could get non trivial, too). If a user does need the INotifyPropertyChanged interface it could be implemented manually as a subclass and the mapping could be implemented manually. --- src/Libs/GObject-2.0/Public/Object.cs | 19 +------------------ 1 file changed, 1 insertion(+), 18 deletions(-) diff --git a/src/Libs/GObject-2.0/Public/Object.cs b/src/Libs/GObject-2.0/Public/Object.cs index 352990a75..b42a863c9 100644 --- a/src/Libs/GObject-2.0/Public/Object.cs +++ b/src/Libs/GObject-2.0/Public/Object.cs @@ -8,13 +8,8 @@ namespace GObject; -public partial class Object : IObject, INotifyPropertyChanged, IDisposable, IHandle +public partial class Object : IObject, IDisposable, IHandle { - /// - /// Event triggered when a property value changes. - /// - public event PropertyChangedEventHandler? PropertyChanged; - private readonly ObjectHandle _handle; public IntPtr Handle => _handle.Handle; @@ -73,18 +68,6 @@ protected virtual void Initialize() Debug.WriteLine($"Initialising Object: Address {_handle.Handle}, Type {GetType()}."); } - /// - /// Notify this object that a property has just changed. - /// - /// The name of the property who changed. - protected internal void OnPropertyChanged([CallerMemberName] string? propertyName = null) - { - if (propertyName == null) - return; - - PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); - } - public virtual void Dispose() { Debug.WriteLine($"Disposing Object: Address {_handle.Handle}, Type {GetType()}."); From 80a1aea3d81d88c6295f6f56d118cb7710ce9366 Mon Sep 17 00:00:00 2001 From: badcel <1218031+badcel@users.noreply.github.com> Date: Thu, 16 May 2024 21:50:33 +0200 Subject: [PATCH 2/2] Faq: Split from use.md and provide a description for property changed notifications --- docs/docs/faq.md | 38 ++++++++++++++++++++++++++++++++++++++ docs/docs/use.md | 19 +------------------ docs/toc.yml | 6 ++++-- src/GirCore.sln | 1 + 4 files changed, 44 insertions(+), 20 deletions(-) create mode 100644 docs/docs/faq.md diff --git a/docs/docs/faq.md b/docs/docs/faq.md new file mode 100644 index 000000000..f0dca1ff4 --- /dev/null +++ b/docs/docs/faq.md @@ -0,0 +1,38 @@ +# Frequently asked questions +Common questions which can come up during development. + +## DLL not found Exception +If the binaries are installed on the system but are not found during runtime a `DllNotFoundException` is raised. In this case the names of the installed libraries probably don't match the expected names. + +The gir.core nuget packages are build against 3 different package sources: +1. Gnome SDK (Linux) +2. MSYS2 (Windows) +3. Homebrew (MacOS) + +Each of those sources defines the names of the binaries which must be available to call into them. If a custom build binary is used, the resulting name of the binary can differ from the one specified by the package source, thus resulting in a `DllNotFoundException`. + +In case of a custom build C binary it is recommended to use a custom gir.core build, too. Please follow the [build instructions](build.md) to get started. It is important to update the gir-files with the corresponding custom build gir-files. + +This allows projects with custom build C binaries to create matching C# binaries without being dependent on one of the package sources. + +## Property changed notifications +C# developers are familar with the `INotifyPropertyChanged` interface, which can be used to notify an event listener about a changed property. The GObject type system uses a different but similar approach. + +Every class which inherits from `GObject.Object` has an event called `Object.OnNotify`. Subscriber to this event get notified about every changed property similar to `INotifyPropertyChanged`. The `NotifySignalArgs` event argument contains a `ParamSpec` instance which can be queried for the *native* property name via `GetName()`. + +As the *native* `Object` instance is represented in C# the properties in C# are named differently (mostly camel cased) in comparision to their *native* counterparts. To be able to match the *native* property name with their managed one, every *native* property has a static `Property` descriptor which provides the managed and unmanged name. Additionally it is possible to get or set the properties via their descriptor. + +In Addition to the `OnNotify` event there is a static field for each event which describes the event. Similar to properties it provides the managed and unmanaged name of every event and allows to connect to the event. + +The GObject type system is more advanced than `INotifyPropertyChanged` as it allows to subscribe to specific properties of an instance: This means there are only events received for properties the application is actually interested in. This feature can be used if an event listener is registered via the `NotifySignal.Connect()` method instead of the `OnNotify` event and supplies a *detail* parameter containing the *native* name of the property to watch. (Other events have a *detail* parameter, too with different meanings.) + +Sample Code: +```csharp +NotifySignal.Connect( + sender: myObj, + signalHandler: OnMyPropertyChanged, + detail: "my-property" +); +``` + +Please remember that the detail information must contain the *native name* of a property which is available through the static property descriptor, too. \ No newline at end of file diff --git a/docs/docs/use.md b/docs/docs/use.md index 11424b21c..690b4915a 100644 --- a/docs/docs/use.md +++ b/docs/docs/use.md @@ -19,21 +19,4 @@ The easiest way to get started on Windows is by installing the packages through 1. Download msys2 from the [official website](https://www.msys2.org/). 2. Run `pacman -Syu` to update the package database. 3. Run `pacman -S mingw-w64-x86_64-XXX` to install a package named XXX. -4. Add the directory `C:/msys64/mingw64/bin` to the front of the PATH. - -## Troubleshooting -Common problems which can come up during development. - -### DLL not found Exception -If the binaries are installed on the system but are not found during runtime a `DllNotFoundException` is raised. In this case the names of the installed libraries probably don't match the expected names. - -The gir.core nuget packages are build against 3 different package sources: -1. Gnome SDK (Linux) -2. MSYS2 (Windows) -3. Homebrew (MacOS) - -Each of those sources defines the names of the binaries which must be available to call into them. If a custom build binary is used, the resulting name of the binary can differ from the one specified by the package source, thus resulting in a `DllNotFoundException`. - -In case of a custom build C binary it is recommended to use a custom gir.core build, too. Please follow the [build instructions](build.md) to get started. It is important to update the gir-files with the corresponding custom build gir-files. - -This allows projects with custom build C binaries to create matching C# binaries without being dependent on one of the package sources. \ No newline at end of file +4. Add the directory `C:/msys64/mingw64/bin` to the front of the PATH. \ No newline at end of file diff --git a/docs/toc.yml b/docs/toc.yml index afcf3ea6d..1a9972167 100644 --- a/docs/toc.yml +++ b/docs/toc.yml @@ -4,14 +4,16 @@ items: - name: Api Documentation href: api/ homepage: api/index.md -- name: Use +- name: Get started items: - - name: Get started + - name: Use href: docs/use.md - name: Apps href: docs/apps.md - name: Libraries href: docs/libraries.md + - name: Faq + href: docs/faq.md - name: Contribute items: - name: Guidelines diff --git a/src/GirCore.sln b/src/GirCore.sln index 4d52d0580..220d4e2c8 100644 --- a/src/GirCore.sln +++ b/src/GirCore.sln @@ -155,6 +155,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "docs", "docs", "{4EE9860B-6 ..\docs\docs\use.md = ..\docs\docs\use.md ..\docs\docs\apps.md = ..\docs\docs\apps.md ..\docs\docs\build.md = ..\docs\docs\build.md + ..\docs\docs\faq.md = ..\docs\docs\faq.md EndProjectSection EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Adw-1", "Libs\Adw-1\Adw-1.csproj", "{CC67D284-6ADE-4F4D-9EE0-544143A7FF40}"