views:

242

answers:

2

Hi all, I am developing (well, trying to at least) a Game framework for the Ruby Gosu library. I have made a basic event system wherebye each Blocks::Event has a list of handlers and when the event is fired the methods are called. At the moment the way to implement an event is as follows:

class TestClass

    attr_accessor :on_close

    def initialize
        @on_close = Blocks::Event.new
    end

    def close
        @on_close.fire(self, Blocks::OnCloseArgs.new)
    end
end

But this method of implementing events seems rather long, my question is, how can I make a way so that when one wants an event in a class, they can just do this

class TestClass

    event :on_close

    def close
        @on_close.fire(self, Blocks::OnCloseArgs.new)
    end
end

Thanks in advance, ell.

A: 

The following is completely untested, but maybe it gets you started:

class Blocks
  class Event
    # dummy 
  end
end

class Class
  def event(*args)
    define_method :initialize do
      args.each { |a| instance_variable_set("@#{a}", Blocks::Event.new) }
    end
  end
end

class TestClass
    event :on_close

    def close
      #@on_close.fire(self, Blocks::OnCloseArgs.new)
      p @on_close
    end
end

test = TestClass.new
test.close
# => #<Blocks::Event:0x10059a0a0>
p test.instance_variables
# => ["@on_close"]

Edited according to banister's comment.

Michael Kohl
It is indeed. As I said, just an untested quick shot, thanks for pointing it out :-)
Michael Kohl
It seems to work on a class that requires no initialization logic and that means I would need to do an alias as well which for me is getting a bit anti-ruby, putting in more work than necessary, so I'l just stick with manually adding it, maybe I'l find a way but for now its until we meet again :)
Ell
A: 

I don't entirely understand what you're trying to do, but you can avoid using the initialize method in the following way:

class TestClass

    event :on_close

    def close
        @on_close ||= Blocks::Event.new
        @on_close.fire(self, Blocks::OnCloseArgs.new)
    end
end

The ||= idiom lets you lazily initialize instance variables in ruby.

banister