Skip to content

Instantly share code, notes, and snippets.

@AzureKitsune
Created July 23, 2011 18:33
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save AzureKitsune/1101726 to your computer and use it in GitHub Desktop.
Save AzureKitsune/1101726 to your computer and use it in GitHub Desktop.
NimEE (inspired by PyEE) and my functional nimrod file.
#
#
# Nimrod's Runtime Library
# (c) Copyright 2010 Amrykid
#
# See the file "copying.txt", included in this
# distribution, for details about the copyright.
#
##
import sequtils
type
TEventArgs* = object of TObject ## Base object for event arguments that are passed to callback functions.
TEventHandler = tuple[name: string, handlers : seq[proc(e:TEventArgs)]]
PEventHandler* = ref TEventHandler ## An eventhandler for an event.
type
TEventEmitter = tuple[events: seq[PEventHandler]]
PEventEmitter* = ref TEventEmitter ## An object that fires events and holds event handlers for an object.
EEventDoesntExist* = object of EInvalidValue
proc initEventHandler*(name : string) : PEventHandler =
##Initializes an EventHandler with the specified name and returns it.
var handler : PEventHandler
new(handler)
handler.handlers = @[]
handler.name = name
return handler
proc addHandler* (handler : PEventHandler, func : proc(e:TEventArgs)) =
##Adds the callback to the specified event handler.
handler.handlers.add(func)
proc removeHandler* (handler : PEventHandler, func : proc(e:TEventArgs)) =
##Removes the callback from the specified event handler.
for i in countup(0, len(handler.handlers) -1):
if func == handler.handlers[i]:
handler.handlers.del(i)
break
proc clearHandlers* (handler : PEventHandler) =
##Clears all of the callbacks from the event handler.
for i in countup(0, len(handler.handlers) -1):
handler.handlers.del(i)
proc containseventhandler(emitter : PEventEmitter, event : string) : bool =
if emitter.events == nil: return false
for k in items(emitter.events):
if k.name == event:
return true
return false
proc on*(emitter : PEventEmitter, event : string, func : proc(e:TEventArgs)) =
##Assigns a event handler with the specified callback. If the event doesn't exist, it will be created.
var containsevent = containseventhandler(emitter, event)
if not containsevent:
var eventhandler : PEventHandler
new(eventhandler)
eventhandler.name = event
var emptyseq : seq[proc(e:TEventArgs)] = @[]
eventhandler.handlers = emptyseq
emitter.events.add(eventhandler) #if not, add it.
var eventname = event
var handler : PEventHandler = findIt(emitter.events, it.name==event)[0]
addHandler(handler, func) #adds the function to the event's list. I get a error here too.
proc emit*(emitter : PEventEmitter, eventhandler : PEventHandler, args :TEventArgs) =
##Fires an event handler with specified event arguments.
for func in items(eventhandler.handlers):
func(args) #call function with args.
proc emit*(emitter : PEventEmitter, event : string, args : TEventArgs) =
##Fires an event handler with specified event arguments.
if containseventhandler(emitter, event):
var allhandlers = findIt(emitter.events, it.name==event)
var handler : PEventHandler = allhandlers[0]
emit(emitter, handler, args)
else:
raise newException(EEventDoesntExist, "The event doesn't exist. Try listening for it using the 'on' function first.")
proc newEventEmitter*() : PEventEmitter =
##Creates and returns a new EventEmitter.
var ee : PEventEmitter
new(ee)
ee.events = @[]
return ee
discard """
file: "nimee_test.nim"
output: '''HandlePrintEvent: Output -> Handled print event
HandlePrintEvent2: Output -> printing for ME
HandlePrintEvent2: Output -> printing for ME'''
"""
import nimee
type
TPrintEventArgs = object of TEventArgs
user* : string
proc handleprintevent*(e : TEventArgs) =
write(stdout, "HandlePrintEvent: Output -> Handled print event")
proc handleprintevent2*(e : TEventArgs) =
var args : TPrintEventArgs = TPrintEventArgs(e)
write(stdout, "HandlePrintEvent2: Output -> printing for " & args.user)
var ee = newEventEmitter()
var eventargs: TPrintEventArgs
eventargs.user = "ME"
##method one test
ee.on("print", handleprintevent)
ee.on("print", handleprintevent2)
ee.emit("print", eventargs)
##method two test
type
TSomeObject = object of TObject
PrintEvent : PEventHandler
var obj : TSomeObject
obj.PrintEvent = initEventHandler("print")
obj.PrintEvent.addHandler(handleprintevent2)
ee.emit(obj.PrintEvent, eventargs)
obj.PrintEvent.removeHandler(handleprintevent2)
ee.emit(obj.PrintEvent, eventargs)
#
#
# Nimrod's Runtime Library
# (c) Copyright 2011 Alex Mitchell
#
# See the file "copying.txt", included in this
# distribution, for details about the copyright.
#
proc concat* [T](seqs : openarray[seq[T]]) : seq[T] =
##Takes several sequences' items and returns them inside of one sequence.
newSeq(result, seqs.sum)
var i = 0
for seqence in items(seqs):
for itm in items(seqence):
result[i] = itm
inc(i)
proc sum* [T](seqs : openarray[seq[t]]) : int =
##Gets of the sum of every sequence.
for seqitm in items(seqs):
inc(result, len(seqitm))
proc distnct* [T](seq1 : seq[T]) : seq[T] =
##Removes duplicates from a sequence and returns it.
result = @[]
var i = 0
for itm in items(seq1):
if not result.contains(itm):
result[i] = itm
inc(i)
proc zip* [S, T](seq1 : seq[S], seq2 : seq[T]) : seq[tuple[a: S, b:T]] =
##Combines two sequences. If one sequence is too short, the remaining items in the longer sequence are discarded.
var len1 = len(seq1)
var len2 = len(seq2)
newSeq(result, min(len1,len2))
for i in 0 .. min(len1,len2)-1:
result[i] = (seq1[i], seq2[i])
iterator findWhere*[T](seq1 : seq[T], pred : proc(item : T) : bool) : T =
##Iterates through a sequence and adds a item to the result as long as the predicate returns true.
for i in countup(0, len(seq1) -1):
var item = seq1[i]
var res : bool = pred(item)
if res:
yield seq1[i]
proc findWhere*[T](seq1 : seq[T], pred : proc(item : T) : bool) : seq[T] =
##Returns all items in a sequence that have returned true from the predicate.
accumulateResult(findWhere(seq1, pred))
template findIt*(seq1, pred: expr) : expr =
##Finds a specific item in a sequence as long as the predicate returns true.
block:
var result : type(seq1) = @[]
for it in items(seq1):
if pred: result.add(it)
result
discard """
file: "sequtils_test.nim"
output: '''Zip: [[1,2],[3,4],[5,6]]")
FindWhere Iterator: 3
FindWhere Iterator: 5
FindWhere Iterator: 7
FindWhere: [3, 5, 7]
FindIt: [1, 3, 7]
Concat: [1, 3, 5, 7, 2, 4, 6]
Distnct: [1, 2, 3, 4, 5, 7]'''
"""
import sequtils
proc testFindWhere(item : int) : bool =
if item != 1: return true
var seq1 : seq[int] = @[]
seq1.add(1)
seq1.add(3)
seq1.add(5)
seq1.add(7)
var seq2 : seq[int] = @[]
seq2.add(2)
seq2.add(4)
seq2.add(6)
var final = zip(seq1, seq2)
write(stdout, "Zip: " & repr(final))
#Test findWhere as a iterator
for itms in findWhere(seq1, testFindWhere):
write(stdout, "FindWhere Iterator: " & repr(itms))
#Test findWhere as a proc
var fullseq : seq[int] = findWhere(seq1, testFindWhere)
write(stdout, "FindWhere: " & repr(fullseq))
#Test findIt as a template
var finditval : seq[int] = findIt(seq1, it!=5)
write(stdout, "FindIt: " & repr(finditval))
var concatseq = concat(seq1,seq2)
write(stdout, "Concat: " & repr(concatseq))
var seq3 = @[1,2,3,4,5,5,5,7]
var discntseq = distnct(seq3)
write(stdout, "Distnct: " & repr(discntseq))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment