xartigas pushed a commit to branch master.

http://git.enlightenment.org/core/efl.git/commit/?id=6a7c273ec76ff9297e7a12212c0e138ae7af9bc4

commit 6a7c273ec76ff9297e7a12212c0e138ae7af9bc4
Author: Marcel Hollerbach <m...@marcel-hollerbach.de>
Date:   Wed Jan 16 12:28:36 2019 +0100

    csharp: add a interface to start apps
    
    Summary:
    until to today you had to call init functions and a run function which
    were static function in a class called Efl.Ui.Config.
    
    However, calling those init functions there is not really OOP style.
    Right now things have changed into a manner where you are defining you
    application class with inheriting from the Application /
    SimpleApplication abstract.
    
    This enables you to call launch() on your application class, calling
    launch there leads to a call to the args function, you can call and use
    the Efl classes in there, everything is booted up.
    Option parsing and dependency start can still be done in the main method
    or application constructor, just ensure that you never call any efl
    class / function outside the launch function.
    
    A commit that demonstrates the usage can be found at
    
    ref T7204
    
    https://git.enlightenment.org/tools/examples.git/log/?h=devs/bu5hm4n/POC
    
    Reviewers: felipealmeida, segfaultxavi, Jaehyun_Cho, cedric
    
    Reviewed By: segfaultxavi
    
    Subscribers: zmike, woohyun, akanad, lauromoura, #reviewers, #committers
    
    Tags: #efl_language_bindings
    
    Maniphest Tasks: T7204
    
    Differential Revision: https://phab.enlightenment.org/D7495
---
 src/Makefile_Efl_Mono.am                           |   1 +
 .../mono/efl_mono/efl_csharp_application.cs        | 131 +++++++++++++++++++++
 src/bindings/mono/efl_mono/meson.build             |   5 +-
 3 files changed, 136 insertions(+), 1 deletion(-)

diff --git a/src/Makefile_Efl_Mono.am b/src/Makefile_Efl_Mono.am
index 73e9ded754..8c7d2f0373 100644
--- a/src/Makefile_Efl_Mono.am
+++ b/src/Makefile_Efl_Mono.am
@@ -43,6 +43,7 @@ efl_ecore_evas_mono_files = \
 # is custom built instead of through _LTLIBRARIES/_LIBRARIES
 lib_efl_mono_libefl_mono_dll_sources = \
        bindings/mono/efl_mono/efl_all.cs \
+       bindings/mono/efl_mono/efl_csharp_application.cs \
        $(efl_eo_mono_files) \
        $(efl_eina_mono_files) \
        $(efl_eldbus_mono_files) \
