# HG changeset patch # User Medo # Date 1345739313 -7200 # Node ID 27e5857da6afea4978b46afa2b8b6537b2bf4e38 # Parent 33924ff4af504d24ce7f8ccb400fabdf16d3cb14 Hedgeroid improvements: - Moved frontlib initialization to a slightly better place - Added new JNA type ByteArrayPtr to move more JNA code into the frontlib package and to improve pointer type safety diff -r 33924ff4af50 -r 27e5857da6af project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/GameConnection.java --- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/GameConnection.java Wed Aug 22 01:30:56 2012 +0200 +++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/GameConnection.java Thu Aug 23 18:28:33 2012 +0200 @@ -24,6 +24,7 @@ import org.hedgewars.hedgeroid.Datastructures.GameConfig; import org.hedgewars.hedgeroid.frontlib.Flib; import org.hedgewars.hedgeroid.frontlib.Frontlib; +import org.hedgewars.hedgeroid.frontlib.Frontlib.ByteArrayPtr; import org.hedgewars.hedgeroid.frontlib.Frontlib.BytesCallback; import org.hedgewars.hedgeroid.frontlib.Frontlib.GameSetupPtr; import org.hedgewars.hedgeroid.frontlib.Frontlib.GameconnPtr; @@ -41,7 +42,6 @@ import android.os.Looper; import android.util.Log; -import com.sun.jna.Memory; import com.sun.jna.Pointer; /** @@ -172,8 +172,8 @@ // runs on the IPCThread private final BytesCallback engineMessageCb = new BytesCallback() { - public void callback(Pointer context, Pointer buffer, NativeSizeT size) { - netplay.sendEngineMessage(buffer.getByteArray(0, size.intValue())); + public void callback(Pointer context, ByteArrayPtr buffer, NativeSizeT size) { + netplay.sendEngineMessage(buffer.deref(size.intValue())); } }; @@ -205,9 +205,8 @@ public void onEngineMessage(final byte[] em) { handler.post(new Runnable() { public void run() { - Memory mem = new Memory(em.length); - mem.write(0, em, 0, em.length); - Flib.INSTANCE.flib_gameconn_send_enginemsg(conn, mem, NativeSizeT.valueOf(em.length)); + ByteArrayPtr ptr = ByteArrayPtr.createJavaOwned(em); + Flib.INSTANCE.flib_gameconn_send_enginemsg(conn, ptr, NativeSizeT.valueOf(em.length)); } }); } diff -r 33924ff4af50 -r 27e5857da6af project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/MapPreviewGenerator.java --- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/MapPreviewGenerator.java Wed Aug 22 01:30:56 2012 +0200 +++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/MapPreviewGenerator.java Thu Aug 23 18:28:33 2012 +0200 @@ -27,6 +27,7 @@ import org.hedgewars.hedgeroid.EngineProtocol.PascalExports; import org.hedgewars.hedgeroid.frontlib.Flib; import org.hedgewars.hedgeroid.frontlib.Frontlib; +import org.hedgewars.hedgeroid.frontlib.Frontlib.ByteArrayPtr; import org.hedgewars.hedgeroid.frontlib.Frontlib.MapRecipePtr; import org.hedgewars.hedgeroid.frontlib.Frontlib.MapconnPtr; import org.hedgewars.hedgeroid.frontlib.Frontlib.MapimageCallback; @@ -161,8 +162,8 @@ * Since the image is present in bytes, we can save some effort by checking entire byte-columns first. */ private final MapimageCallback successCb = new MapimageCallback() { - public void callback(Pointer context, Pointer buffer, int hedgehogCount) { - byte[] mapdata = buffer.getByteArray(0, Frontlib.MAPIMAGE_BYTES); + public void callback(Pointer context, ByteArrayPtr buffer, int hedgehogCount) { + byte[] mapdata = buffer.deref(Frontlib.MAPIMAGE_BYTES); int leftmostPixel = Frontlib.MAPIMAGE_WIDTH; int rightmostPixel = -1; diff -r 33924ff4af50 -r 27e5857da6af project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/frontlib/Flib.java --- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/frontlib/Flib.java Wed Aug 22 01:30:56 2012 +0200 +++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/frontlib/Flib.java Thu Aug 23 18:28:33 2012 +0200 @@ -33,6 +33,13 @@ } public static final Frontlib INSTANCE = (Frontlib)Native.loadLibrary("frontlib", Frontlib.class, Collections.singletonMap(Library.OPTION_TYPE_MAPPER, AndroidTypeMapper.INSTANCE)); + static { + // We'll just do it here and never quit it again... + if(Flib.INSTANCE.flib_init() != 0) { + throw new RuntimeException("Unable to initialize frontlib"); + } + } + // Hook frontlib logging into Android logging private static final Frontlib.LogCallback logCb = new Frontlib.LogCallback() { public void callback(int level, String message) { diff -r 33924ff4af50 -r 27e5857da6af project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/frontlib/Frontlib.java --- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/frontlib/Frontlib.java Wed Aug 22 01:30:56 2012 +0200 +++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/frontlib/Frontlib.java Thu Aug 23 18:28:33 2012 +0200 @@ -320,6 +320,33 @@ } } + public static class ByteArrayPtr extends PointerType { + public byte[] deref(int size) { + return getPointer().getByteArray(0, size); + } + + public static byte[] deref(ByteArrayPtr ptr, int size) { + if(ptr==null && size==0) { + return null; + } else { + return ptr.deref(size); + } + } + + public static ByteArrayPtr createJavaOwned(byte[] buffer) { + if(buffer == null) { + return null; + } + // no need for javaOwnedInstance here because PointerType + // remembers the memory as its Pointer + Pointer ptr = new Memory(buffer.length); + ptr.write(0, buffer, 0, buffer.length); + ByteArrayPtr result = new ByteArrayPtr(); + result.setPointer(ptr); + return result; + } + } + static class HogStruct extends Structure { public static class ByVal extends HogStruct implements Structure.ByValue {} public static class ByRef extends HogStruct implements Structure.ByReference {} @@ -566,24 +593,14 @@ seed = map.seed; theme = map.theme; byte[] buf = map.getDrawData(); - if(buf != null) { - drawData = new Memory(buf.length); - drawData.write(0, buf, 0, buf.length); - drawDataSize = NativeSizeT.valueOf(buf.length); - } else { - drawData = null; - drawDataSize = NativeSizeT.valueOf(0); - } + drawData = ByteArrayPtr.createJavaOwned(buf); + drawDataSize = NativeSizeT.valueOf(buf==null ? 0 : buf.length); templateFilter = map.templateFilter; mazeSize = map.mazeSize; } public MapRecipe toMapRecipe() { - byte[] buf = null; - if(drawData != null && drawDataSize.intValue()>0) { - buf = new byte[drawDataSize.intValue()]; - drawData.read(0, buf, 0, drawDataSize.intValue()); - } + byte[] buf = ByteArrayPtr.deref(drawData, drawDataSize.intValue()); return new MapRecipe(mapgen, templateFilter, mazeSize, name, seed, theme, buf); } @@ -591,7 +608,7 @@ public String name; public String seed; public String theme; - public Pointer drawData; + public ByteArrayPtr drawData; public NativeSizeT drawDataSize; public int templateFilter; public int mazeSize; @@ -948,11 +965,11 @@ } public static interface BytesCallback extends Callback { - void callback(Pointer context, Pointer buffer, NativeSizeT size); + void callback(Pointer context, ByteArrayPtr buffer, NativeSizeT size); } public static interface BytesBoolCallback extends Callback { - void callback(Pointer context, Pointer buffer, NativeSizeT size, boolean arg3); + void callback(Pointer context, ByteArrayPtr buffer, NativeSizeT size, boolean arg3); } public static interface SchemeCallback extends Callback { @@ -968,7 +985,7 @@ } public static interface MapimageCallback extends Callback { - void callback(Pointer context, Pointer buffer, int hedgehogCount); + void callback(Pointer context, ByteArrayPtr buffer, int hedgehogCount); } public static interface LogCallback extends Callback { @@ -1035,7 +1052,7 @@ int flib_netconn_send_toggleReady(NetconnPtr conn); int flib_netconn_send_addTeam(NetconnPtr conn, TeamPtr team); int flib_netconn_send_removeTeam(NetconnPtr conn, String teamname); - int flib_netconn_send_engineMessage(NetconnPtr conn, Pointer message, NativeSizeT size); + int flib_netconn_send_engineMessage(NetconnPtr conn, ByteArrayPtr message, NativeSizeT size); int flib_netconn_send_teamHogCount(NetconnPtr conn, String teamname, int hogcount); int flib_netconn_send_teamColor(NetconnPtr conn, String teamname, int colorIndex); int flib_netconn_send_weaponset(NetconnPtr conn, WeaponsetPtr weaponset); @@ -1046,7 +1063,7 @@ int flib_netconn_send_mapMazeSize(NetconnPtr conn, int mazeSize); int flib_netconn_send_mapSeed(NetconnPtr conn, String seed); int flib_netconn_send_mapTheme(NetconnPtr conn, String theme); - int flib_netconn_send_mapDrawdata(NetconnPtr conn, Pointer drawData, NativeSizeT size); + int flib_netconn_send_mapDrawdata(NetconnPtr conn, ByteArrayPtr drawData, NativeSizeT size); int flib_netconn_send_script(NetconnPtr conn, String scriptName); int flib_netconn_send_scheme(NetconnPtr conn, SchemePtr scheme); int flib_netconn_send_roundfinished(NetconnPtr conn, boolean withoutError); @@ -1100,15 +1117,15 @@ static final int GAME_END_ERROR = 3; GameconnPtr flib_gameconn_create(String playerName, GameSetupPtr setup, boolean netgame); - GameconnPtr flib_gameconn_create_playdemo(Pointer demo, NativeSizeT size); - GameconnPtr flib_gameconn_create_loadgame(String playerName, Pointer save, NativeSizeT size); + GameconnPtr flib_gameconn_create_playdemo(ByteArrayPtr demo, NativeSizeT size); + GameconnPtr flib_gameconn_create_loadgame(String playerName, ByteArrayPtr save, NativeSizeT size); GameconnPtr flib_gameconn_create_campaign(String playerName, String seed, String script); void flib_gameconn_destroy(GameconnPtr conn); int flib_gameconn_getport(GameconnPtr conn); void flib_gameconn_tick(GameconnPtr conn); - int flib_gameconn_send_enginemsg(GameconnPtr conn, Pointer data, NativeSizeT len); + int flib_gameconn_send_enginemsg(GameconnPtr conn, ByteArrayPtr data, NativeSizeT len); int flib_gameconn_send_textmsg(GameconnPtr conn, int msgtype, String msg); int flib_gameconn_send_chatmsg(GameconnPtr conn, String playername, String msg); int flib_gameconn_send_quit(GameconnPtr conn); diff -r 33924ff4af50 -r 27e5857da6af project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/netplay/Netplay.java --- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/netplay/Netplay.java Wed Aug 22 01:30:56 2012 +0200 +++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/netplay/Netplay.java Thu Aug 23 18:28:33 2012 +0200 @@ -39,7 +39,6 @@ import org.hedgewars.hedgeroid.Datastructures.TeamIngameAttributes; import org.hedgewars.hedgeroid.Datastructures.Weaponset; import org.hedgewars.hedgeroid.Datastructures.Weaponsets; -import org.hedgewars.hedgeroid.frontlib.Flib; import org.hedgewars.hedgeroid.netplay.ThreadedNetConnection.ToNetMsgType; import org.hedgewars.hedgeroid.util.ObservableTreeMap; @@ -198,11 +197,6 @@ */ public static Netplay getAppInstance(Context applicationContext) { if(instance == null) { - // We'll just do it here and never quit it again... - if(Flib.INSTANCE.flib_init() != 0) { - throw new RuntimeException("Unable to start frontlib"); - } - // We will need some default values for rooms, best load them here Scheme defaultScheme = null; Weaponset defaultWeaponset = null; diff -r 33924ff4af50 -r 27e5857da6af project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/netplay/ThreadedNetConnection.java --- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/netplay/ThreadedNetConnection.java Wed Aug 22 01:30:56 2012 +0200 +++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/netplay/ThreadedNetConnection.java Thu Aug 23 18:28:33 2012 +0200 @@ -35,6 +35,7 @@ import org.hedgewars.hedgeroid.frontlib.Flib; import org.hedgewars.hedgeroid.frontlib.Frontlib; import org.hedgewars.hedgeroid.frontlib.Frontlib.BoolCallback; +import org.hedgewars.hedgeroid.frontlib.Frontlib.ByteArrayPtr; import org.hedgewars.hedgeroid.frontlib.Frontlib.BytesCallback; import org.hedgewars.hedgeroid.frontlib.Frontlib.GameSetupPtr; import org.hedgewars.hedgeroid.frontlib.Frontlib.IntStrCallback; @@ -73,7 +74,6 @@ import android.util.Log; import android.util.Pair; -import com.sun.jna.Memory; import com.sun.jna.Pointer; /** @@ -128,7 +128,7 @@ return; } - //FLIB.flib_netconn_onAdminAccess(conn, adminAccessCb, null) + // FLIB.flib_netconn_onAdminAccess(conn, adminAccessCb, null) FLIB.flib_netconn_onSchemeChanged(conn, cfgSchemeCb, null); FLIB.flib_netconn_onChat(conn, chatCb, null); FLIB.flib_netconn_onConnected(conn, connectedCb, null); @@ -331,8 +331,8 @@ }; private final BytesCallback engineMessageCb = new BytesCallback() { - public void callback(Pointer context, Pointer buffer, NativeSizeT size) { - sendFromNet(MSG_ENGINE_MESSAGE, buffer.getByteArray(0, size.intValue())); + public void callback(Pointer context, ByteArrayPtr buffer, NativeSizeT size) { + sendFromNet(MSG_ENGINE_MESSAGE, buffer.deref(size.intValue())); } }; @@ -512,9 +512,8 @@ } case MSG_SEND_ENGINE_MESSAGE: { byte[] message = (byte[])msg.obj; - Memory mem = new Memory(message.length); - mem.write(0, message, 0, message.length); - FLIB.flib_netconn_send_engineMessage(conn, mem, NativeSizeT.valueOf(message.length)); + ByteArrayPtr ptr = ByteArrayPtr.createJavaOwned(message); + FLIB.flib_netconn_send_engineMessage(conn, ptr, NativeSizeT.valueOf(message.length)); break; } case MSG_SEND_ROUND_FINISHED: { @@ -563,9 +562,8 @@ } case MSG_SEND_MAP_DRAWDATA: { byte[] message = (byte[])msg.obj; - Memory mem = new Memory(message.length); - mem.write(0, message, 0, message.length); - FLIB.flib_netconn_send_mapDrawdata(conn, mem, NativeSizeT.valueOf(message.length)); + ByteArrayPtr ptr = ByteArrayPtr.createJavaOwned(message); + FLIB.flib_netconn_send_mapDrawdata(conn, ptr, NativeSizeT.valueOf(message.length)); break; } case MSG_SEND_GAMESTYLE: { diff -r 33924ff4af50 -r 27e5857da6af project_files/frontlib/extra/jnacontrol.c --- a/project_files/frontlib/extra/jnacontrol.c Wed Aug 22 01:30:56 2012 +0200 +++ b/project_files/frontlib/extra/jnacontrol.c Thu Aug 23 18:28:33 2012 +0200 @@ -67,6 +67,7 @@ typedef bool boolean; typedef size_t NativeSizeT; typedef void *Pointer; +typedef uint8_t *ByteArrayPtr; typedef char *String; /* @@ -96,7 +97,7 @@ * Below here are the copypasted method declarations from the JNA bindings */ -// frontlib.h + // frontlib.h int flib_init(); void flib_quit(); @@ -127,6 +128,7 @@ int flib_netconn_send_toggleReady(NetconnPtr conn); int flib_netconn_send_addTeam(NetconnPtr conn, TeamPtr team); int flib_netconn_send_removeTeam(NetconnPtr conn, String teamname); + int flib_netconn_send_engineMessage(NetconnPtr conn, ByteArrayPtr message, NativeSizeT size); int flib_netconn_send_teamHogCount(NetconnPtr conn, String teamname, int hogcount); int flib_netconn_send_teamColor(NetconnPtr conn, String teamname, int colorIndex); int flib_netconn_send_weaponset(NetconnPtr conn, WeaponsetPtr weaponset); @@ -137,6 +139,7 @@ int flib_netconn_send_mapMazeSize(NetconnPtr conn, int mazeSize); int flib_netconn_send_mapSeed(NetconnPtr conn, String seed); int flib_netconn_send_mapTheme(NetconnPtr conn, String theme); + int flib_netconn_send_mapDrawdata(NetconnPtr conn, ByteArrayPtr drawData, NativeSizeT size); int flib_netconn_send_script(NetconnPtr conn, String scriptName); int flib_netconn_send_scheme(NetconnPtr conn, SchemePtr scheme); int flib_netconn_send_roundfinished(NetconnPtr conn, boolean withoutError); @@ -184,13 +187,17 @@ void flib_netconn_onServerVar(NetconnPtr conn, StrStrCallback callback, Pointer context); // ipc/gameconn.h + GameconnPtr flib_gameconn_create(String playerName, GameSetupPtr setup, boolean netgame); + GameconnPtr flib_gameconn_create_playdemo(ByteArrayPtr demo, NativeSizeT size); + GameconnPtr flib_gameconn_create_loadgame(String playerName, ByteArrayPtr save, NativeSizeT size); GameconnPtr flib_gameconn_create_campaign(String playerName, String seed, String script); void flib_gameconn_destroy(GameconnPtr conn); int flib_gameconn_getport(GameconnPtr conn); void flib_gameconn_tick(GameconnPtr conn); + int flib_gameconn_send_enginemsg(GameconnPtr conn, ByteArrayPtr data, NativeSizeT len); int flib_gameconn_send_textmsg(GameconnPtr conn, int msgtype, String msg); int flib_gameconn_send_chatmsg(GameconnPtr conn, String playername, String msg); int flib_gameconn_send_quit(GameconnPtr conn); @@ -229,5 +236,6 @@ // model/gamesetup.h void flib_gamesetup_destroy(GameSetupPtr gamesetup); + // util/logging.h void flib_log_setLevel(int level); void flib_log_setCallback(LogCallback callback);