implement search stations
This commit is contained in:
199
client/src/main/java/ru/trader/controllers/SearchController.java
Normal file
199
client/src/main/java/ru/trader/controllers/SearchController.java
Normal file
@@ -0,0 +1,199 @@
|
||||
package ru.trader.controllers;
|
||||
|
||||
import javafx.beans.property.*;
|
||||
import javafx.collections.FXCollections;
|
||||
import javafx.collections.ObservableList;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.scene.control.*;
|
||||
import javafx.util.StringConverter;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import ru.trader.core.MarketFilter;
|
||||
import ru.trader.core.SERVICE_TYPE;
|
||||
import ru.trader.model.*;
|
||||
import ru.trader.model.support.BindingsHelper;
|
||||
import ru.trader.model.support.ChangeMarketListener;
|
||||
import ru.trader.view.support.NumberField;
|
||||
import ru.trader.view.support.cells.CustomListCell;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
public class SearchController {
|
||||
private final static Logger LOG = LoggerFactory.getLogger(SearchController.class);
|
||||
|
||||
@FXML
|
||||
private ComboBox<SystemModel> source;
|
||||
@FXML
|
||||
private ComboBox<ItemModel> items;
|
||||
@FXML
|
||||
private NumberField distance;
|
||||
@FXML
|
||||
private CheckBox cbMarket;
|
||||
@FXML
|
||||
private CheckBox cbBlackMarket;
|
||||
@FXML
|
||||
private CheckBox cbRepair;
|
||||
@FXML
|
||||
private CheckBox cbMunition;
|
||||
@FXML
|
||||
private CheckBox cbOutfit;
|
||||
@FXML
|
||||
private CheckBox cbShipyard;
|
||||
@FXML
|
||||
private CheckBox cbMediumLandpad;
|
||||
@FXML
|
||||
private CheckBox cbLargeLandpad;
|
||||
@FXML
|
||||
private TableView<ResultEntry> tblResults;
|
||||
|
||||
private final List<ResultEntry> results = FXCollections.observableArrayList();
|
||||
private final ObservableList<ItemModel> itemsList = FXCollections.observableArrayList();
|
||||
|
||||
private MarketModel market;
|
||||
|
||||
@FXML
|
||||
private void initialize() {
|
||||
items.setCellFactory(new CustomListCell<>(ItemModel::getName));
|
||||
items.setConverter(new StringConverter<ItemModel>() {
|
||||
@Override
|
||||
public String toString(ItemModel item) {
|
||||
return item.getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemModel fromString(String string) {
|
||||
throw new UnsupportedOperationException("Is not editable field");
|
||||
}
|
||||
});
|
||||
BindingsHelper.setTableViewItems(tblResults, results);
|
||||
items.setItems(itemsList);
|
||||
init();
|
||||
}
|
||||
|
||||
void init(){
|
||||
market = MainController.getMarket();
|
||||
market.getNotificator().add(new SearchChangeListener());
|
||||
source.setItems(market.systemsProperty());
|
||||
itemsList.clear();
|
||||
itemsList.add(ModelFabric.NONE_ITEM);
|
||||
itemsList.addAll(market.itemsProperty().get());
|
||||
source.getSelectionModel().selectFirst();
|
||||
}
|
||||
|
||||
|
||||
private void addItem(ItemModel item){
|
||||
itemsList.add(item);
|
||||
}
|
||||
|
||||
private void removeItem(ItemModel item){
|
||||
itemsList.remove(item);
|
||||
}
|
||||
|
||||
@FXML
|
||||
private void searchStations(){
|
||||
MarketFilter filter = new MarketFilter();
|
||||
filter.setDistance(distance.getValue().doubleValue());
|
||||
if (cbMarket.isSelected()) filter.add(SERVICE_TYPE.MARKET); else filter.remove(SERVICE_TYPE.MARKET);
|
||||
if (cbBlackMarket.isSelected()) filter.add(SERVICE_TYPE.BLACK_MARKET); else filter.remove(SERVICE_TYPE.BLACK_MARKET);
|
||||
if (cbMunition.isSelected()) filter.add(SERVICE_TYPE.MUNITION); else filter.remove(SERVICE_TYPE.MUNITION);
|
||||
if (cbRepair.isSelected()) filter.add(SERVICE_TYPE.REPAIR); else filter.remove(SERVICE_TYPE.REPAIR);
|
||||
if (cbOutfit.isSelected()) filter.add(SERVICE_TYPE.OUTFIT); else filter.remove(SERVICE_TYPE.OUTFIT);
|
||||
if (cbShipyard.isSelected()) filter.add(SERVICE_TYPE.SHIPYARD); else filter.remove(SERVICE_TYPE.SHIPYARD);
|
||||
if (cbMediumLandpad.isSelected()) filter.add(SERVICE_TYPE.MEDIUM_LANDPAD); else filter.remove(SERVICE_TYPE.MEDIUM_LANDPAD);
|
||||
if (cbLargeLandpad.isSelected()) filter.add(SERVICE_TYPE.LARGE_LANDPAD); else filter.remove(SERVICE_TYPE.LARGE_LANDPAD);
|
||||
ItemModel item = items.getValue();
|
||||
if (item == null || item == ModelFabric.NONE_ITEM){
|
||||
Collection<StationModel> stations = market.getStations(filter);
|
||||
fill(stations);
|
||||
} else {
|
||||
Collection<OfferModel> offers = market.getOffers(item, filter);
|
||||
fill(offers);
|
||||
}
|
||||
}
|
||||
|
||||
private void fill(Collection<?> entries){
|
||||
results.clear();
|
||||
for (Object entry : entries) {
|
||||
if (entry instanceof StationModel){
|
||||
results.add(new ResultEntry((StationModel) entry));
|
||||
} else {
|
||||
if (entry instanceof OfferModel) {
|
||||
results.add(new ResultEntry((OfferModel) entry));
|
||||
} else {
|
||||
throw new IllegalArgumentException("Argument must have StationModel or OfferModel class");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public class ResultEntry {
|
||||
private final StationModel station;
|
||||
private final OfferModel offer;
|
||||
private final ReadOnlyDoubleProperty distance;
|
||||
|
||||
private ResultEntry(StationModel station) {
|
||||
this(station, null);
|
||||
}
|
||||
|
||||
private ResultEntry(OfferModel offer) {
|
||||
this(offer.getStation(), offer);
|
||||
}
|
||||
|
||||
private ResultEntry(StationModel station, OfferModel offer) {
|
||||
this.station = station;
|
||||
this.offer = offer;
|
||||
this.distance = new SimpleDoubleProperty(source.getValue().getDistance(station.getSystem()));
|
||||
}
|
||||
|
||||
public SystemModel getSystem(){
|
||||
return station.getSystem();
|
||||
}
|
||||
|
||||
private StationModel getStation(){
|
||||
return station;
|
||||
}
|
||||
|
||||
private OfferModel getOffer() {
|
||||
return offer;
|
||||
}
|
||||
|
||||
public ReadOnlyStringProperty stationProperty(){
|
||||
return new SimpleStringProperty(String.format("%s (%.0f Ls)", station.getName(), station.getDistance()));
|
||||
}
|
||||
|
||||
public ReadOnlyStringProperty nameProperty(){
|
||||
return offer != null ? offer.nameProperty() : new SimpleStringProperty("");
|
||||
}
|
||||
|
||||
public ReadOnlyDoubleProperty priceProperty(){
|
||||
return offer != null ? offer.priceProperty() : new SimpleDoubleProperty(Double.NaN);
|
||||
}
|
||||
|
||||
public ReadOnlyLongProperty countProperty(){
|
||||
return offer != null ? offer.countProperty() : new SimpleLongProperty(0);
|
||||
}
|
||||
|
||||
public ReadOnlyDoubleProperty distanceProperty(){
|
||||
return distance;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private class SearchChangeListener extends ChangeMarketListener {
|
||||
|
||||
@Override
|
||||
public void add(ItemModel item) {
|
||||
addItem(item);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove(ItemModel item) {
|
||||
removeItem(item);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -18,6 +18,12 @@ public class ItemModel {
|
||||
private final ItemStatModel statSell;
|
||||
private final ItemStatModel statBuy;
|
||||
|
||||
ItemModel() {
|
||||
this.item = null;
|
||||
this.statSell = null;
|
||||
this.statBuy = null;
|
||||
}
|
||||
|
||||
ItemModel(Item item, MarketModel market) {
|
||||
this.item = item;
|
||||
this.statSell = new ItemStatModel(market.getStat(OFFER_TYPE.SELL, item), market);
|
||||
@@ -30,7 +36,7 @@ public class ItemModel {
|
||||
|
||||
public String getId() {return item.getName();}
|
||||
|
||||
public String getName() {return name != null ? name.get() : item.getName();}
|
||||
public String getName() {return name != null ? name.get() : Localization.getString("item." + item.getName(), item.getName());}
|
||||
|
||||
public void setName(String value) {
|
||||
LOG.info("Change name of item {} to {}", item, value);
|
||||
|
||||
@@ -20,6 +20,7 @@ import ru.trader.services.OrdersSearchTask;
|
||||
import ru.trader.services.RoutesSearchTask;
|
||||
import ru.trader.view.support.Localization;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
|
||||
@@ -122,6 +123,14 @@ public class MarketModel {
|
||||
return market.getStat(type, item);
|
||||
}
|
||||
|
||||
public ObservableList<OfferModel> getOffers(ItemModel item, MarketFilter filter){
|
||||
return BindingsHelper.observableList(analyzer.getOffers(item.getItem(), filter), modeler::get);
|
||||
}
|
||||
|
||||
public Collection<StationModel> getStations(MarketFilter filter){
|
||||
return BindingsHelper.observableList(analyzer.getVendors(filter), modeler::get);
|
||||
}
|
||||
|
||||
public void getOrders(SystemModel from, double balance, Consumer<ObservableList<OrderModel>> result) {
|
||||
getOrders(from, ModelFabric.NONE_STATION, ModelFabric.NONE_SYSTEM, ModelFabric.NONE_STATION, balance, result);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package ru.trader.model;
|
||||
|
||||
import javafx.beans.property.ReadOnlyDoubleProperty;
|
||||
import javafx.beans.property.ReadOnlyObjectProperty;
|
||||
import javafx.beans.property.ReadOnlyStringProperty;
|
||||
import javafx.collections.FXCollections;
|
||||
import javafx.collections.ObservableList;
|
||||
@@ -117,6 +119,7 @@ public class ModelFabric {
|
||||
|
||||
public static SystemModel NONE_SYSTEM = new FAKE_SYSTEM_MODEL();
|
||||
public static StationModel NONE_STATION = new FAKE_STATION_MODEL();
|
||||
public static ItemModel NONE_ITEM = new FAKE_ITEM_MODEL();
|
||||
|
||||
private static class FAKE_SYSTEM_MODEL extends SystemModel {
|
||||
FAKE_SYSTEM_MODEL() {
|
||||
@@ -130,7 +133,7 @@ public class ModelFabric {
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
throw new UnsupportedOperationException("Is fake system, change unsupported");
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -207,7 +210,7 @@ public class ModelFabric {
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
throw new UnsupportedOperationException("Is fake system, unsupported");
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -290,4 +293,110 @@ public class ModelFabric {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
public static class FAKE_ITEM_MODEL extends ItemModel {
|
||||
|
||||
FAKE_ITEM_MODEL() {
|
||||
super();
|
||||
}
|
||||
|
||||
FAKE_ITEM_MODEL(Item item, MarketModel market) {
|
||||
super(item, market);
|
||||
}
|
||||
|
||||
@Override
|
||||
Item getItem() {
|
||||
throw new UnsupportedOperationException("Is fake item, unsupported");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getId() {
|
||||
throw new UnsupportedOperationException("Is fake item, unsupported");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setName(String value) {
|
||||
throw new UnsupportedOperationException("Is fake item, unsupported");
|
||||
}
|
||||
|
||||
@Override
|
||||
public ReadOnlyStringProperty nameProperty() {
|
||||
throw new UnsupportedOperationException("Is fake item, unsupported");
|
||||
}
|
||||
|
||||
@Override
|
||||
public ReadOnlyDoubleProperty avgBuyProperty() {
|
||||
throw new UnsupportedOperationException("Is fake item, unsupported");
|
||||
}
|
||||
|
||||
@Override
|
||||
public ReadOnlyObjectProperty<OfferModel> minBuyProperty() {
|
||||
throw new UnsupportedOperationException("Is fake item, unsupported");
|
||||
}
|
||||
|
||||
@Override
|
||||
public ReadOnlyObjectProperty<OfferModel> maxBuyProperty() {
|
||||
throw new UnsupportedOperationException("Is fake item, unsupported");
|
||||
}
|
||||
|
||||
@Override
|
||||
public ReadOnlyObjectProperty<OfferModel> bestBuyProperty() {
|
||||
throw new UnsupportedOperationException("Is fake item, unsupported");
|
||||
}
|
||||
|
||||
@Override
|
||||
public ReadOnlyDoubleProperty avgSellProperty() {
|
||||
throw new UnsupportedOperationException("Is fake item, unsupported");
|
||||
}
|
||||
|
||||
@Override
|
||||
public ReadOnlyObjectProperty<OfferModel> minSellProperty() {
|
||||
throw new UnsupportedOperationException("Is fake item, unsupported");
|
||||
}
|
||||
|
||||
@Override
|
||||
public ReadOnlyObjectProperty<OfferModel> maxSellProperty() {
|
||||
throw new UnsupportedOperationException("Is fake item, unsupported");
|
||||
}
|
||||
|
||||
@Override
|
||||
public ReadOnlyObjectProperty<OfferModel> bestSellProperty() {
|
||||
throw new UnsupportedOperationException("Is fake item, unsupported");
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<OfferModel> getSeller() {
|
||||
throw new UnsupportedOperationException("Is fake item, unsupported");
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<OfferModel> getBuyer() {
|
||||
throw new UnsupportedOperationException("Is fake item, unsupported");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isMarketItem() {
|
||||
throw new UnsupportedOperationException("Is fake item, unsupported");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void refresh() {
|
||||
throw new UnsupportedOperationException("Is fake item, unsupported");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void refresh(OFFER_TYPE type) {
|
||||
throw new UnsupportedOperationException("Is fake item, unsupported");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,7 +29,6 @@ market.order.seller=Seller
|
||||
market.order.distance=Distance
|
||||
|
||||
# Route
|
||||
routes=Routes
|
||||
routes.path=Path
|
||||
routes.jumps=Jumps
|
||||
routes.refills=Refills
|
||||
@@ -64,6 +63,8 @@ main.menu.settings.language=Language
|
||||
main.menu.settings.language.item=English
|
||||
main.menu.settings.parameters=Preferences
|
||||
main.menu.settings.filter=Filter
|
||||
main.tab.routes=Routes
|
||||
main.tab.search=Search
|
||||
|
||||
# add item dialog
|
||||
dialog.item.title=Adding new commodity
|
||||
@@ -118,6 +119,7 @@ router.pane.route.to=To:
|
||||
router.pane.route.jumps=Jumps:
|
||||
router.button.recompute=Recompute
|
||||
router.button.rebuild=Rebuild
|
||||
router.button.routes=Routes
|
||||
router.button.top=TOP 100
|
||||
router.pane.total=Total
|
||||
router.pane.total.profit=Profit:
|
||||
@@ -156,3 +158,9 @@ analyzer.graph.station.build=Building graph from %s (%s)
|
||||
analyzer.graph.build=Building graph from %s
|
||||
analyzer.graph.success=Graph is built
|
||||
analyser.finish=Finish
|
||||
|
||||
# search.fxml
|
||||
search.text.from=From:
|
||||
search.text.item=Commodity:
|
||||
search.text.distance=Distance \nto station(Ls):
|
||||
search.button.find=Find
|
||||
@@ -29,7 +29,6 @@ market.order.seller=\u041F\u0440\u043E\u0434\u0430\u0432\u0435\u0446
|
||||
market.order.distance=\u0414\u0438\u0441\u0442\u0430\u043D\u0446\u0438\u044F
|
||||
|
||||
# Route
|
||||
routes=\u041C\u0430\u0440\u0448\u0440\u0443\u0442\u044B
|
||||
routes.path=\u041F\u0443\u0442\u044C
|
||||
routes.jumps=\u041F\u0440\u044B\u0436\u043A\u043E\u0432
|
||||
routes.refills=\u0417\u0430\u043F\u0440\u0430\u0432\u043E\u043A
|
||||
@@ -65,6 +64,8 @@ main.menu.settings.language=\u042F\u0437\u044B\u043A
|
||||
main.menu.settings.language.item=\u0420\u0443\u0441\u0441\u043A\u0438\u0439
|
||||
main.menu.settings.parameters=\u041F\u0430\u0440\u0430\u043C\u0435\u0442\u0440\u044B
|
||||
main.menu.settings.filter=\u0424\u0438\u043B\u044C\u0442\u0440
|
||||
main.tab.routes=\u041C\u0430\u0440\u0448\u0440\u0443\u0442\u044B
|
||||
main.tab.search=\u041F\u043E\u0438\u0441\u043A
|
||||
|
||||
# add item dialog
|
||||
dialog.item.title=\u0414\u043E\u0431\u0430\u0432\u043B\u0435\u043D\u0438\u0435 \u043D\u043E\u0432\u043E\u0433\u043E \u0442\u043E\u0432\u0430\u0440\u0430
|
||||
@@ -118,6 +119,7 @@ router.pane.route.to=\u0414\u043E:
|
||||
router.pane.route.jumps=\u041F\u0440\u044B\u0436\u043A\u043E\u0432:
|
||||
router.button.recompute=\u041F\u0435\u0440\u0435\u0441\u0447\u0438\u0442\u0430\u0442\u044C
|
||||
router.button.rebuild=\u041F\u0435\u0440\u0435\u0441\u0442\u0440\u043E\u0438\u0442\u044C
|
||||
router.button.routes=\u041C\u0430\u0440\u0448\u0440\u0443\u0442\u044B
|
||||
router.button.top=TOP 100
|
||||
router.pane.total=\u0418\u0442\u043E\u0433\u043E
|
||||
router.pane.total.profit=\u041F\u0440\u0438\u0431\u044B\u043B\u044C:
|
||||
@@ -156,3 +158,9 @@ analyzer.graph.station.build=\u041F\u043E\u0441\u0442\u0440\u043E\u0439\u043A\u0
|
||||
analyzer.graph.build=\u041F\u043E\u0441\u0442\u0440\u043E\u0439\u043A\u0430 \u0433\u0440\u0430\u0444\u0430 \u043E\u0442 %s
|
||||
analyzer.graph.success=\u0413\u0440\u0430\u0444 \u043F\u043E\u0441\u0442\u0440\u043E\u0435\u043D
|
||||
analyser.finish=\u0413\u043E\u0442\u043E\u0432\u043E
|
||||
|
||||
# search.fxml
|
||||
search.text.from=\u041E\u0442:
|
||||
search.text.item=\u0422\u043E\u0432\u0430\u0440:
|
||||
search.text.distance=\u0414\u0438\u0441\u0442\u0430\u043D\u0446\u0438\u044F \n\u0434\u043E \u0441\u0442\u0430\u043D\u0446\u0438\u0438(Ls):
|
||||
search.button.find=\u041D\u0430\u0439\u0442\u0438
|
||||
@@ -45,9 +45,12 @@
|
||||
<Tab text="%market.systems">
|
||||
<fx:include fx:id="offers" source="offers.fxml"/>
|
||||
</Tab>
|
||||
<Tab text="%routes">
|
||||
<Tab text="%main.tab.routes">
|
||||
<fx:include fx:id="router" source="router.fxml"/>
|
||||
</Tab>
|
||||
<Tab text="%main.tab.search">
|
||||
<fx:include source="search.fxml"/>
|
||||
</Tab>
|
||||
</TabPane>
|
||||
</center>
|
||||
|
||||
|
||||
@@ -64,7 +64,7 @@
|
||||
<Button text="%router.button.top" onAction="#showTopOrders" />
|
||||
</HBox>
|
||||
<HBox alignment="CENTER" spacing="5">
|
||||
<Button prefWidth="80" text="%routes" onAction="#showRoutes" />
|
||||
<Button prefWidth="80" text="%router.button.routes" onAction="#showRoutes" />
|
||||
<Button text="%router.button.top" onAction="#showTopRoutes" />
|
||||
</HBox>
|
||||
</VBox>
|
||||
|
||||
79
client/src/main/resources/view/search.fxml
Normal file
79
client/src/main/resources/view/search.fxml
Normal file
@@ -0,0 +1,79 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<?import javafx.geometry.*?>
|
||||
<?import javafx.scene.control.*?>
|
||||
<?import javafx.scene.layout.*?>
|
||||
|
||||
<?import javafx.scene.control.cell.PropertyValueFactory?>
|
||||
|
||||
<?import ru.trader.view.support.NumberField?>
|
||||
<?import ru.trader.view.support.cells.DistanceCell?>
|
||||
<GridPane xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1"
|
||||
fx:controller="ru.trader.controllers.SearchController">
|
||||
|
||||
<fx:define><Insets fx:id="separator_margin" top="10" bottom="10"/></fx:define>
|
||||
|
||||
<columnConstraints>
|
||||
<ColumnConstraints minWidth="270" maxWidth="270"/>
|
||||
<ColumnConstraints fillWidth="true"/>
|
||||
</columnConstraints>
|
||||
|
||||
<TitledPane text="%market.systems" prefHeight="590" collapsible="false">
|
||||
<GridPane vgap="4">
|
||||
<columnConstraints>
|
||||
<ColumnConstraints minWidth="100"/>
|
||||
<ColumnConstraints minWidth="150" maxWidth="150"/>
|
||||
</columnConstraints>
|
||||
<Label text="%search.text.from" />
|
||||
<ComboBox fx:id="source" prefWidth="150" GridPane.columnIndex="1" />
|
||||
<Label text="%search.text.item" GridPane.rowIndex="1"/>
|
||||
<ComboBox fx:id="items" prefWidth="150" GridPane.columnIndex="1" GridPane.rowIndex="1"/>
|
||||
<Label text="%search.text.distance" GridPane.rowIndex="2" />
|
||||
<NumberField fx:id="distance" GridPane.columnIndex="1" GridPane.rowIndex="2" />
|
||||
<Label text="%filter.services" GridPane.rowIndex="3" />
|
||||
<TilePane hgap="5" vgap="5" tileAlignment="BASELINE_LEFT" GridPane.columnSpan="2" GridPane.rowIndex="4" >
|
||||
<CheckBox fx:id="cbMarket" text="%services.MARKET"/>
|
||||
<CheckBox fx:id="cbBlackMarket" text="%services.BLACK_MARKET"/>
|
||||
<CheckBox fx:id="cbRepair" text="%services.REPAIR"/>
|
||||
<CheckBox fx:id="cbMunition" text="%services.MUNITION"/>
|
||||
<CheckBox fx:id="cbOutfit" text="%services.OUTFIT"/>
|
||||
<CheckBox fx:id="cbShipyard" text="%services.SHIPYARD"/>
|
||||
<CheckBox fx:id="cbMediumLandpad" text="%services.MEDIUM_LANDPAD"/>
|
||||
<CheckBox fx:id="cbLargeLandpad" text="%services.LARGE_LANDPAD"/>
|
||||
</TilePane>
|
||||
<Separator GridPane.columnSpan="2" GridPane.rowIndex="5" GridPane.margin="$separator_margin"/>
|
||||
<HBox GridPane.columnSpan="2" GridPane.rowIndex="6" spacing="10" alignment="CENTER">
|
||||
<Button text="%search.button.find" onAction="#searchStations" />
|
||||
</HBox>
|
||||
</GridPane>
|
||||
</TitledPane>
|
||||
<TableView fx:id="tblResults" GridPane.columnIndex="1" GridPane.hgrow="ALWAYS" GridPane.vgrow="ALWAYS">
|
||||
<columns>
|
||||
<TableColumn minWidth="200.0" text="%market.system.name">
|
||||
<cellValueFactory><PropertyValueFactory property="system"/></cellValueFactory>
|
||||
</TableColumn>
|
||||
<TableColumn minWidth="200.0" text="%market.station.name">
|
||||
<cellValueFactory><PropertyValueFactory property="station"/></cellValueFactory>
|
||||
</TableColumn>
|
||||
<TableColumn minWidth="180.0" text="%market.item.name">
|
||||
<cellValueFactory><PropertyValueFactory property="name"/></cellValueFactory>
|
||||
</TableColumn>
|
||||
<TableColumn minWidth="110.0" text="%market.offer.price">
|
||||
<cellValueFactory><PropertyValueFactory property="price"/></cellValueFactory>
|
||||
</TableColumn>
|
||||
<TableColumn minWidth="110.0" text="%market.offer.supply">
|
||||
<cellValueFactory><PropertyValueFactory property="count"/></cellValueFactory>
|
||||
</TableColumn>
|
||||
<TableColumn minWidth="110.0" text="%market.order.distance" fx:id="sortColumn" sortType="ASCENDING">
|
||||
<cellFactory><DistanceCell /></cellFactory>
|
||||
<cellValueFactory><PropertyValueFactory property="distance"/></cellValueFactory>
|
||||
</TableColumn>
|
||||
</columns>
|
||||
<columnResizePolicy>
|
||||
<TableView fx:constant="UNCONSTRAINED_RESIZE_POLICY"/>
|
||||
</columnResizePolicy>
|
||||
<sortOrder>
|
||||
<fx:reference source="sortColumn"/>
|
||||
</sortOrder>
|
||||
</TableView>
|
||||
</GridPane>
|
||||
@@ -25,7 +25,10 @@ public interface Market {
|
||||
|
||||
Collection<Place> get();
|
||||
default Collection<Vendor> getVendors(){
|
||||
return new PlacesWrapper(get());
|
||||
return getVendors(false);
|
||||
}
|
||||
default Collection<Vendor> getVendors(boolean includeTransit){
|
||||
return new PlacesWrapper(get(), includeTransit);
|
||||
}
|
||||
Collection<Group> getGroups();
|
||||
Collection<Item> getItems();
|
||||
|
||||
@@ -64,6 +64,42 @@ public class MarketAnalyzer {
|
||||
this.limit = count;
|
||||
}
|
||||
|
||||
public Collection<Offer> getOffers(Item item, MarketFilter filter){
|
||||
Collection<Offer> offers = market.getSell(item);
|
||||
Collection<Offer> res = new ArrayList<>(offers.size());
|
||||
callback.setMax(offers.size());
|
||||
for (Offer offer : offers) {
|
||||
if (callback.isCancel()) break;
|
||||
if (isFiltered(offer.getVendor()) || filter.isFiltered(offer.getVendor())){
|
||||
LOG.trace("Is filtered, skip");
|
||||
callback.inc();
|
||||
continue;
|
||||
}
|
||||
res.add(offer);
|
||||
callback.inc();
|
||||
}
|
||||
callback.onEnd();
|
||||
return res;
|
||||
}
|
||||
|
||||
public Collection<Vendor> getVendors(MarketFilter filter){
|
||||
Collection<Vendor> vendors = getVendors();
|
||||
Collection<Vendor> res = new ArrayList<>(vendors.size());
|
||||
callback.setMax(vendors.size());
|
||||
for (Vendor vendor : vendors) {
|
||||
if (callback.isCancel()) break;
|
||||
if (filter.isFiltered(vendor)){
|
||||
LOG.trace("Is filtered, skip");
|
||||
callback.inc();
|
||||
continue;
|
||||
}
|
||||
res.add(vendor);
|
||||
callback.inc();
|
||||
}
|
||||
callback.onEnd();
|
||||
return res;
|
||||
}
|
||||
|
||||
public Collection<Order> getTop(double balance){
|
||||
LOG.debug("Get top {}", limit);
|
||||
Collection<Place> places = getPlaces();
|
||||
@@ -230,14 +266,14 @@ public class MarketAnalyzer {
|
||||
}
|
||||
|
||||
public PathRoute getPath(Vendor from, Vendor to){
|
||||
RouteGraph graph = new RouteGraph(from, getVendors(), tank, maxDistance, true, jumps);
|
||||
RouteGraph graph = new RouteGraph(from, getVendors(true), tank, maxDistance, true, jumps);
|
||||
return (PathRoute)graph.getFastPathTo(to);
|
||||
}
|
||||
|
||||
public Collection<PathRoute> getPaths(Vendor from, double balance){
|
||||
callback.setMax(1);
|
||||
RouteSearcher searcher = new RouteSearcher(maxDistance, tank, segmentSize, callback.onStartSearch());
|
||||
Collection<Vendor> vendors = getVendors();
|
||||
Collection<Vendor> vendors = getVendors(true);
|
||||
Collection<PathRoute> res = searcher.getPaths(from, vendors, jumps, balance, cargo, limit);
|
||||
callback.inc();
|
||||
callback.onEndSearch();
|
||||
@@ -246,7 +282,7 @@ public class MarketAnalyzer {
|
||||
|
||||
public Collection<PathRoute> getPaths(Place from, double balance){
|
||||
List<PathRoute> top = new ArrayList<>(limit);
|
||||
Collection<Vendor> vendors = getVendors();
|
||||
Collection<Vendor> vendors = getVendors(true);
|
||||
callback.setMax(vendors.size());
|
||||
RouteSearcher searcher = new RouteSearcher(maxDistance, tank, segmentSize, callback.onStartSearch());
|
||||
for (Vendor vendor : from.get()) {
|
||||
@@ -267,7 +303,7 @@ public class MarketAnalyzer {
|
||||
public Collection<PathRoute> getPaths(Vendor from, Vendor to, double balance){
|
||||
callback.setMax(1);
|
||||
RouteSearcher searcher = new RouteSearcher(maxDistance, tank, segmentSize, callback.onStartSearch());
|
||||
Collection<PathRoute> res = searcher.getPaths(from, to, getVendors(), jumps, balance, cargo, limit);
|
||||
Collection<PathRoute> res = searcher.getPaths(from, to, getVendors(true), jumps, balance, cargo, limit);
|
||||
callback.inc();
|
||||
callback.onEndSearch();
|
||||
return res;
|
||||
@@ -275,7 +311,7 @@ public class MarketAnalyzer {
|
||||
|
||||
public Collection<PathRoute> getPaths(Place from, Place to, double balance){
|
||||
List<PathRoute> top = new ArrayList<>(limit);
|
||||
Collection<Vendor> vendors = getVendors();
|
||||
Collection<Vendor> vendors = getVendors(true);
|
||||
Collection<Vendor> fVendors = from.get();
|
||||
Collection<Vendor> toVendors = to.get();
|
||||
int count = (int) Math.ceil(limit / fVendors.size());
|
||||
@@ -306,7 +342,7 @@ public class MarketAnalyzer {
|
||||
|
||||
public Collection<PathRoute> getPaths(Vendor from, Place to, double balance){
|
||||
List<PathRoute> top = new ArrayList<>(limit);
|
||||
Collection<Vendor> vendors = getVendors();
|
||||
Collection<Vendor> vendors = getVendors(true);
|
||||
Collection<Vendor> toVendors = to.get();
|
||||
int count = (int) Math.ceil(limit / toVendors.size());
|
||||
callback.setMax(toVendors.size());
|
||||
@@ -328,7 +364,7 @@ public class MarketAnalyzer {
|
||||
|
||||
public Collection<PathRoute> getPaths(Place from, Vendor to, double balance){
|
||||
List<PathRoute> top = new ArrayList<>(limit);
|
||||
Collection<Vendor> vendors = getVendors();
|
||||
Collection<Vendor> vendors = getVendors(true);
|
||||
Collection<Vendor> fVendors = from.get();
|
||||
int count = (int) Math.ceil(limit / fVendors.size());
|
||||
callback.setMax(fVendors.size());
|
||||
@@ -350,7 +386,7 @@ public class MarketAnalyzer {
|
||||
|
||||
public Collection<PathRoute> getTopPaths(double balance){
|
||||
List<PathRoute> top = new ArrayList<>(limit);
|
||||
Collection<Vendor> vendors = getVendors();
|
||||
Collection<Vendor> vendors = getVendors(true);
|
||||
callback.setMax(vendors.size());
|
||||
RouteSearcher searcher = new RouteSearcher(maxDistance, tank, segmentSize, callback.onStartSearch());
|
||||
for (Vendor vendor : vendors) {
|
||||
@@ -389,11 +425,15 @@ public class MarketAnalyzer {
|
||||
}
|
||||
|
||||
private Collection<Vendor> getVendors(){
|
||||
return getVendors(false);
|
||||
}
|
||||
|
||||
private Collection<Vendor> getVendors(boolean includeTransit){
|
||||
if (filter != null){
|
||||
Collection<Vendor> vendors = new PlacesWrapper(getPlaces());
|
||||
Collection<Vendor> vendors = new PlacesWrapper(getPlaces(), includeTransit);
|
||||
return filter.filteredVendors(vendors);
|
||||
} else {
|
||||
return market.getVendors();
|
||||
return market.getVendors(includeTransit);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -8,21 +8,23 @@ import java.util.Iterator;
|
||||
|
||||
public class PlacesWrapper extends AbstractCollection<Vendor> {
|
||||
private final Collection<Place> places;
|
||||
private final boolean includeTransit;
|
||||
private int size;
|
||||
|
||||
public PlacesWrapper(Collection<Place> places) {
|
||||
public PlacesWrapper(Collection<Place> places, boolean includeTransit) {
|
||||
this.places = places;
|
||||
this.includeTransit = includeTransit;
|
||||
size = 0;
|
||||
for (Place place : places) {
|
||||
int count = place.count();
|
||||
size += count > 0 ? count : 1;
|
||||
size += count > 0 ? count : includeTransit ? 1 : 0;
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Iterator<Vendor> iterator() {
|
||||
return new VendorsIterator(places);
|
||||
return new VendorsIterator(places, includeTransit);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -9,11 +9,13 @@ import java.util.Iterator;
|
||||
public class VendorsIterator implements Iterator<Vendor> {
|
||||
|
||||
private final Iterator<Place> places;
|
||||
private final boolean includeTransit;
|
||||
private Iterator<Vendor> vendors;
|
||||
private Vendor next;
|
||||
|
||||
public VendorsIterator(Collection<Place> places) {
|
||||
public VendorsIterator(Collection<Place> places, boolean includeTransit) {
|
||||
this.places = places.iterator();
|
||||
this.includeTransit = includeTransit;
|
||||
nextPlace();
|
||||
}
|
||||
|
||||
@@ -25,7 +27,10 @@ public class VendorsIterator implements Iterator<Vendor> {
|
||||
vendors = v.iterator();
|
||||
nextVendor();
|
||||
} else {
|
||||
if (includeTransit)
|
||||
next = new TransitVendor(place);
|
||||
else
|
||||
nextPlace();
|
||||
}
|
||||
} else {
|
||||
next = null;
|
||||
|
||||
@@ -65,7 +65,7 @@ public class RouteGraphTest extends Assert {
|
||||
|
||||
@Test
|
||||
public void testRoutes() throws Exception {
|
||||
RouteGraph graph = new RouteGraph(v1, market.getVendors(), 1, 1, true, 4);
|
||||
RouteGraph graph = new RouteGraph(v1, market.getVendors(true), 1, 1, true, 4);
|
||||
graph.setBalance(500);
|
||||
graph.setCargo(5);
|
||||
//Profit: 150 180 200 230 670 620 950 890 620 950 1015 1180 890 950 930
|
||||
@@ -97,7 +97,7 @@ public class RouteGraphTest extends Assert {
|
||||
|
||||
@Test
|
||||
public void testRoutes2() throws Exception {
|
||||
RouteGraph graph = new RouteGraph(v5, market.getVendors(), 1, 15, true, 4);
|
||||
RouteGraph graph = new RouteGraph(v5, market.getVendors(true), 1, 15, true, 4);
|
||||
graph.setBalance(500);
|
||||
graph.setCargo(5);
|
||||
ArrayList<Path<Vendor>> routes = (ArrayList<Path<Vendor>>) graph.getPathsTo(v1, 5);
|
||||
|
||||
@@ -28,7 +28,7 @@ public class RouteSearcherTest extends Assert {
|
||||
Vendor ithaca = market.get().stream().filter((v)->v.getName().equals("Ithaca")).findFirst().get().get().iterator().next();
|
||||
|
||||
RouteSearcher searcher = new RouteSearcher(13.4, 40);
|
||||
RouteGraph graph = new RouteGraph(ithaca, market.getVendors(), 40, 13.4, true, 6);
|
||||
RouteGraph graph = new RouteGraph(ithaca, market.getVendors(true), 40, 13.4, true, 6);
|
||||
graph.setCargo(440);
|
||||
graph.setBalance(6000000);
|
||||
|
||||
@@ -36,7 +36,7 @@ public class RouteSearcherTest extends Assert {
|
||||
List<Path<Vendor>> epaths = graph.getPathsTo(ithaca, 10);
|
||||
PathRoute expect = epaths.stream().map(p -> (PathRoute) p).findFirst().get();
|
||||
|
||||
List<PathRoute> apaths = searcher.getPaths(ithaca, ithaca, market.getVendors(), 6, 6000000, 440, 10);
|
||||
List<PathRoute> apaths = searcher.getPaths(ithaca, ithaca, market.getVendors(true), 6, 6000000, 440, 10);
|
||||
PathRoute actual = apaths.stream().findFirst().get();
|
||||
assertTrue("Routes is different",expect.isRoute(actual));
|
||||
|
||||
@@ -51,23 +51,23 @@ public class RouteSearcherTest extends Assert {
|
||||
Vendor lhs3262 = market.get().stream().filter((v)->v.getName().equals("LHS 3262")).findFirst().get().get().iterator().next();
|
||||
|
||||
RouteSearcher searcher = new RouteSearcher(13.6, 40);
|
||||
RouteGraph graph = new RouteGraph(ithaca, market.getVendors(), 40, 13.6, true, 6);
|
||||
RouteGraph graph = new RouteGraph(ithaca, market.getVendors(true), 40, 13.6, true, 6);
|
||||
graph.setCargo(440);
|
||||
graph.setBalance(6000000);
|
||||
|
||||
List<Path<Vendor>> epaths = graph.getPathsTo(ithaca, 10);
|
||||
PathRoute expect = epaths.stream().map(p -> (PathRoute) p).findFirst().get();
|
||||
|
||||
List<PathRoute> apaths = searcher.getPaths(ithaca, ithaca, market.getVendors(), 6, 6000000, 440, 10);
|
||||
List<PathRoute> apaths = searcher.getPaths(ithaca, ithaca, market.getVendors(true), 6, 6000000, 440, 10);
|
||||
PathRoute actual = apaths.stream().findFirst().get();
|
||||
assertTrue("Routes is different",expect.isRoute(actual));
|
||||
|
||||
graph = new RouteGraph(lhs3262, market.getVendors(), 40, 13.6, true, 6);
|
||||
graph = new RouteGraph(lhs3262, market.getVendors(true), 40, 13.6, true, 6);
|
||||
graph.setCargo(440);
|
||||
graph.setBalance(6000000);
|
||||
|
||||
expect = graph.getPathsTo(lhs3262, 10).stream().map(p -> (PathRoute)p).findFirst().get();
|
||||
apaths = searcher.getPaths(lhs3262, lhs3262, market.getVendors(), 6, 6000000, 440, 10);
|
||||
apaths = searcher.getPaths(lhs3262, lhs3262, market.getVendors(true), 6, 6000000, 440, 10);
|
||||
actual = apaths.stream().findFirst().get();
|
||||
assertEquals("Routes is different",expect.getAvgProfit(), actual.getAvgProfit(), 0.00001);
|
||||
|
||||
|
||||
@@ -166,7 +166,6 @@ public class MarketTest extends Assert {
|
||||
|
||||
int c = 3;
|
||||
for (Vendor vendor : market.getVendors()) {
|
||||
if ("Transit".equals(vendor.toString())) continue;
|
||||
if ("Vendor 1".equals(vendor.getName())){
|
||||
assertEquals(vendor1, vendor);
|
||||
assertEquals(place1, vendor.getPlace());
|
||||
@@ -208,12 +207,12 @@ public class MarketTest extends Assert {
|
||||
place1.remove(vendor2);
|
||||
place2.remove(vendor3);
|
||||
|
||||
assertEquals(2, market.getVendors().size());
|
||||
assertEquals(0, market.getVendors().size());
|
||||
|
||||
market.remove(place1);
|
||||
market.remove(place2);
|
||||
|
||||
assertEquals(0, market.getVendors().size());
|
||||
assertEquals(0, market.getVendors(true).size());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -340,7 +339,7 @@ public class MarketTest extends Assert {
|
||||
|
||||
assertEquals(0, market.getSell(item1).size());
|
||||
assertEquals(0, market.getBuy(item1).size());
|
||||
assertEquals(0, market.getVendors().size());
|
||||
assertEquals(0, market.getVendors(true).size());
|
||||
assertEquals(0, market.get().size());
|
||||
assertEquals(0, sellStat.getOffers().size());
|
||||
assertEquals(0, buyStat.getOffers().size());
|
||||
|
||||
Reference in New Issue
Block a user