diff --git a/src/bindings/mono/efl_mono/efl_csharp_application.cs 
b/src/bindings/mono/efl_mono/efl_csharp_application.cs
new file mode 100644
index 0000000000..2b2c55c75e
--- /dev/null
+++ b/src/bindings/mono/efl_mono/efl_csharp_application.cs
@@ -0,0 +1,131 @@
+using System;
+using System.Runtime.InteropServices;
+using System.Threading;
+using static Efl.UnsafeNativeMethods;
+
+static class UnsafeNativeMethods {
+    [DllImport(efl.Libs.Ecore)] public static extern void ecore_init();
+    [DllImport(efl.Libs.Ecore)] public static extern void ecore_shutdown();
+    [DllImport(efl.Libs.Elementary)] public static extern int elm_init(int 
argc, IntPtr argv);
+    [DllImport(efl.Libs.Elementary)] public static extern void 
elm_policy_set(int policy, int policy_detail);
+    [DllImport(efl.Libs.Elementary)] public static extern void elm_shutdown();
+    [DllImport(efl.Libs.Elementary)] public static extern void elm_exit();
+}
+
+namespace Efl {
+  namespace Csharp {
+    public enum Components {
+        Basic,
+        Ui,
+    }
+    /// <summary>
+    /// This represents the entry point for the EFL framework
+    /// You can use this class to implement the 4 abstract methods which will 
then be called accordingly
+    /// All subsystems of efl are booted up correctly when the abstract 
methods of this class are called.
+    /// </summary>
+    /// <remarks>
+    /// Calls to efl outside those efl-callbacks or outside the mainloop are 
not allowed and will lead to issues
+    /// </remarks>
+    /// <example>
+    /// UserApp is the class that implements the Application abstract
+    /// <code>
+    /// public static void Main() {
+    ///   UserApp editor = new UserApp();
+    ///   editor.Launch(editor);
+    /// }
+    /// </code>
+    /// </example>
+    public abstract class Application {
+      //the initializied components
+      private static Components initComponent;
+      //what follows are 3 private functions to boot up the internals of efl
+      private static void Init(Efl.Csharp.Components component) {
+        Eina.Config.Init();
+        Efl.Eo.Config.Init();
+        ecore_init();
+        evas_init();
+        eldbus.Config.Init();
+
+        if (component == Components.Ui) {
+          // TODO Support elm command line arguments
+#if WIN32 // Not a native define, we define it in our build system
+          // Ecore_Win32 uses OleInitialize, which requires single thread 
apartments
+          if (System.Threading.Thread.CurrentThread.GetApartmentState() != 
ApartmentState.STA)
+              throw new InvalidOperationException("UI Applications require 
STAThreadAttribute in Main()");
+#endif
+          elm_init(0, IntPtr.Zero);
+
+          elm_policy_set((int)Elm.Policy.Quit, 
(int)Elm.PolicyQuit.LastWindowHidden);
+        }
+        initComponent = component;
+      }
+      private static void Shutdown() {
+        // Try to cleanup everything before actually shutting down.
+        System.GC.Collect();
+        System.GC.WaitForPendingFinalizers();
+
+        if (initComponent == Components.Ui) {
+          elm_shutdown();
+        }
+        eldbus.Config.Shutdown();
+        evas_shutdown();
+        ecore_shutdown();
+        Efl.Eo.Config.Shutdown();
+        Eina.Config.Shutdown();
+      }
+      /// <summary>
+      /// Called when the application is started. Arguments from the command 
line are passed here.
+      /// </summary>
+      protected abstract void OnInitialize(Eina.Array<System.String> args);
+      /// <summary>
+      /// Arguments are passed here, Additional calls to this function may 
occure,
+      /// but then the initialization flag is set to false.
+      /// </summary>
+      /// <remarks>
+      /// When Initialize is true then OnInitialize is also called
+      /// </remarks>
+      protected virtual void OnArguments(Efl.LoopArguments args) { }
+      /// <summary>
+      /// Called when the application is not going to be displayed, or is not 
used by a user for some time.
+      /// </summary>
+      protected virtual void OnPause() { }
+      /// <summary>
+      /// Called before an application is used again after a call to OnPause().
+      /// </summary>
+      protected virtual void OnResume() { }
+      /// <summary>
+      /// Called before starting the shutdown of the application.
+      /// </summary>
+      protected virtual void OnTerminate() { }
+      /// <summary>
+      /// This function initializices everything in EFL and runs your 
application.
+      /// This call will result in a call to OnInitialize(), which you 
application should override.
+      /// </summary>
+      public void Launch(Efl.Csharp.Components components=Components.Ui) {
+        Init(components);
+        Efl.App app = Efl.App.AppMain;
+        foreach (var arg in Environment.GetCommandLineArgs())
+          app.AppendArg(arg);
+        app.ArgumentsEvt += (object sender, LoopArgumentsEvt_Args evt) => {
+          if (evt.arg.Initialization) {
+            OnInitialize(evt.arg.Argv);
+          }
+          OnArguments(evt.arg);
+        };
+        app.PauseEvt += (object sender, EventArgs e) => {
+          OnPause();
+        };
+        app.ResumeEvt += (object sender, EventArgs e) => {
+          OnResume();
+        };
+        app.TerminateEvt += (object sender, EventArgs e) => {
+          OnTerminate();
+        };
+        app.Begin();
+        Shutdown();
+      }
+    }
+  }
+}
+
+
diff --git a/src/bindings/mono/efl_mono/meson.build 
b/src/bindings/mono/efl_mono/meson.build
index 9134de5bbd..acfeb4bc3f 100644
--- a/src/bindings/mono/efl_mono/meson.build
+++ b/src/bindings/mono/efl_mono/meson.build
@@ -1,4 +1,7 @@
-mono_files += files('efl_all.cs')
+mono_files += files(
+  'efl_all.cs',
+  'efl_csharp_application.cs'
+  )
 
 bash = find_program('bash')
 

-- 


Reply via email to