Skip to content

Latest commit

 

History

11 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 

Repository files navigation

* Objective-C to Lisp Bridge with Transparent Layer

Dependencies:
#+BEGIN_SRC common-lisp
(ql:quickload '(:alexandria :anaphora :closer-mop :cffi :cffi-libffi :float-features :trivial-main-thread))
#+END_SRC

Packages:
- OBJC ::              Main Package
- OBJC-CLASS ::        For Class Definitions
- OBJC-META ::         For Metaclass Definitions
- OBJC-INSTANCETYPE :: For [[https://developer.apple.com/library/archive/releasenotes/ObjectiveC/ModernizationObjC/AdoptingModernObjective-C/AdoptingModernObjective-C.html][instancetype]] Definitions
- OBJC-METHOD ::       For Obj-C -> Lisp Generic Function Methods
- OBJC-PROP ::         Obj-C Properties -> Lisp Slot Names

#+BEGIN_QUOTE
The source code is separated using titles and #\Page, please use ~C-x [~ and ~C-x ]~ to navigate throught subtitles.
#+END_QUOTE

** Usage

To get a Obj-C class, either pass its string name or the Lisp name it should be translated to ~cls~ macro or ~ensure-objc-class~ function, or use string name for ~objc-lookup-class~:

#+begin_src common-lisp
  (objc:cls ns-object)
  ;; or
  (objc:ensure-objc-class 'objc-class::ns-object)
  ;; or
  (objc:ensure-objc-class "NSObject")
  ;; or
  (objc:objc-lookup-class "NSObject")

  ;; => #<OBJC-META:NS-OBJECT OBJC-CLASS:NS-OBJECT>
#+end_src

(These are convenient functions, CLOS & MOP methods will be introduced below.)

The class object will be automatically created inside corresponding (~OBJC-CLASS~ or ~OBJC-META~) package, with all superclasses & metaclasses defined. By default, all methods under the class will also be registered in ~OBJC-METHOD~ package, and class properties will be registered as Lisp class slots named in ~OBJC-PROP~ package.

#+begin_src text
  #<OBJC-META:NS-OBJECT {7005C64A43}>
--------------------
Name: OBJC-CLASS:NS-OBJECT
Super classes: #<STANDARD-CLASS OBJC::OBJC-OBJECT>
Direct Slots: CLASS-DESCRIPTION, ATTRIBUTE-KEYS, TO-ONE-RELATIONSHIP-KEYS, TO-MANY-RELATIONSHIP-KEYS, OBSERVATION-INFO, CLASS-FOR-KEYED-ARCHIVER, AUTO-CONTENT-ACCESSING-PROXY, SCRIPTING-PROPERTIES, CLASS-CODE, CLASS-NAME, EXPOSED-BINDINGS, _NS_OBSERVATION-TRACKING-DICTIONARY, HASH, SUPERCLASS, DESCRIPTION, DEBUG-DESCRIPTION, HASH, SUPERCLASS, DESCRIPTION, DEBUG-DESCRIPTION, _AX-IS-WRAPPED-POINTER, ACCESSIBILITY-SWIFT-UI-DEFAULT-ACTION-STORED-BLOCK, ACCESSIBILITY-SWIFT-UI-STORED-LINK-ROTOR, SWIFTUI_ACCESSIBILITY-LABEL, KNOWN-REPRESENTED-ELEMENT, ROTOR-OWNER-ELEMENT, HASH, SUPERCLASS, DESCRIPTION, DEBUG-DESCRIPTION
Effective Slots: #<N/A (class not finalized)> [finalize]
Sub classes: NS-RULER-MARKER, NS-GRID-ROW, NS-GRID-COLUMN, NS-GRID-CELL, NS-CELL, NS-FILE-PROMISE-RECEIVER, NS-FILE-PROMISE-PROVIDER, NS-CONTROLLER, NS-DOCUMENT-CONTROLLER, NS-DOCUMENT, NS-PASTEBOARD-ITEM, NS-PASTEBOARD, NS-WORKSPACE, NS-RESPONDER, NS-DICTIONARY, NS-SET, NS-ARRAY, NS-STRING, NS-VALUE, PROTOCOL
Precedence List: #<N/A (class not finalized)>
Prototype: #<N/A (class not finalized)>
--------------------
 Group slots by inheritance [X]
 Sort slots alphabetically  [X]

CLASS:
[ ]  %DOCUMENTATION                     = NIL
[ ]  CLASS-EQ-SPECIALIZER               = #<SB-PCL::CLASS-EQ-SPECIALIZER #<OBJC-META:NS-OBJECT OBJC-CLASS:NS-OBJECT>>
[ ]  DIRECT-METHODS                     = (NIL)
[ ]  DIRECT-SUBCLASSES                  = (#<OBJC-META:NS-RULER-MARKER OBJC-CLASS:NS-RULER-MARKER> #<OBJC-META:NS-GRID-ROW OBJC-CLASS:NS-GRID-ROW> #<OBJC-META:NS-GRID-COLUMN OBJC-CLASS:NS-GRID-COLUMN> #<OBJC-META:NS-GRID-CELL OBJC-CLASS:NS-GRID-CELL> #<OBJC-META:NS-CELL OBJC-CLASS:NS-CELL> #<OBJC-META:NS-FILE-PROMISE-RECEIVER OBJC-CLASS:NS-FILE-PROMISE-RECEIVER> #<OBJC-META:NS-FILE-PROMISE-PROVIDER OBJC-CLASS:NS-FILE-PROMISE-PROVIDER> #<OBJC-META:NS-CONTROLLER OBJC-CLASS:NS-CONTROLLER> ..)
[ ]  DIRECT-SUPERCLASSES                = (#<STANDARD-CLASS OBJC::OBJC-OBJECT>)
[ ]  FINALIZED-P                        = NIL
[ ]  NAME                               = OBJC-CLASS:NS-OBJECT
[ ]  SAFE-P                             = NIL

DEFINITION-SOURCE-MIXIN:
[ ]  SOURCE                             = #S(SB-C:DEFINITION-SOURCE-LOCATION :NAMESTRING "/Users/april/common-lisp/objc/objc.lisp" :INDICES 4521988)

NS-OBJECT:
[ ]  ACCESS-INSTANCE-VARIABLES-DIRECTLY = T

OBJC-CLASS:
[ ]  AUTO-BIND-PROPERTIES               = T
[ ]  AUTO-REGISTER-METHODS              = T
[ ]  OBJC-CLASS-NAME                    = "NSObject"

OBJC-OBJECT:
[ ]  OBJ                                = #.(SB-SYS:INT-SAP #X1F2689D70)

PCL-CLASS:
[ ]  %CLASS-PRECEDENCE-LIST             = #<unbound>
[ ]  CAN-PRECEDE-LIST                   = (#<SB-PCL:SYSTEM-CLASS COMMON-LISP:T> #<SB-PCL::SLOT-CLASS SB-PCL::SLOT-OBJECT> #<STANDARD-CLASS COMMON-LISP:STANDARD-OBJECT> #<STANDARD-CLASS OBJC::OBJC-OBJECT>)
[ ]  CPL-AVAILABLE-P                    = NIL
[ ]  INCOMPATIBLE-SUPERCLASS-LIST       = NIL
[ ]  PROTOTYPE                          = NIL
[ ]  WRAPPER                            = #<SB-KERNEL:LAYOUT for OBJC-CLASS:NS-OBJECT {7005241303}>

PLIST-MIXIN:
[ ]  PLIST                              = NIL

SLOT-CLASS:
[ ]  DIRECT-SLOTS                       = (#<OBJC::OBJC-PROPERTY-SLOT OBJC-PROP:CLASS-DESCRIPTION> #<OBJC::OBJC-PROPERTY-SLOT OBJC-PROP:ATTRIBUTE-KEYS> #<OBJC::OBJC-PROPERTY-SLOT OBJC-PROP:TO-ONE-RELATIONSHIP-KEYS> #<OBJC::OBJC-PROPERTY-SLOT OBJC-PROP:TO-MANY-RELATIONSHIP-KEYS> #<OBJC::OBJC-PROPERTY-SLOT OBJC-PROP:OBSERVATION-INFO> #<OBJC::OBJC-PROPERTY-SLOT OBJC-PROP:CLASS-FOR-KEYED-ARCHIVER> #<OBJC::OBJC-PROPERTY-SLOT OBJC-PROP:AUTO-CONTENT-ACCESSING-PROXY> #<OBJC::OBJC-PROPERTY-SLOT OBJC-PROP:SCRIPTING-PROPERTIES> ..)
[ ]  SLOTS                              = NIL

SPECIALIZER:
[ ]  %TYPE                              = (CLASS #<OBJC-META:NS-OBJECT OBJC-CLASS:NS-OBJECT>)

[set value]  [make unbound]

#+end_src

To control the behaviour, you can use the MOP function ~ensure-class~, or even ~defclass~ directly.

#+begin_src common-lisp
  (c2mop:ensure-class 'objc-class:ns-object
                      :metaclass 'objc:objc-class
                      :auto-bind-properties nil   ; optionally disable auto property binding
                      :auto-register-methods nil) ; optionally disable auto method registration
  ;; or
  (defclass objc-class:ns-object () ()
    (:metaclass objc-class))
#+end_src

#+begin_quote
FIXME: Currently we didn't implemented ~change-class~ relative methods on objc-class, so all class can only be defined once. Execution of the form above will signal error because ~NSObject~ has been defined. It's just for demonstrating purpose.
#+end_quote

To make an instance:

#+begin_src lisp
  (make-instance (objc:cls ns-object))
#+end_src

Note that this use ~class_createInstance~ runtime function, and you may need to do additional initialization for the object.

or if you has the object's Obj-C pointer (the objc ~id~):

#+begin_src lisp
  (make-instance (objc:cls ns-object) :objc-object <pointer>)
#+end_src

To call a method:

#+begin_src lisp
  (objc-method:new (objc:cls ns-object))
  ;; or
  (funcall (objc:sel new) (objc:cls ns-object))

  ;; => #<OBJC-CLASS:NS-OBJECT {700964F153}>
#+end_src

Use ~slot-value~ to get the Obj-C property:

#+begin_src lisp
  (slot-value (objc-method:new (objc::cls ns-object)) 'objc-prop:hash)
  ;; => 105553174675536 (47 bits, #x6000037B4050)
#+end_src

** Todos

*** TODO Features [22%]

- [X] Wrapper for NSPoint, NSSize, NSRect, CGPoint, CGSize, CGRect
- [ ] Parse type encoding for array, structure, union, bits
- [ ] Keyword-style objc methods
- [ ] Give a better way to (partially) disable auto-translation of (certain) objc properties
- [ ] Give a better way to (partially) disable auto-translation of (certain) objc methods
- [ ] Give a way to (partially) disable auto-translation of (certain) objc class

Subclassing

- [X] Basic
- [X] Redefine subclass
- [ ] Dispose subclass
- [ ] Slot (Property)
- [ ] Method

*** TODO AppKit Bindings [0%]

- [ ] NSApplication

*** TODO Tests [0%]

- [ ] Page 1
- [ ] Page 2
- [ ] Page 3
- [ ] Page 4
- [ ] Page 5
- [ ] Page 6
- [ ] Page 7
- [ ] Page 8
- [ ] Page 9
- [ ] Page 10
- [ ] Page 11
- [ ] Page 12
- [ ] Page 13
- [ ] Page 14
- [ ] Page 15
- [ ] Page 16
- [ ] Page 17
- [ ] Page 18

*** TODO Documentation [0%]

- [ ] For class
- [ ] For functions & generic functions
- [ ] For slots
- [ ] For MOP methods
- [ ] For C functions
- [ ] For Obj-C classes
- [ ] For Obj-C methods
- [ ] For Obj-C properties

*** TODO Manual [0%]

*** TODO Examples [0%]

About

Objective-C to Lisp Binding with Transparent Layer

Resources

Stars

12 stars

Watchers

2 watching

Forks

Releases

Packages

Contributors

Languages