Author Topic: [XP][VX] Scheduler - When you want something to happen after an amount of frames  (Read 9506 times)

Offline Zeriab

  • Ethereal Devastator
  • ****
  • Posts: 350
  • LV: 65
  • Mighty Scripter
    • View Profile
    • Zeriab's Junk
Scheduler
Authors: Zeriab
Version: 1.0
Type: Scheduler
Key Term: Scripting Tool

Introduction

How many of you tried creating a parallel process where you put in an amount of frames and then a script call or something else afterwards?
Basically a simply way of doing something after an amount of frames. This is the principle behind the script. To schedule pieces of code to be executed after an arbitrary amount of frames. No making decrementing counters. The scheduler takes care of all that or well most of it. It is still not as simple as using the wait event command.

Script

Code: [Select]
#==============================================================================
# ** Scheduler
#------------------------------------------------------------------------------
#  This class allows to schedule a proc or method call a given amount of frames
#  into the future with any amount of arguments
#==============================================================================
class Scheduler
  #============================================================================
  # ** Order
  #----------------------------------------------------------------------------
  #  An order is a proc, method or something else which has 'call' as a method,
  #  and the arguments to pass along.
  #============================================================================
  # Create an struct for containing the data
  Order = Struct.new(:callable, :arguments)
  # Extend the class with a call-method which calls the callable with the args
  class Order
    #------------------------------------------------------------------------
    # * Call the callable with the present arguments
    #------------------------------------------------------------------------
    def call
      callable.call(*arguments)
    end
  end
  #============================================================================
  # ** RecurringOrder
  #----------------------------------------------------------------------------
  #  An order which is recurring every specified amount of time until
  #  FalseClass is returned from the call.
  #  Note that arguments remain the same for each call
  #============================================================================
  # Create an struct for containing the data
  RecurringOrder = Struct.new(:callable, :arguments, :frames)
  # Extend the class with a call-method which calls the callable with the args
  class RecurringOrder
    #------------------------------------------------------------------------
    # * Call the callable with the present arguments
    #------------------------------------------------------------------------
    def call
      result = callable.call(*arguments)
      unless result == FalseClass
        Scheduler.schedule_recurring(frames, frames, callable, *arguments)
      end
    end
  end
 
  #============================================================================
  # ** Mapping
  #----------------------------------------------------------------------------
  # Maps an index to an array. Values can be added to these value.
  # Each array starts empty.
  #============================================================================
  class Mapping
    #------------------------------------------------------------------------
    # * Initialization
    #------------------------------------------------------------------------
    def initialize
      @mapping = {}
    end
    #------------------------------------------------------------------------
    # * Add an value to a given index
    #------------------------------------------------------------------------
    def add(index, value)
      @mapping[index] = [] if @mapping[index].nil?
      @mapping[index] << value
    end
    #------------------------------------------------------------------------
    # * Retrieve the list of values mapped to the index
    #------------------------------------------------------------------------
    def get(index)
      return [] if @mapping[index].nil?
      @mapping[index]
    end
    #------------------------------------------------------------------------
    # * Delete the array the index is mapped to. Conceptually it is now empty
    #------------------------------------------------------------------------
    def empty(index)
      @mapping.delete(index)
    end
  end
 
  #--------------------------------------------------------------------------
  # * Initialization
  #--------------------------------------------------------------------------
  def initialize
    # This maps
    @mapping = Mapping.new
    @tick = 0
  end
  #--------------------------------------------------------------------------
  # * Scheduling
  #--------------------------------------------------------------------------
  def schedule(frames, callable, *arguments)
    # Create an order
    order = Order.new(callable, arguments)
    @mapping.add(frames + @tick, order)
  end
  #--------------------------------------------------------------------------
  # * Scheduling
  #--------------------------------------------------------------------------
  def schedule_recurring(frames, frames_to_wait, callable, *arguments)
    # Create an order
    order = RecurringOrder.new(callable, arguments, frames_to_wait)
    @mapping.add(frames + @tick, order)
  end
  #--------------------------------------------------------------------------
  # * Update the scheduler
  #--------------------------------------------------------------------------
  def update
    # Get the orders for the current tick
    orders = @mapping.get(@tick)
    # Delete the mapping's reference to the list of orders
    @mapping.empty(@tick)
    # Call each order
    for order in orders
      order.call
    end
    # Advance the tick (next frame)
    @tick += 1
  end
 
  #--------------------------------------------------------------------------
  # * 'Singleton' principle used although you can easily make
  #   an extra scheduler. (Class method only works for this)
  #--------------------------------------------------------------------------
  @@instance = self.new
  def self.instance
    return @@instance
  end
  ## Class methods point to the equivalent instance methods
  def self.schedule_recurring(*args) instance.schedule_recurring(*args); end
  def self.schedule(*args) instance.schedule(*args); end
  def self.update(*args) instance.update(*args); end
end

The latest version will be present here: http://zeriab.plesk3.freepgs.com/root/scripts/Scheduler/scheduler.txt
You could check it if more than a month has passed since last edit. You know, just in case.
More generally all material related to the Scheduler except the forum topic can be found here: http://zeriab.plesk3.freepgs.com/index.php?dir=scripts/Scheduler/

Here is a binding if you want the scheduler to work for every frame. Basically for each Graphic.update the scheduler is updated.
It doesn't matter whether you are in a menu, title screen, battle. As long as Graphic.update is called so is the scheduler. (The main scheduler)
Code: [Select]
module Graphics
  class << self
    unless self.method_defined?(:scheduler_update)
      alias :scheduler_update :update
    end
    def update(*args)
      scheduler_update(*args)
      Scheduler.update
    end
  end
end

Instructions

(click to show/hide)

Compatibility

The Scheduler alone use only Ruby and could easily be placed in a Ruby if one wanted that.
It is highly unlikely that you will encounter any compatibility issues with the backbone alone since it is independent from RGSS/2 library.

On the other side there could potentially be problems with the bindings which makes use of the scheduler so it actually does something in game.
Currently there is only the Graphics.update binding which makes compatibility issues very unlikely.

Future Work
 - Explicitly exit/stop a scheduler. The scheduled items can then be discard, executed or maybe something else.
 - Error handling. (This may be an external. I.e. not embedded in the core)
 - Documentation

Credits and Thanks

Credits goes to Zeriab for creating the system

I would like to thank everyone using their time to try and use my system.
I would like to thank everyone reading this topic.

Thanks.

Author's Notes

I would be delighted if you report any bug, errors or issues you find.
In fact I would be delighted if you took the time and replied even if you have nothing to report.
Suggestions are more than welcome.

Note that I will release a demo which shows a couple of ways of using this script.
Note also that I will always make a post when I have an update. (Small stuff like typos excluded)

And finally: ENJOY!

 - Zeriab
« Last Edit: February 21, 2009, 01:07:48 PM by Blizzard »

Offline Punn

  • Ethereal Devastator
  • ****
  • Posts: 493
  • LV: 9
    • View Profile
Re: Scheduler - When you want something to happen after an amount of frames
« Reply #1 on: November 28, 2008, 01:34:55 AM »
Can you make a demo of this? I might wanna use this

Offline Zeriab

  • Ethereal Devastator
  • ****
  • Posts: 350
  • LV: 65
  • Mighty Scripter
    • View Profile
    • Zeriab's Junk
Re: Scheduler - When you want something to happen after an amount of frames
« Reply #2 on: November 28, 2008, 01:44:41 AM »
(...)
Author's Notes

I would be delighted if you report any bug, errors or issues you find.
In fact I would be delighted if you took the time and replied even if you have nothing to report.
Suggestions are more than welcome.

Note that I will release a demo which shows a couple of ways of using this script.
Note also that I will always make a post when I have an update. (Small stuff like typos excluded)

And finally: ENJOY!

 - Zeriab

I intend to do so. I did forget to tell that it will be within a couple of weeks.
Please do note that this is a scripter tool and therefore you might not be able to use it properly. (Unless you are a scripter >_>)

*hugs*
 - Zeriab

Offline Blizzard

  • This sexy
  • Administrator
  • has over 9000 posts
  • *****
  • Posts: 20016
  • LV: 651
  • Gender: Male
  • Magic midgets.
    • View Profile
    • You're already on it. (-_-')
Re: Scheduler - When you want something to happen after an amount of frames
« Reply #3 on: November 28, 2008, 01:13:37 PM »
<3 *powers up*
Check out Daygames and our games:

King of Booze      King of Booze: Never Ever      Pet Bots
Drinking Game for Android      Never have I ever for Android      Pet Bots for Android
Drinking Game for iOS      Never have I ever for iOS      Pet Bots for iOS
Drinking Game on Steam


Quote from: winkio
I do not speak to bricks, either as individuals or in wall form.

Quote from: Barney Stinson
When I get sad, I stop being sad and be awesome instead. True story.

Offline ForeverZer0

  • CP's Pedophile
  • Global Moderator
  • Guardian of Chaos
  • ****
  • Posts: 3255
  • LV: 298
  • Gender: Male
  • Remember you are unique, just like everyone else.
    • View Profile
I know this is an old topic, but just checked this out and I love it.
I can definitely see just how potentially powerful this tool could be.
I am done scripting for RMXP. I will likely not offer support for even my own scripts anymore, but feel free to ask on the forum, there are plenty of other talented scripters that can help you.

Offline Zeriab

  • Ethereal Devastator
  • ****
  • Posts: 350
  • LV: 65
  • Mighty Scripter
    • View Profile
    • Zeriab's Junk
I had totally forgotten about making a demo utilizing the script >_<
I would be grateful if any of the awesome scripters here would do it for me as I don't have the time :3

Offline ForeverZer0

  • CP's Pedophile
  • Global Moderator
  • Guardian of Chaos
  • ****
  • Posts: 3255
  • LV: 298
  • Gender: Male
  • Remember you are unique, just like everyone else.
    • View Profile
I had totally forgotten about making a demo utilizing the script >_<
I would be grateful if any of the awesome scripters here would do it for me as I don't have the time :3

I may be able to help you out with that.
Once I had it all figured out, I realized how beautiful it was. Makes things nice and easy...
I am done scripting for RMXP. I will likely not offer support for even my own scripts anymore, but feel free to ask on the forum, there are plenty of other talented scripters that can help you.

Offline Zeriab

  • Ethereal Devastator
  • ****
  • Posts: 350
  • LV: 65
  • Mighty Scripter
    • View Profile
    • Zeriab's Junk
Thanks a lot. I appreciate it :3

*huggles*

Offline ForeverZer0

  • CP's Pedophile
  • Global Moderator
  • Guardian of Chaos
  • ****
  • Posts: 3255
  • LV: 298
  • Gender: Male
  • Remember you are unique, just like everyone else.
    • View Profile
Thanks a lot. I appreciate it :3

*huggles*

Try this out. It was a little difficult making a demo for this, but it has a few examples, etc.

http://www.mediafire.com/download.php?1jt3kjmmfzq
I am done scripting for RMXP. I will likely not offer support for even my own scripts anymore, but feel free to ask on the forum, there are plenty of other talented scripters that can help you.

Offline Ryex

  • Arctic Bird of Programming
  • Global Moderator
  • Chaos Ultimate
  • ****
  • Posts: 5135
  • LV: 198
  • Gender: Female
  • Wants to write a compiler for fun
    • View Profile
Zeriab has left us
I no longer keep up with posts in the forum very well. If you have a question or comment, about my work, or in general I welcome PM's. if you make a post in one of my threads and I don't reply with in a day or two feel free to PM me and point it out to me.

DropBox, the best free file syncing service there is.
(click to show/hide)

Offline ForeverZer0

  • CP's Pedophile
  • Global Moderator
  • Guardian of Chaos
  • ****
  • Posts: 3255
  • LV: 298
  • Gender: Male
  • Remember you are unique, just like everyone else.
    • View Profile
Zeriab has left us
What do you mean? He's not gonna be on CP no more?
I am done scripting for RMXP. I will likely not offer support for even my own scripts anymore, but feel free to ask on the forum, there are plenty of other talented scripters that can help you.

Offline Ryex

  • Arctic Bird of Programming
  • Global Moderator
  • Chaos Ultimate
  • ****
  • Posts: 5135
  • LV: 198
  • Gender: Female
  • Wants to write a compiler for fun
    • View Profile
I no longer keep up with posts in the forum very well. If you have a question or comment, about my work, or in general I welcome PM's. if you make a post in one of my threads and I don't reply with in a day or two feel free to PM me and point it out to me.

DropBox, the best free file syncing service there is.
(click to show/hide)