ecere/gui/AndroidInterface: Fixed issues running Blokus sample
authorJerome St-Louis <jerome@ecere.com>
Wed, 14 Nov 2012 09:14:37 +0000 (04:14 -0500)
committerJerome St-Louis <jerome@ecere.com>
Wed, 14 Nov 2012 09:14:37 +0000 (04:14 -0500)
- Fixed hangs in input handling and modal loops
- Fixed GuiApplication::lockMutex being wrongly locked/unlocked in initialization and termination
- Added more debugging tools to Mutex class
- Added android files to Blokus sample

ecere/ecere.epj
ecere/src/gui/GuiApplication.ec
ecere/src/gui/drivers/AndroidInterface.ec
ecere/src/sys/Mutex.ec
samples/eC/staticLink/staticLink.epj
samples/games/blokus/BlokusServer.ec
samples/games/blokus/android/AndroidManifest.xml [new file with mode: 0644]
samples/games/blokus/android/res/values/strings.xml [new file with mode: 0644]
samples/games/blokus/blokus.epj

index 35f2757..da0d29e 100644 (file)
       {
          "Name" : "Android",
          "Options" : {
-            "Optimization" : "Speed",
+            "Debug" : true,
+            "Optimization" : "None",
             "PreprocessorDefinitions" : [
-               "ECERE_NOFONTCONFIG"
+               "ECERE_NOFONTCONFIG",
+               "_DEBUG"
             ],
             "IncludeDirs" : [
                "../deps/jpeg-6b",
                }
             }
          ]
+      },
+      {
+         "FileName" : "C:/Windows/Fonts/arial.ttf",
+         "Options" : {
+            "ExcludeFromBuild" : true
+         },
+         "Configurations" : [
+            {
+               "Name" : "Android",
+               "Options" : {
+                  "ExcludeFromBuild" : false
+               }
+            }
+         ]
+      },
+      {
+         "FileName" : "C:/Windows/Fonts/arialbd.ttf",
+         "Options" : {
+            "ExcludeFromBuild" : true
+         },
+         "Configurations" : [
+            {
+               "Name" : "Android",
+               "Options" : {
+                  "ExcludeFromBuild" : false
+               }
+            }
+         ]
       }
    ],
    "Description" : "The allmighty Ecere Runtime library.",
index 9f8a47d..eef2e69 100644 (file)
@@ -224,7 +224,10 @@ public class GuiApplication : Application
          XUnlockDisplay(xGlobalDisplay);
 #endif
 
+#if !defined(__ANDROID__)
+      // Because destruction of app won't be from main thread
       lockMutex.Release();
+#endif
 
       if(interfaceDriver)
       {
@@ -730,6 +733,11 @@ public:
          }
       }
       Terminate();
+
+#if defined(__ANDROID__)
+      // Because destruction of GuiApp won't be from main thread
+      lockMutex.Release();
+#endif
    }
 
    void Wait(void)
index c30934d..6eb69e5 100644 (file)
@@ -133,7 +133,7 @@ private:
             if(AInputQueue_preDispatchEvent(inputQueue, event))
                return;
             handled = onInputEvent(event);
-            AInputQueue_finishEvent(inputQueue, event, handled);
+            //AInputQueue_finishEvent(inputQueue, event, handled);
          }
          else
             LOGE("Failure reading next input event: %s\n", strerror(errno));
@@ -150,7 +150,9 @@ private:
    void free_saved_state()
    {
       mutex.Wait();
-      free(savedState);
+      if(savedState)
+         free(savedState);
+      savedState = 0;
       savedStateSize = 0;
       mutex.Release();
    }
