Thanks Elliot, I thought the readme might have been enough as a starting 
point, but I see, that my post doesn't encourage anyone to put time into 
this.

The readme shows how to use the event system and I'd like to know, if this 
is a good design for an event system.
I wouldn't trust my judgment too much in this regard, as I don't have much 
real world experience with big software projects.

This is my EventAction type, which is basically just a call back with a 
condition. The T is the event type, that the EventAction should be 
registerted for.

immutable EventAction{T <: Event}
        #condition(T, conditionArgs...) -> Bool
        condition::Function
        conditionArgs::Tuple
        #action(T, actionArgs...) -> nothing
        action::Function
        actionArgs::Tuple
end


These EventActions get pushed into a Dict, where the keys are the Event 
type:
const EVENT_ACTION_QUEUE = Dict{DataType, Dict{Uint64, EventAction}}()
The second Dict could be also a list, but a Dict is more convenient, as one 
can use the object_id of the EventAction as the key, making deletes easier 
and it is impossible to add the exact same EventAction more than one time.
So if someone publishes an event, the list with the EventActions for that 
particular Event is looked up, and then all the actions get executed (if 
the condition is met).

This lead to the odd design choice, that I'm using a parametric type for 
the Events, whereas the parameter represents an Event ID.
With this, a more fine grained( and also more complicated)  event flow is 
possible, because you can have a new entry in EVENT_ACTION_QUEUE for the 
same event type.
So you can register an EventAction{MouseMoved{1}} and 
EventAction{MouseMoved{2}}.
This only make sense together with the republish function, which takes an 
event and republishes it with a different ID.
>From there, it is quite easy to make a hierarchical event flow.
The design downside is, that you can't see the hierarchy, like you would in 
an explicit if/else tree.

I also have two implementation question.
First, how do I get a type without its parameter? 
I would to do it like this: 

function republishEvent{T, ID}(event::T{ID}, newID)


But that didn't work, so I made this ugly workaround:


function republishEvent{T}(event::T, newID)
        eventValues = {}
        for field in names(T)
                push!(eventValues, getfield(event, field))
        end
        # I don't now how to get rid of {ID}, this is a workaround:
        nameWithoutID = eval(parse(string(T.name)))
        publishEvent(nameWithoutID{newID}(eventValues...))
end


Also I'm very open for any inspirations on how to execute the publishEvent 
function in parallel. 
I must admit, I haven't looked into Julias multithreadding yet and I don't 
really know where to start.
The "publishEvent" function should definitely be multithreaded, but I'm 
afraid, that this will introduce quite a few problems, because then the 
event actions are executed on a different thread.
Does anyone has some good example for something similar?

Thank you! =)

Best,
Simon

Reply via email to