Jump to content

How to use an Event System


Puharesource

Recommended Posts

I've decided to make this system, due to my dislike of the way that most scripts are being made and the fact that I come from an environment where everything is truly event based.
 
This tutorial will depend on a system that I wrote (OSBotEventSystem), which you can find on GitHub here.

Documentation can also be found on my website here.

What is an event system?
An event system is a system that allows you to subscribe (listen) to certain events. Events are fired whenever something specific happens. The outcome of the event is driven by the listening subscribers (EventHandlers) and will allow you to fire whatever code you want, whenever the event that you're listening for fires. You can read about Event-driven programming here, if you need a proper understanding of the subject.
 
What are the benefits of an event system?
The benefits of an event system, allows you to manage and maintain your code much easier. You'll be able to easily tell your code in what order, your subscribers are going to be executed. And much... much... more.
 
Step #1
We're going to start off by adding the event system to our build path (this has to be compiled with your script). I've added this to a maven repository, so it should be easy for anyone to go ahead and add this to your pom, build.gradle or heck! even just a simple jar file.

 

I expect you to already know how to add a dependency to your IDE of choice, so I'm just going to provide your with the repositories, artifacts and links.
 
Gradle repository

maven {
    name 'Puharesource'
    url 'http://repo.puha.io/nexus/content/repositories/releases/'
}

 
Gradle artifact

compile group: 'io.puharesource.osrs', name: 'eventsystem', version: '1.0.1'

Maven repository

<repository>
  <id>puha-repo</id>
  <url>http://repo.puha.io/nexus/content/repositories/releases/</url>
</repository>

 
Maven dependency

<dependency>
  <groupId>io.puharesource.osrs</groupId>
  <artifactId>eventsystem</artifactId>
  <version>1.0.1</version>
</dependency>

Jar file

http://repo.puha.io/nexus/content/repositories/releases/io/puharesource/osrs/eventsystem/1.0.1/eventsystem-1.0.1.jar

 

Step #2

Now that we've added the system to our build path, it's time to setup the basic script skeleton a quick guide can be found here. I've gone ahead and removed the bits that we don't need for this tutorial.

import org.osbot.rs07.script.Script;
import org.osbot.rs07.script.ScriptManifest;

@ScriptManifest(version = 1, author = "Puharesource", logo = "", name = "TestScript", info = "Showing you how to use the events system in a script.")
public final class TestScript extends Script {
    @Override
    public void onStart() throws InterruptedException {
        //TODO: Add code that'll add our upcoming custom events to the event system.
        //TODO: Add code that'll add our upcoming listeners to the event system.
    }

    @Override
    public int onLoop() throws InterruptedException {
        //TODO: Add code that'll make the our upcoming custom events fire.
        
        return random(200, 300);
    }
}

Step #3

Now that we have the script skeleton, we're going to make our first event. This event will fire whenever a random number between 0 and 10 hits 5 and then take the System.currentTimeMillis() of when that happened. This event will also implement the CancellableEvent interface which means that we're going to be able to cancel the event and therefor stop certain subscribers from listening for the event (if cancelled). The event looks as follows:

import io.puharesource.osrs.eventsystem.CancellableEvent;
import io.puharesource.osrs.eventsystem.Event;

public final class TestEvent extends Event implements CancellableEvent {
    private final long time;
    private boolean cancelled;

    public TestEvent() {
        this.time = System.currentTimeMillis();
    }

    public long getTime() {
        return time;
    }

    @Override
    public boolean isCancelled() {
        return cancelled;
    }

    @Override
    public void setCancelled(boolean cancel) {
        this.cancelled = cancel;
    }
}

Step #4

Now that we've created our event, we have to register the event. This is done by adding the following to the onStart() method in our script class.

@Override
public void onStart() throws InterruptedException {
    EventManager.get().registerEvent(TestEvent.class);
    //TODO: Add code that'll add our upcoming listeners to the event system.
}

Step #5

Now that we've registered our event, we have to make it fire the event somehow. Again, in our test case, we'll be checking if a random number hits 5, if it does we're going to get the time and possibly run code to make it either cancel the event or go through. This is all done in our onLoop method in our script class.

@Override
public int onLoop() throws InterruptedException {
    if (random(0, 10) == 5) {
        final TestEvent event = new TestEvent();

        EventManager.get().callEvent(event);

        if (!event.isCancelled()) {
            log("TestEvent cancelled!");
        }
    }

    return random(200, 300);
}

As seen above, we get the number between 0 and 10 and check whether it's 5. If it is 5, we create a new instance of our event and call the event through the EventManager. Afterwards we check whether the event has been cancelled, if it has we're going to log that it was cancelled.

 

Step #6

Now that we're able to fire the event, we'll need to create an EventListener with a few EventHandlers that will fire once the event is called.

For a better understanding of the upcoming code, please read EventPriority and EventHandler

import io.puharesource.osrs.eventsystem.EventHandler;
import io.puharesource.osrs.eventsystem.EventListener;
import io.puharesource.osrs.eventsystem.EventPriority;

public final class TestListener implements EventListener {
    @EventHandler(priority = EventPriority.LOWEST)
    public void onEventFirst(final TestEvent event) {
        event.setCancelled(true);
    }

    @EventHandler
    public void onEventSecond(final TestEvent event) {
        if (event.isCancelled()) {
            event.setCancelled(false);
        }
    }

    @EventHandler(priority = EventPriority.HIGHEST)
    public void onEventLast(final TestEvent event) {
        if (event.getTime() % 2 != 0) {
            event.setCancelled(true);
        }
    }

    @EventHandler(ignoreCancelled = true, priority = EventPriority.MONITOR)
    public void onEventLog(final TestEvent event) {
        System.out.println("This event was fired at: " + event.getTime() + " and is an even number!");
    }
}

As you can see, our class implements the EventListener interface. Our class also contains several methods of the same structure, with the @EventHandler annotation above them and our TestEvent as the methods ONLY parameter.

 

Since our method onEventFirst, has the LOWEST priority, it will be executed before any of the other methods. (In this case we make it cancel the event)

 

Then since our second event onEventSecond doesn't have ignoreCancelled = true in the EventHandler annotation, the code within it is still going to be executed, even though the event has been cancelled. (In this case we make it uncancel the event if the event is cancelled).

 

Afterwards onEventLast will fire. (In this case we're if the time of which the event was fired, was an uneven number, if it was cancel it).

 

And at last, we get to onEventLog which has the priority of MONITOR and ignores cancelled events. MONITOR events should ONLY be used for logging purposes and should not change any data. Since we cancelled the event in onEventLast if the time was an odd number, that means onEventLog will ONLY fire when the time was even. (This we obviously log).

 

Step #7

At last, we just need to register our listener in our onStart() method in our script class.

@Override
public void onStart() throws InterruptedException {
    EventManager.get().registerEvent(TestEvent.class);
    EventManager.get().registerListener(new TestListener()); // Registered our listener.
}

And finally we're done. Remember, you can register as many events and listeners as you want. Simultaneously you can use as many EventListeners and EventHandlers for your events as you'd like.

Edited by Puharesource
  • Like 7
Link to comment
Share on other sites

 

 

Thought the event stuff looked familiar, checked your github, was right tongue.png Good first post!

 

Yup, the event system is inspired by the Bukkit event system (however, I feel that my implementation is a bit better than theirs, as there's no need for strange static methods and "handlerLists")

  • Like 1
Link to comment
Share on other sites

  • 1 month later...

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...