0

LWCF - my take on component oriented programming

On my path of making a GUI toolkit, I thought Component Oriented Programming would suit best for such task, because GUIs are essentially made of little blocks that do their own thing. Inheritance and Object Orientation, while usable, creates a mess for me. So what I came up with was an extremely (no kidding) minimal component framework. While it is only a handful of actual code lines, funnily enough took me hours to get right. I call it the Light-weight Component Framework. In the process of explaining how it works, I will create a Player with a Movement component, that will be attached to Player, giving it "legs"!

20th Nov 2016, 5:36 PM
asdadasdsaczxc
3 Réponses
+ 1
2/3 - the Receiver component - Now comes the fun part, messaging between the components. Since components are very lonely we need a way for them to communicate. Every component has an event() method, which will send out the given messages to all its children. The basic usage is: component.event(message=data) To demonstrate, we shall add a move(x, y) function to our player class, which will send out a message when it's called. class Movement(Component): pass class Player(Component): def move(self, x, y): print('I AM MOVING!') self.event(move=(x,y)) player = Player() player << Movement() player.move(1,1) Running this code will just make the player scream, and nothing else will happen. The Receiver Component lets child components receive the parent's messages. The Receiver will register a certain keyword and it will call the function it's given with the data it got from the message. This is how we do it: component << Receiver('message', function_callback) We can attach it now: class MyComp(Component): def __setup__(self): self << Receiver('message', function) Or later: class MyComp(Component): pass MyComp() << Receiver('message', function)
20th Nov 2016, 4:29 PM
asdadasdsaczxc
+ 1
1/3 - the Component class - All component classes must inherit this to become a part of the bigger picture. And that's the only inheritance you will need to do on your path to modularity. To make it cleaner I had to forbid the use of __init__(). While it might seem silly, because the only thing the Component initializer does is create a list, I'd hate to type super().__init__() at the beginning of each of my components __init__ function. Instead __init__ is replaced by __setup__, and acts just like __init__, so no changes besides a little different name to use. Components can be attached to eachother in a couple ways. First way is using the .attach() method each component has. It can be used to attach lots of components at once. component.attach(another_component, yet_another, ...) Second way is using the overloaded left-shift bitwise operator (what a moutful, maybe "two birds flying West"?) This can only take one Component though. component << another_component So let's make Movement and Player components (yes, the player itself can be used as a component). Then we will attach Movement to Player. class Movement(Component): pass class Player(Component): pass player = Player() player << Movement() Simple, right?
20th Nov 2016, 4:29 PM
asdadasdsaczxc
0
3/3 So lastly let's give our player the legs it deserves class Movement(Component): def __setup__(self): self.pos = [0,0] self << Receiver('move', self.move) def move(self, x, y): self.pos[0] += x self.pos[1] += y print('Movement: moved by', x, ';', y, 'to', self.pos) class Player(Component): def move(self, x, y): print('Player: I AM MOVING!') self.event(move=(x, y)) player = Player() player << Movement() player.move(-1,-1) Output: Player: I AM MOVING! Movement: moved by -1 ; -1 to [-1, -1] It's so simple, so primitive, yet so effective. It's probably not that cool as I think it is :D The module along with this very example can be found on my profile or here: https://code.sololearn.com/cE8LdVeB58F3
20th Nov 2016, 4:32 PM
asdadasdsaczxc