138 lines
		
	
	
		
			2.4 KiB
		
	
	
	
		
			V
		
	
	
			
		
		
	
	
			138 lines
		
	
	
		
			2.4 KiB
		
	
	
	
		
			V
		
	
	
| module eventbus
 | |
| 
 | |
| 
 | |
| pub struct Publisher {
 | |
| 	mut:
 | |
| 	registry &Registry
 | |
| }
 | |
| 
 | |
| pub struct Subscriber {
 | |
| 	mut:
 | |
| 	registry &Registry
 | |
| }
 | |
| 
 | |
| struct Registry{
 | |
| 	mut:
 | |
| 	names []string
 | |
| 	events []voidptr
 | |
| 	once []string
 | |
| }
 | |
| 
 | |
| struct EventHandler {
 | |
| 	func fn(Params)
 | |
| }
 | |
| 
 | |
| pub struct EventBus{
 | |
| 	mut:
 | |
| 	registry &Registry
 | |
| 	publisher &Publisher
 | |
| 	pub:
 | |
| 	subscriber &Subscriber
 | |
| }
 | |
| 
 | |
| pub fn new() &EventBus{
 | |
| 	registry := &Registry{
 | |
| 		names: []
 | |
| 		events: []
 | |
| 		once: []
 | |
| 	}
 | |
| 	return &EventBus{
 | |
| 		registry,
 | |
| 		&Publisher{registry},
 | |
| 		&Subscriber{registry}
 | |
| 	}
 | |
| }
 | |
| 
 | |
| // EventBus Methods
 | |
| 
 | |
| pub fn (eb &EventBus) publish(name string, p Params) {
 | |
| 	mut publisher := eb.publisher
 | |
| 	publisher.publish(name, p)
 | |
| }
 | |
| 
 | |
| pub fn (eb &EventBus) clear_all(){
 | |
| 	mut publisher := eb.publisher
 | |
| 	publisher.clear_all()
 | |
| }
 | |
| 
 | |
| pub fn (eb &EventBus) has_subscriber(name string) bool {
 | |
| 	return eb.registry.check_subscriber(name)
 | |
| }
 | |
| 
 | |
| // Publisher Methods
 | |
| 
 | |
| fn (pb mut Publisher) publish(name string, p Params){
 | |
| 	for i, n in pb.registry.names {
 | |
| 		if name == n {
 | |
| 			eh := pb.registry.events[i]
 | |
| 			invoke(eh, p)
 | |
| 			once_index := pb.registry.once.index(pb.registry.names[i])
 | |
| 			if once_index > -1 {
 | |
| 				pb.registry.events.delete(i)
 | |
| 				pb.registry.names.delete(i)
 | |
| 				pb.registry.once.delete(once_index)
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| }
 | |
| 
 | |
| fn (p mut Publisher) clear_all(){
 | |
| 	for i, n in p.registry.names {
 | |
| 		p.registry.delete_entry(i)
 | |
| 	}
 | |
| }
 | |
| 
 | |
| // Subscriber Methods
 | |
| 
 | |
| pub fn (s mut Subscriber) subscribe(name string, handler fn(Params)){
 | |
| 	s.registry.names << name
 | |
| 	v := voidptr(handler)
 | |
| 	s.registry.events << v
 | |
| }
 | |
| 
 | |
| pub fn (s mut Subscriber) subscribe_once(name string, handler fn(Params)){
 | |
| 	s.subscribe(name, handler)
 | |
| 	s.registry.once << name
 | |
| }
 | |
| 
 | |
| pub fn (s &Subscriber) is_subscribed(name string) bool {
 | |
| 	return s.registry.check_subscriber(name)
 | |
| }
 | |
| 
 | |
| pub fn (s mut Subscriber) unsubscribe(name string, handler fn(Params)){
 | |
| 	v := voidptr(handler)
 | |
| 	for i, n in s.registry.names {
 | |
| 		if name == n {
 | |
| 			eh := s.registry.events[i]
 | |
| 			if eh == v {
 | |
| 				s.registry.delete_entry(i)
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| }
 | |
| 
 | |
| // Registry Methods
 | |
| 
 | |
| fn (r &Registry) check_subscriber(name string) bool {
 | |
| 	for n in r.names {
 | |
| 		if name == n {return true}
 | |
| 	}
 | |
| 	return false
 | |
| }
 | |
| 
 | |
| fn (r mut Registry) delete_entry(index int) {
 | |
| 	once_index := r.once.index(r.names[index])
 | |
| 	if once_index > -1 {
 | |
| 		r.once.delete(once_index)
 | |
| 	}
 | |
| 	r.events.delete(index)
 | |
| 	r.names.delete(index)
 | |
| }
 | |
| 
 | |
| // Helper Functions
 | |
| 
 | |
| fn invoke(p voidptr, arr Params){
 | |
| 	handler := EventHandler{p}.func
 | |
| 	handler(arr)
 | |
| }
 |