Created
November 25, 2017 04:59
-
-
Save rweichler/be1c8577b86f4da8ba494732302f7b4c to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| local objc = require 'objc' | |
| local ffi = require 'ffi' | |
| local count = 0 | |
| function objc.GenerateClass(super, ...) | |
| super = super or 'NSObject' | |
| count = count + 1 | |
| local name = 'EQEAPP_'..count..super | |
| if ... then | |
| objc.class(name, super..'<'..table.concat({...}, ',')..'>') | |
| else | |
| objc.class(name, super) | |
| end | |
| return objc[name] | |
| end | |
| local key = ffi.new('int[1]') | |
| function objc.ref(obj, set) | |
| -- associated objects should be objc | |
| -- objects. but this works, so w/e | |
| assert(set) | |
| local ref = REF(set, true) | |
| local v = ffi.cast('int *', C.malloc(ffi.sizeof('int'))) | |
| v[0] = ref | |
| C.objc_setAssociatedObject(obj, key, ffi.cast('id', v), C.OBJC_ASSOCIATION_ASSIGN) | |
| end | |
| function objc.unref(obj) | |
| local v = ffi.cast('int *', C.objc_getAssociatedObject(obj, key)) | |
| if not v then error('obj not found') end | |
| REF(v[0], false) | |
| C.objc_setAssociatedObject(obj, key, nil, C.OBJC_ASSOCIATION_ASSIGN) | |
| C.free(v) | |
| end | |
| function objc.getref(obj) | |
| local v = ffi.cast('int *', C.objc_getAssociatedObject(obj, key)) | |
| return v and REF(v[0], nil) or nil | |
| end | |
| local vc_class = objc.GenerateClass('UIViewController') | |
| local function dealloc(m) | |
| local self = objc.getref(m) | |
| for _,v in pairs(self.i) do | |
| local type = type(v) | |
| if type == 'cdata' then | |
| v:release() | |
| elseif type == 'table' and v.m then | |
| v.m:release() | |
| end | |
| end | |
| if self.dealloc then | |
| self:dealloc() | |
| end | |
| objc.unref(m) | |
| objc.callsuper(m, 'dealloc') | |
| end | |
| dealloc = ffi.cast('IMP', ffi.cast('void (*)(id, SEL)', dealloc)) | |
| C.class_replaceMethod(vc_class, objc.SEL('dealloc'), dealloc, ffi.arch == 'arm64' and 'v16@0:8' or 'v8@0:4') | |
| local function viewDidLoad(m) | |
| local self = objc.getref(m) | |
| return self.on_load(m) | |
| end | |
| viewDidLoad = ffi.cast('IMP', ffi.cast('void (*)(id, SEL)', viewDidLoad)) | |
| C.class_replaceMethod(vc_class, objc.SEL('viewDidLoad'), viewDidLoad, ffi.arch == 'arm64' and 'v16@0:8' or 'v8@0:4') | |
| function VIEWCONTROLLER(callback, title) | |
| local self = {} | |
| self.i = {} | |
| self.m = vc_class:alloc():init() | |
| self.on_load = callback | |
| self.m:setTitle(title or '') | |
| objc.ref(self.m, self) | |
| self.m:autorelease() | |
| return self.m | |
| end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment