PBXB64 OOP & Classes

OOP & Classes Standard

Full object-oriented programming with CLASS, INTERFACE, METHOD, PROPERTY, EVENTS FROM, EVENTS END, RAISEEVENT, IMPLEMENTS, and WITH. Multi-subscriber event dispatch, interface inheritance, and property accessors. All backed by real vtable and event-helper runtime code.

CLASS with METHOD and PROPERTY

Class definition and usage
#COMPILE EXE #DIM ALL CLASS MyClass INSTANCE count AS LONG CLASS METHOD Create() ' constructor, runs when the object is created count = 0 END METHOD INTERFACE IMyClass INHERIT IUNKNOWN METHOD Increment() AS LONG count = count + 1 METHOD = count END METHOD PROPERTY GET Counter() AS LONG PROPERTY = count END PROPERTY END INTERFACE END CLASS FUNCTION PBMAIN() AS LONG LOCAL obj AS IMyClass LET obj = CLASS "MyClass" obj.Increment() obj.Increment() PRINT "Count: "; obj.Counter ' 2 FUNCTION = 0 END FUNCTION

CLASS defines a type with INSTANCE variables and an INTERFACE that holds the METHOD and PROPERTY members. Objects are created with LET obj = CLASS "name"; CLASS METHOD Create() acts as the constructor. Members are called via dot notation (methods with or without parentheses) with real vtable dispatch.

EVENTS FROM / EVENTS END / RAISEEVENT

Multi-subscriber events
#COMPILE EXE #DIM ALL INTERFACE IEvents ' event interface: the shared contract INHERIT IUNKNOWN METHOD MyEvent(BYVAL iValue AS LONG) END INTERFACE CLASS Listener1 AS EVENT ' event sinks are marked AS EVENT INTERFACE IEvents INHERIT IUNKNOWN AS EVENT METHOD MyEvent(BYVAL iValue AS LONG) PRINT "Listener1 got: "; iValue END METHOD END INTERFACE END CLASS CLASS Listener2 AS EVENT INTERFACE IEvents INHERIT IUNKNOWN AS EVENT METHOD MyEvent(BYVAL iValue AS LONG) PRINT "Listener2 got: "; iValue END METHOD END INTERFACE END CLASS CLASS EventSource INTERFACE IEvents ' redeclared inside the source (empty bodies) INHERIT IUNKNOWN METHOD MyEvent(BYVAL iValue AS LONG) END METHOD END INTERFACE INTERFACE ISource INHERIT IUNKNOWN METHOD Trigger() RAISEEVENT IEvents.MyEvent(42) END METHOD END INTERFACE EVENT SOURCE IEvents ' this class raises IEvents events END CLASS FUNCTION PBMAIN() AS LONG LOCAL src AS ISource LOCAL l1 AS IEvents LOCAL l2 AS IEvents LET src = CLASS "EventSource" LET l1 = CLASS "Listener1" LET l2 = CLASS "Listener2" EVENTS FROM src CALL l1 ' subscribe the listeners EVENTS FROM src CALL l2 src.Trigger() ' raises MyEvent(42) EVENTS END l1 ' unsubscribe EVENTS END l2 FUNCTION = 0 END FUNCTION

The event interface is declared once at module level. The source class redeclares it nested, adds EVENT SOURCE, and fires events with RAISEEVENT IEvents.Method(args). Listener classes are declared AS EVENT. EVENTS FROM subscribes a listener and EVENTS END unsubscribes it; RAISEEVENT dispatches to all registered listeners via runtime helpers (bestof_events_from, bestof_events_end, bestof_raiseevent_0..6). Full regression test: test_class_events_multi.pb.

WITH - Block-level Member Access

WITH block for shorthand access
#COMPILE EXE #DIM ALL TYPE Counter count AS LONG label AS STRING END TYPE FUNCTION PBMAIN() AS LONG LOCAL c AS Counter WITH c .label = "clicks" .count = 0 .count = .count + 1 .count = .count + 1 PRINT .label; ": "; .count ' clicks: 2 END WITH FUNCTION = 0 END FUNCTION

WITH saves the variable reference and expands .field prefixes throughout the block, so the variable name is not repeated. It works on TYPE variables; for interface objects use the object name. The variable is stored in fn->with_var and used by the expression and decl parsers.

Back to feature list