@@ -312,7 +314,9 @@ private:
 
    void setSavedState(void * state, uint size)
    {
-      free(savedState);
+      if(savedState)
+         free(savedState);
+      savedState = null;
       if(state)
       {
          savedState = malloc(size);
@@ -568,10 +572,13 @@ class AndroidInterface : Interface
       bool eventAvailable = false;
       if(androidActivity.ident >= 0)
       {
+         AndroidPollSource source = androidActivity.source;
          //PrintLn("androidActivity.ident >= 0");
          // Process this event.
-         if(androidActivity.source)
-            androidActivity.source.process(androidActivity.source.userData);
+         androidActivity.ident = 0;
+         androidActivity.source = null;
+         if(source)
+            source.process(source.userData);
 
          // If a sensor has data, process it now.
          /*
@@ -592,7 +599,7 @@ class AndroidInterface : Interface
             eventAvailable = true;
          }
       }
-      androidActivity.ident = 0;
+
       if(androidActivity.animating)
          guiApp.desktop.Update(null);
 
@@ -913,6 +920,7 @@ class AndroidActivity : AndroidAppGlue
          int x = (int)AMotionEvent_getX(event, 0);
          int y = (int)AMotionEvent_getY(event, 0);
 
+         AInputQueue_finishEvent(inputQueue, event, 1);
          switch(action)
          {
             case AMOTION_EVENT_ACTION_DOWN:
@@ -939,7 +947,11 @@ class AndroidActivity : AndroidAppGlue
          uint flags = AKeyEvent_getFlags(event);
          uint keyCode = AKeyEvent_getKeyCode(event);
          uint meta = AKeyEvent_getMetaState(event);
+
+         AInputQueue_finishEvent(inputQueue, event, 1);
       }
+      else
+         AInputQueue_finishEvent(inputQueue, event, 0);
       return 0;
    }
 
@@ -1020,8 +1032,9 @@ class AndroidActivity : AndroidAppGlue
          guiApp.interfaceDriver = class(AndroidInterface);
          while(!gotInit)
          {
-            guiApp.Wait();
-            guiApp.ProcessInput(true);
+            // Can't call the GuiApplication here, because GuiApplication::Initialize() has not been called yet
+            guiApp.interfaceDriver.Wait();
+            guiApp.interfaceDriver.ProcessInput(true);
          }
 
          // Invoke __ecereDll_Load() in lib[our package name].so
@@ -1051,8 +1064,8 @@ class AndroidActivity : AndroidAppGlue
             ANativeActivity_finish(activity);
          while(!destroyRequested)
          {
-            guiApp.Wait();
-            guiApp.ProcessInput(true);
+            guiApp.interfaceDriver.Wait();
+            guiApp.interfaceDriver.ProcessInput(true);
          }
       }
    }
index a0ffb73..a686193 100644 (file)
@@ -1,3 +1,9 @@
+#if defined(__ANDROID__)
+#include <android/log.h>
+
+#define printf(...)  ((void)__android_log_print(ANDROID_LOG_VERBOSE, "ecere-app", __VA_ARGS__))
+#endif
+
 namespace sys;
 
 #define _GNU_SOURCE
@@ -102,8 +108,17 @@ public:
          EnterCriticalSection(&mutex);
 #endif
 #else
+#ifdef _DEBUG
+         {
+            int e;
+            e = pthread_mutex_lock(&mutex);
+            if(e)
+               PrintLn("pthread_mutex_lock returned ", e);
+         }
+#else
          pthread_mutex_lock(&mutex);
 #endif
+#endif
 
 #ifdef _DEBUG
          owningThread = GetCurrentThreadID();
@@ -120,6 +135,10 @@ public:
          if(this == globalSystem.fileMonitorMutex)
             printf("[%d] Releasing Mutex %x\n", GetCurrentThreadID(), this);
          */
+#ifdef _DEBUG
+         if(lockCount && owningThread != GetCurrentThreadID())
+            PrintLn("WARNING: Not in owning thread!!");
+#endif
 
          if(!--lockCount)
 #ifdef _DEBUG
@@ -134,8 +153,21 @@ public:
          LeaveCriticalSection(&mutex);
 #endif
 #else
+#ifdef _DEBUG
+         {
+            int e;
+            e = pthread_mutex_unlock(&mutex);
+            if(e)
+               PrintLn("pthread_mutex_unlock returned ", e);
+         }
+#else
          pthread_mutex_unlock(&mutex);
 #endif
+#endif
+#ifdef _DEBUG
+         if(lockCount < 0)
+            PrintLn("WARNING: lockCount < 0");
+#endif
       }
    }
 };
index 060dba9..776ad81 100644 (file)
@@ -60,7 +60,7 @@
                      "z"
                   ],
                   "LibraryDirs" : [
-                     "../../deps/zlib/obj/release.$(PLATFORM)"
+                     "../../../deps/zlib/obj/release.$(PLATFORM)"
                   ]
                }
             }
index a34ab4e..5536604 100644 (file)
@@ -28,7 +28,7 @@ public struct GameInfo
    }
 };
 
-class Player
+public class Player
 {
    ServerConnection connection;
    int id;
@@ -130,7 +130,7 @@ void EndGame()
 }
 
 //////////////////////////////////////////
-remote class ServerConnection
+public remote class ServerConnection
 {
 public:
    // Remote Functions
diff --git a/samples/games/blokus/android/AndroidManifest.xml b/samples/games/blokus/android/AndroidManifest.xml
new file mode 100644 (file)
index 0000000..6126086
--- /dev/null
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- BEGIN_INCLUDE(manifest) -->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+        package="com.ecere.Blokus"
+        android:versionCode="1"
+        android:versionName="1.0">
+
+    <!-- This is the platform API where NativeActivity was introduced. -->
+    <uses-sdk android:minSdkVersion="9" />
+    <uses-permission android:name="android.permission.INTERNET" />
+
+    <!-- This .apk has no Java code itself, so set hasCode to false. -->
+    <application android:label="@string/app_name" android:hasCode="false" android:icon="@drawable/icon">
+
+        <!-- Our activity is the built-in NativeActivity framework class. This will take care of integrating with our NDK code. -->
+        <activity android:name="android.app.NativeActivity"
+                  android:label="@string/app_name"
+                  android:configChanges="orientation|keyboardHidden">
+            <!-- Tell NativeActivity the name of our .so -->
+            <meta-data android:name="android.app.lib_name"
+                       android:value="ecere" />
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+    </application>
+
+</manifest> 
+<!-- END_INCLUDE(manifest) -->
diff --git a/samples/games/blokus/android/res/values/strings.xml b/samples/games/blokus/android/res/values/strings.xml
new file mode 100644 (file)
index 0000000..426d524
--- /dev/null
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+    <string name="app_name">Ecere Blokus</string>
+</resources>
index da84c1c..91c39aa 100644 (file)
             "Console" : true,
             "FastMath" : false
          }
+      },
+      {
+         "Name" : "Android",
+         "Options" : {
+            "Optimization" : "Speed",
+            "TargetType" : "SharedLibrary",
+            "PostbuildCommands" : [
+               "$(call mkdirq,$(OBJ)apk/lib/x86)",
+               "$(call mkdirq,$(OBJ)apk/lib/armeabi)",
+               "$(call cpq,/sdk/ecere/obj/android.linux.$(COMPILER)/libecere.so,$(OBJ)apk/lib/x86)",
+               "$(call cpq,$(TARGET),$(OBJ)apk/lib/x86)",
+               "aapt package -v -f -m -M android/AndroidManifest.xml -F $(OBJ)$(MODULE)-unsigned.apk -I C:/android-sdk/platforms/android-16/android.jar -S android/res $(OBJ)apk",
+               "jarsigner -storepass mypassword -sigalg MD5withRSA -digestalg SHA1 $(OBJ)$(MODULE)-unsigned.apk mykey -signedjar $(OBJ)$(MODULE).apk",
+               "adb uninstall com.ecere.Blokus",
+               "adb install $(OBJ)$(MODULE).apk",
+               "adb shell am start -a android.intent.action.MAIN -n com.ecere.Blokus/android.app.NativeActivity"
+            ]
+         }
       }
    ],
    "Files" : [
+      {
+         "Folder" : "android",
+         "Files" : [
+            {
+               "Folder" : "res",
+               "Files" : [
+                  {
+                     "Folder" : "values",
+                     "Files" : [
+                        "strings.xml"
+                     ]
+                  },
+                  {
+                     "Folder" : "drawable",
+                     "Files" : [
+                        {
+                           "FileName" : "icon.png",
+                           "Options" : {
+                              "ExcludeFromBuild" : true
+                           }
+                        }
+                     ]
+                  },
+                  {
+                     "Folder" : "drawable-xhdpi",
+                     "Files" : [
+                        "icon.png"
+                     ]
+                  }
+               ]
+            },
+            "AndroidManifest.xml"
+         ]
+      },
       "blokus.ec",
       "BlokusServer.ec",
       "../../net/eirc/console.ec"