From 99fea69520d5acaf490537d98c12791b615951e9 Mon Sep 17 00:00:00 2001 From: 7u83 <7u83@maiil.ru> Date: Tue, 25 Dec 2018 18:16:45 +0100 Subject: [PATCH] Improvements on EventListener Event ... --- src/opensesim/gui/SeSimApplication.java | 25 +++++++- .../gui/orderbook/OrderBookDialog.form | 11 ++-- .../gui/orderbook/OrderBookDialog.java | 26 +++++--- .../gui/orderbook/OrderBookPanel.java | 63 +++++++++++++------ src/opensesim/trader/SimpleTrader.java | 1 + src/opensesim/world/Exchange.java | 16 +++++ src/opensesim/world/TradingAPI.java | 5 +- src/opensesim/world/scheduler/Event.java | 17 ++--- .../world/scheduler/FiringEvent.java | 45 +++++++++++++ src/opensesim/world/scheduler/Scheduler.java | 16 ++--- 10 files changed, 168 insertions(+), 57 deletions(-) create mode 100644 src/opensesim/world/scheduler/FiringEvent.java diff --git a/src/opensesim/gui/SeSimApplication.java b/src/opensesim/gui/SeSimApplication.java index 88d8bd1..e266628 100644 --- a/src/opensesim/gui/SeSimApplication.java +++ b/src/opensesim/gui/SeSimApplication.java @@ -37,6 +37,7 @@ import java.io.File; import java.io.IOException; import java.io.InputStream; +import java.util.HashSet; import java.util.Scanner; import java.util.Set; import javax.swing.JDialog; @@ -64,6 +65,7 @@ import opensesim.world.Order; import opensesim.world.Trader; import opensesim.world.TradingAPI; import opensesim.world.World; +import opensesim.world.scheduler.FiringEvent; import opensesim.world.scheduler.EventListener; @@ -616,7 +618,7 @@ public class SeSimApplication extends javax.swing.JFrame { for (Order o: ob){ double v = o.getVolume(); - System.out.printf("Volume: %d\n",o.getVolume()); + System.out.printf("Volume: %f\n",o.getVolume()); } @@ -907,10 +909,29 @@ public class SeSimApplication extends javax.swing.JFrame { stopSim(); }//GEN-LAST:event_stopButtonActionPerformed + public class GodWorldEvent extends FiringEvent{ + public GodWorld goworld; + public GodWorldEvent(EventListener listener) { + super(listener); + } + + } + + HashSet gwlisteners = new HashSet<>(); + + void updateGodWorld(GodWorld godworld){ + GodWorldEvent e = new GodWorldEvent(null); + for (EventListener el : gwlisteners){ + + } + } + private void jCheckBoxMenuItem1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jCheckBoxMenuItem1ActionPerformed // JDialog jd = new opensesim.gui.orderbook.OrderBookDialog(this, false); // jd.setVisible(rootPaneCheckingEnabled); - opensesim.gui.orderbook.OrderBookDialog.runDialog(this, godworld); + EventListener e = opensesim.gui.orderbook.OrderBookDialog.runDialog(this, godworld); + gwlisteners.add(e); + }//GEN-LAST:event_jCheckBoxMenuItem1ActionPerformed diff --git a/src/opensesim/gui/orderbook/OrderBookDialog.form b/src/opensesim/gui/orderbook/OrderBookDialog.form index fd10b3e..1ca758e 100644 --- a/src/opensesim/gui/orderbook/OrderBookDialog.form +++ b/src/opensesim/gui/orderbook/OrderBookDialog.form @@ -23,9 +23,9 @@ - + - + @@ -34,17 +34,14 @@ - - + + - - - diff --git a/src/opensesim/gui/orderbook/OrderBookDialog.java b/src/opensesim/gui/orderbook/OrderBookDialog.java index 2274276..3b8cfa9 100644 --- a/src/opensesim/gui/orderbook/OrderBookDialog.java +++ b/src/opensesim/gui/orderbook/OrderBookDialog.java @@ -26,14 +26,16 @@ package opensesim.gui.orderbook; import java.awt.Frame; -import java.awt.Window; import opensesim.world.GodWorld; +import opensesim.world.scheduler.Event; +import opensesim.world.scheduler.FiringEvent; +import opensesim.world.scheduler.EventListener; /** * * @author 7u83 <7u83@mail.ru> */ -public class OrderBookDialog extends javax.swing.JDialog { +public class OrderBookDialog extends javax.swing.JDialog implements EventListener{ /** * Creates new form OrderBookDialog @@ -47,13 +49,13 @@ public class OrderBookDialog extends javax.swing.JDialog { GodWorld godworld; - static public void runDialog(Frame parent, GodWorld godworld){ + static public EventListener runDialog(Frame parent, GodWorld godworld){ OrderBookDialog d = new OrderBookDialog(parent,false); d.godworld=godworld; d.setVisible(true); // d.dispose(); - + return d; } /** @@ -65,7 +67,7 @@ public class OrderBookDialog extends javax.swing.JDialog { // //GEN-BEGIN:initComponents private void initComponents() { - orderBookPanel1 = new opensesim.gui.orderbook.OrderBookPanel(godworld); + orderBookPanel1 = new opensesim.gui.orderbook.OrderBookPanel(); setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); @@ -73,17 +75,17 @@ public class OrderBookDialog extends javax.swing.JDialog { getContentPane().setLayout(layout); layout.setHorizontalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(layout.createSequentialGroup() + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() .addContainerGap() - .addComponent(orderBookPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, 418, Short.MAX_VALUE) + .addComponent(orderBookPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addContainerGap()) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addContainerGap() - .addComponent(orderBookPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addComponent(orderBookPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addContainerGap()) ); pack(); @@ -134,4 +136,10 @@ public class OrderBookDialog extends javax.swing.JDialog { // Variables declaration - do not modify//GEN-BEGIN:variables private opensesim.gui.orderbook.OrderBookPanel orderBookPanel1; // End of variables declaration//GEN-END:variables + + @Override + public long receive(Event task) { + this.orderBookPanel1.setGodWorld(godworld); + return 0; + } } diff --git a/src/opensesim/gui/orderbook/OrderBookPanel.java b/src/opensesim/gui/orderbook/OrderBookPanel.java index e903fd4..31a81e7 100644 --- a/src/opensesim/gui/orderbook/OrderBookPanel.java +++ b/src/opensesim/gui/orderbook/OrderBookPanel.java @@ -29,7 +29,6 @@ import opensesim.gui.Globals; import opensesim.gui.util.NummericCellRenderer; import java.awt.Component; import java.text.DecimalFormat; -import java.util.ArrayList; import java.util.Collection; import java.util.Timer; import java.util.TimerTask; @@ -39,12 +38,14 @@ import javax.swing.table.DefaultTableCellRenderer; import javax.swing.table.DefaultTableModel; import javax.swing.table.TableColumn; import javax.swing.table.TableColumnModel; +import opensesim.world.AssetPair; +import opensesim.world.Exchange; import opensesim.world.GodWorld; import opensesim.world.Order; - import opensesim.world.TradingAPI; import opensesim.world.scheduler.Event; +import opensesim.world.scheduler.FiringEvent; import opensesim.world.scheduler.EventListener; /** @@ -55,12 +56,14 @@ public class OrderBookPanel extends javax.swing.JPanel implements EventListener DefaultTableModel model; TableColumn trader_column = null; - - TradingAPI api=null; + + TradingAPI api = null; @Override public long receive(Event task) { - synchronized (this) { + System.out.printf("There is an o event \n"); + + synchronized (this) { if (oupdate) { new_oupdate = true; return 0; @@ -120,35 +123,59 @@ public class OrderBookPanel extends javax.swing.JPanel implements EventListener /** * Bla */ -/* @Override + /* @Override public final void cfgChanged() { boolean gm = Globals.prefs.get(Globals.CfgStrings.GODMODE, "false").equals("true"); setGodMode(gm); list.invalidate(); list.repaint(); } -*/ + */ -/* + /* public void setType(OrderType type) { this.type = type; Globals.se.addBookReceiver(type, this); } -*/ - + */ + public OrderBookPanel() { + initComponents(); + } + GodWorld godworld; + + public void setGodWorld(GodWorld godworld) { + // is our world alread the godworld to set? + if (this.godworld == godworld) { + return; + } + + this.godworld = godworld; + Exchange ex = godworld.getDefaultExchange(); + AssetPair ap = godworld.getDefaultAssetPair(); + api = ex.getAPI(ap); + api.addOrderBookListener(this); + + } + /** * Creates new form OrderBookNew */ public OrderBookPanel(GodWorld godworld) { + initComponents(); if (Globals.world == null) { - return; +// return; } - + this.godworld = godworld; - + + Exchange ex = godworld.getDefaultExchange(); + AssetPair ap = godworld.getDefaultAssetPair(); + api = ex.getAPI(ap); + api.addOrderBookListener(this); + model = (DefaultTableModel) this.list.getModel(); trader_column = list.getColumnModel().getColumn(0); list.getColumnModel().getColumn(1).setCellRenderer(new NummericCellRenderer(3)); @@ -156,15 +183,15 @@ public class OrderBookPanel extends javax.swing.JPanel implements EventListener // cfgChanged(); // Globals.se.addBookReceiver(Exchange.OrderType.BUYLIMIT, this); // Globals.addCfgListener(this); - + new Timer().schedule(new TimerTask() { @Override public void run() { - // System.out.printf("Update order book\n"); - // UpdateOrderBook(); + // System.out.printf("Update order book\n"); + // UpdateOrderBook(); } }, 1000, 1000); - + } boolean oupdate = false; @@ -175,7 +202,7 @@ public class OrderBookPanel extends javax.swing.JPanel implements EventListener void oupdater() { // ArrayList ob = Globals.se.getOrderBook(type, depth); - Collection ob = api.getOrderBook(Order.Type.BUY); + Collection ob = api.getOrderBook(Order.Type.BUY); model.setRowCount(ob.size()); int row = 0; diff --git a/src/opensesim/trader/SimpleTrader.java b/src/opensesim/trader/SimpleTrader.java index 9c4d7c4..2ba29da 100644 --- a/src/opensesim/trader/SimpleTrader.java +++ b/src/opensesim/trader/SimpleTrader.java @@ -33,6 +33,7 @@ import opensesim.world.Order; import opensesim.world.TradingAPI; import opensesim.world.World; import opensesim.world.scheduler.Event; +import opensesim.world.scheduler.FiringEvent; import opensesim.world.scheduler.EventListener; import org.json.JSONObject; diff --git a/src/opensesim/world/Exchange.java b/src/opensesim/world/Exchange.java index ee028c4..4acd740 100644 --- a/src/opensesim/world/Exchange.java +++ b/src/opensesim/world/Exchange.java @@ -35,6 +35,8 @@ import java.util.TreeSet; import opensesim.world.RealWorld; import opensesim.sesim.interfaces.Configurable; import opensesim.sesim.interfaces.GetJson; +import opensesim.world.scheduler.FiringEvent; +import opensesim.world.scheduler.EventListener; import org.json.JSONObject; /** @@ -145,14 +147,22 @@ public class Exchange implements Configurable, GetJson { } } + + + @Override public Order createOrder(Account account, Order.Type type, double volume, double limit) { + Order o = new opensesim.world.Order(world, account, pair, type, volume, limit); synchronized (this){ order_books.get(o.type).add(o); } + for (FiringEvent e:book_listener){ + e.fire(); + } + return o; } @@ -160,6 +170,12 @@ public class Exchange implements Configurable, GetJson { public Set getOrderBook(Order.Type type) { return Collections.unmodifiableSet(order_books.get(type)); } + + HashSet book_listener = new HashSet<>(); + @Override + public void addOrderBookListener(EventListener listener) { + book_listener.add(new FiringEvent(listener)); + } diff --git a/src/opensesim/world/TradingAPI.java b/src/opensesim/world/TradingAPI.java index 54297c4..326cd24 100644 --- a/src/opensesim/world/TradingAPI.java +++ b/src/opensesim/world/TradingAPI.java @@ -26,13 +26,16 @@ package opensesim.world; import java.util.Set; +import opensesim.world.scheduler.EventListener; /** * * @author tube */ public interface TradingAPI { - + + public void addOrderBookListener(EventListener listener); + public Order createOrder(Account account, Order.Type type, double volume, double limit); public Set getOrderBook(Order.Type type); diff --git a/src/opensesim/world/scheduler/Event.java b/src/opensesim/world/scheduler/Event.java index 92a8f2c..50c939a 100644 --- a/src/opensesim/world/scheduler/Event.java +++ b/src/opensesim/world/scheduler/Event.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 7u83 <7u83@mail.ru> + * Copyright (c) 2018, tube * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -25,17 +25,10 @@ */ package opensesim.world.scheduler; - /** * - * @author 7u83 <7u83@mail.ru> + * @author tube */ - public class Event { - - EventListener listener; - - Event(EventListener listener) { - this.listener = listener; - } - - } \ No newline at end of file +public abstract class Event { + +} diff --git a/src/opensesim/world/scheduler/FiringEvent.java b/src/opensesim/world/scheduler/FiringEvent.java new file mode 100644 index 0000000..bb1bd98 --- /dev/null +++ b/src/opensesim/world/scheduler/FiringEvent.java @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2018, 7u83 <7u83@mail.ru> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +package opensesim.world.scheduler; + + +/** + * + * @author 7u83 <7u83@mail.ru> + */ + public class FiringEvent extends Event { + + EventListener listener; + + public FiringEvent(EventListener listener) { + this.listener = listener; + } + + public void fire(){ + listener.receive(this); + } + + } \ No newline at end of file diff --git a/src/opensesim/world/scheduler/Scheduler.java b/src/opensesim/world/scheduler/Scheduler.java index 7596c6f..00f6652 100644 --- a/src/opensesim/world/scheduler/Scheduler.java +++ b/src/opensesim/world/scheduler/Scheduler.java @@ -37,7 +37,7 @@ import opensesim.world.scheduler.EventListener; */ public class Scheduler { - private final SortedMap> event_queue = new TreeMap<>(); + private final SortedMap> event_queue = new TreeMap<>(); private class Worker extends Thread { @@ -64,7 +64,7 @@ public class Scheduler { } continue; } - Event e = getNextEvent(); + FiringEvent e = getNextEvent(); if (e == null) { continue; @@ -96,11 +96,11 @@ public class Scheduler { } } - public Event startTimerTask(EventListener listener, long time) { - Event e = new Event(listener); + public FiringEvent startTimerTask(EventListener listener, long time) { + FiringEvent e = new FiringEvent(listener); long t = time + clock.currentTimeMillis(); synchronized (event_queue) { - LinkedList s = event_queue.get(t); + LinkedList s = event_queue.get(t); if (s == null) { s = new LinkedList<>(); event_queue.put(t, s); @@ -129,7 +129,7 @@ public class Scheduler { } } - protected Event getNextEvent() { + protected FiringEvent getNextEvent() { // System.out.printf("RunEvents in Thread %d\n",Thread.currentThread().getId()); synchronized (event_queue) { @@ -138,9 +138,9 @@ public class Scheduler { } long t = event_queue.firstKey(); - LinkedList s = event_queue.get(t); + LinkedList s = event_queue.get(t); - Event e = s.pop(); + FiringEvent e = s.pop(); if (s.isEmpty()) { event_queue.remove(t); }