Quick Links: Gideros Home | Download Gideros | Developer Guide
iCade plugin
  • I have not tested this one bit or even tried to compile it. This is what I came up with by looking at the storekit, gamekit, and uikit plugins.

    If anyone has any comments or corrections by just looking (I don't exactly expect anyone to test it for me), I'd appreciate it.

    @Caroline, you are hosting the MHUIKit plugin. I've never used GitHub so I was thinking maybe you would like to host this? I also noticed that you seem to be the plugin expert, so you would be a perfect choice to host this! ;)

    EDITS:

    Fixed a bug

    Included usage

    This requires the 3 files at the following URL:
    https://github.com/scarnie/iCade-iOS/tree/master/iCadeTest/iCade

    And this will require some lua code to interpret the events. I'll write some code to do that tomorrow.


    /*

    This code is MIT licensed, see http://www.opensource.org/licenses/mit-license.php

    Events:
    iCadeStateChanged
    iCadeButtonUp
    iCadeButtonDown

    Each event has an int that contains the state of the icade: event.state. The values of the state variable are shown in iCadeState.h (see https://github.com/scarnie/iCade-iOS/tree/master/iCadeTest/iCade)

    Methods:
    BOOL isActive()
    setActive(BOOL)
    int iCadeState()

    */

    #include "gideros.h"
    #include "lua.h"
    #include "lauxlib.h"

    #import "iCadeReaderView.h"

    static const char KEY_OBJECTS = ' ';

    static const char* STATE_CHANGED = "iCadeStateChanged";
    static const char* BUTTON_UP = "iCadeButtonUp";
    static const char* BUTTON_DOWN = "iCadeButtonDown";

    static void dispatchEvent(lua_State* L, const char* type,
    (iCadeState) state)
    {
    lua_pushlightuserdata(L, (void *)&KEY_OBJECTS);
    lua_rawget(L, LUA_REGISTRYINDEX);

    lua_rawgeti(L, -1, 1);

    if (lua_isnil(L, -1))
    {
    lua_pop(L, 2);
    return;
    }

    lua_getfield(L, -1, "dispatchEvent");

    lua_pushvalue(L, -2);

    lua_getglobal(L, "Event");
    lua_getfield(L, -1, "new");
    lua_remove(L, -2);
    lua_pushstring(L, type);
    lua_call(L, 1, 1);

    lua_pushinteger(L, state);
    lua_setfield(L, -2, "state");

    if (lua_pcall(L, 2, 0, 0) != 0)
    g_error(L, lua_tostring(L, -1));

    lua_pop(L, 2);
    }

    @interface iCadeHelper : NSObject
    iCadeReaderView* control;
    lua_State* L;
    @end

    @implementation iCadeHelper
    - (id)initWithLuaState:(lua_State *)theL
    {
    if (self = [super init])
    {
    L = theL;
    control = [[iCadeReaderView alloc] initWithFrame:CGRectZero];
    control.active = YES;
    control.delegate = self;
    UIViewController* controller = g_getRootViewController();
    [controller.view addSubview:control];
    }
    return self;
    }
    - (void)dealloc {
    [control removeFromSuperview];
    [control release];
    }
    - (void)setActive:(BOOL)state {
    control.active = state;
    }
    - (BOOL)isActive {
    return control.active;
    }
    - (iCadeState)iCadeState {
    return control.iCadeState;
    }
    - (void)stateChanged:(iCadeState)state {
    dispatchEvent(L, STATE_CHANGED, state);
    }
    - (void)buttonDown:(iCadeState)button {
    dispatchEvent(L, BUTTON_DOWN, button);
    }
    - (void)buttonUp:(iCadeState)button {
    dispatchEvent(L, BUTTON_UP, button);
    }

    @end

    class iCade : public GEventDispatcherProxy
    {
    public:
    iCade(lua_State* L) : L(L)
    {
    helper = [[iCadeHelper alloc] initWithLuaState:L];
    }

    ~iCade()
    {
    [helper release];
    }

    BOOL isActive()
    {
    return [helper isActive];
    }

    void setActive(BOOL state)
    {
    [helper setActive:state];
    }

    iCadeState iCadeState()
    {
    return [helper iCadeState];
    }

    private:
    lua_State* L;
    iCadeHelper* helper;
    };

    static int destruct(lua_State* L)
    {
    void* ptr = *(void**)lua_touserdata(L, 1);
    GReferenced* object = static_cast(ptr);
    iCade* icade = static_cast(object->proxy());

    icade->unref();

    return 0;
    }

    static iCade* getInstance(lua_State* L, int index)
    {
    GReferenced* object = static_cast(g_getInstance(L, "iCade", index));
    iCade* icade = static_cast(object->proxy());

    return icade;
    }

    static int isActive(lua_State* L)
    {
    iCade* icade = getInstance(L, 1);

    lua_pushboolean(L, icade->isActive());

    return 1;
    }

    static int setActive(lua_State* L)
    {
    iCade* icade = getInstance(L, 1);
    bool state = lua_toboolean(L, 2);
    icade->setActive(state);

    return 0;
    }

    static int iCadeState(lua_State* L)
    {
    iCade* icade = getInstance(L, 1);

    lua_pushinteger(L, icade->iCadeState());

    return 1;
    }

    static int loader(lua_State* L)
    {
    const luaL_Reg functionlist[] = {
    {"isActive", isActive},
    {"setActive", setActive},
    {"iCadeState", iCadeState},
    {NULL, NULL},
    };

    g_createClass(L, "iCade", "EventDispatcher", NULL, destruct, functionlist);

    lua_getglobal(L, "Event");
    lua_pushstring(L, STATE_CHANGED);
    lua_setfield(L, -2, "STATE_CHANGED");
    lua_pushstring(L, BUTTON_UP);
    lua_setfield(L, -2, "BUTTON_UP");
    lua_pushstring(L, BUTTON_DOWN);
    lua_setfield(L, -2, "BUTTON_DOWN");
    lua_pop(L, 1);

    // create a weak table in LUA_REGISTRYINDEX that can be accessed with the address of KEY_OBJECTS
    lua_pushlightuserdata(L, (void *)&KEY_OBJECTS);
    lua_newtable(L); // create a table
    lua_pushliteral(L, "v");
    lua_setfield(L, -2, "__mode"); // set as weak-value table
    lua_pushvalue(L, -1); // duplicate table
    lua_setmetatable(L, -2); // set itself as metatable
    lua_rawset(L, LUA_REGISTRYINDEX);

    iCade* icade = new iCade(L);
    g_pushInstance(L, "iCade", icade->object());

    lua_pushlightuserdata(L, (void *)&KEY_OBJECTS);
    lua_rawget(L, LUA_REGISTRYINDEX);
    lua_pushvalue(L, -2);
    lua_rawseti(L, -2, 1);
    lua_pop(L, 1);

    lua_pushvalue(L, -1);
    lua_setglobal(L, "icade");

    return 1;
    }

    static void g_initializePlugin(lua_State* L)
    {
    lua_getglobal(L, "package");
    lua_getfield(L, -1, "preload");

    lua_pushcfunction(L, loader);
    lua_setfield(L, -2, "icade");

    lua_pop(L, 2);
    }

    static void g_deinitializePlugin(lua_State *L)
    {

    }

    REGISTER_PLUGIN("iCade", "1.0")

  • 1. I'm just a wannabe plugin expert - I have to have 3 hours of uninterrupted concentration and a lot of stack dumps to do anything with them.

    2. It feels to me that the dispatch function is wrong - it should be in the iCade class - I think that you are looking up "dispatchEvent" in a table where it doesn't exist. The iCade class descends from GEventDispatcherProxy, which allows it to dispatch events. (See gamekit.mm for example)

    3. I would be happy to host when it's more fully tested, although I had not used github before, so am no expert. However, you could work out how to host in under an hour - there's even a github app if you don't like working through Terminal. Then it's easier for you to make changes - if this is something that you're working on, it makes more sense for you to host.

    4. Some things might be wrong (not sure, just put into Xcode, compiled, and picked the obvious things)

    needs - #import "iCadeState.h"

    static void dispatchEvent(lua_State* L, const char* type, (iCadeState) state)
    should be
    static void dispatchEvent(lua_State* L, const char* type, iCadeState state)

    @interface iCadeHelper : NSObject
    should be
    @interface iCadeHelper : NSObject < iCadeEventDelegate >

    and you need { } around the @interface variables.

    You don't need the dealloc if you release the view after addSubview, and if you have dealloc, you need [super dealloc] (unless you are using ARC, in which case you don't have to worry about releases).

    You can't have a function called iCadeState, as it's already defined in iCadeState.h

    Your destruct and getInstance needs to have a <> casting as in:
    GReferenced* object = static_cast< GReferenced* >(ptr);
    iCade* icade = static_cast< iCade* >(object->proxy());

    I haven't gone through the lua stack stuff, so not sure if you've got that right. I tend to that by trial and stack dump.
  • I forgot to say, that I'm impressed so far, and would love to see this working on your iCade.
    (Wants...)
  • @Caroline, thanks, those were most of the compile bugs. I can't get the iCadeReaderView to work. It isn't getting text events. Something to do with firstResponder. I'll have to look at it more tomorrow.

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Login with Facebook Sign In with Google Sign In with OpenID

In this Discussion

Top Posters