Skip to content

Commit

Permalink
Merge pull request #518 from xpdota/table-display-improvements
Browse files Browse the repository at this point in the history
Clean up events tab and table details
  • Loading branch information
xpdota authored Jul 16, 2024
2 parents cc1e2d9 + 86c1f87 commit 7149fee
Show file tree
Hide file tree
Showing 10 changed files with 187 additions and 178 deletions.
1 change: 1 addition & 0 deletions reevent/src/main/java/gg/xp/reevent/events/Event.java
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ default boolean delayedEnqueueAtFront() {
return false;
}

@Deprecated // Use Groovy methods instead
default Map<Field, Object> dumpFields() {
return Utils.dumpAllFields(this);
}
Expand Down
105 changes: 17 additions & 88 deletions xivsupport/src/main/java/gg/xp/xivsupport/gui/GuiMain.java
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
import gg.xp.xivsupport.gui.tables.filters.SystemLogLoggerNameFilter;
import gg.xp.xivsupport.gui.tables.filters.SystemLogTextFilter;
import gg.xp.xivsupport.gui.tables.filters.SystemLogThreadFilter;
import gg.xp.xivsupport.gui.tables.groovy.GroovyColumns;
import gg.xp.xivsupport.gui.tables.renderers.ActionAndStatusRenderer;
import gg.xp.xivsupport.gui.tables.renderers.NameJobRenderer;
import gg.xp.xivsupport.gui.tabs.AdvancedTab;
Expand Down Expand Up @@ -80,6 +81,7 @@
import gg.xp.xivsupport.speech.TtsRequest;
import gg.xp.xivsupport.sys.Threading;
import gg.xp.xivsupport.sys.XivMain;
import groovy.lang.PropertyValue;
import org.apache.commons.io.IOUtils;
import org.intellij.lang.annotations.Language;
import org.jetbrains.annotations.NotNull;
Expand Down Expand Up @@ -728,20 +730,9 @@ private void getAndAddTabs() {
private JPanel getCombatantsPanel() {
// Main table
XivState state = container.getComponent(XivStateImpl.class);
TableWithFilterAndDetails<XivCombatant, Map.Entry<Field, Object>> table = TableWithFilterAndDetails.builder("Combatants",
TableWithFilterAndDetails<XivCombatant, PropertyValue> table = TableWithFilterAndDetails.builder("Combatants",
() -> state.getCombatantsListCopy().stream().sorted(Comparator.comparing(XivEntity::getId)).collect(Collectors.toList()),
combatant -> {
if (combatant == null) {
return Collections.emptyList();
}
else {
return Utils.dumpAllFields(combatant)
.entrySet()
.stream()
.filter(e -> !"serialVersionUID".equals(e.getKey().getName()))
.collect(Collectors.toList());
}
})
GroovyColumns::getValues)
.addMainColumn(StandardColumns.entityIdColumn)
.addMainColumn(StandardColumns.nameJobColumn)
.addMainColumn(columns.statusEffectsColumn())
Expand All @@ -750,13 +741,8 @@ private JPanel getCombatantsPanel() {
.addMainColumn(columns.hpColumnWithUnresolved())
.addMainColumn(StandardColumns.mpColumn)
.addMainColumn(StandardColumns.posColumn)
.addDetailsColumn(StandardColumns.fieldName)
.addDetailsColumn(StandardColumns.fieldValue)
.addDetailsColumn(StandardColumns.identity)
.addDetailsColumn(StandardColumns.fieldType)
.addDetailsColumn(StandardColumns.fieldDeclaredIn)
.apply(GroovyColumns::addDetailColumns)
.setSelectionEquivalence((a, b) -> a.getId() == b.getId())
.setDetailsSelectionEquivalence((a, b) -> a.getKey().equals(b.getKey()))
.addFilter(EventEntityFilter::selfFilter)
.addFilter(NonCombatEntityFilter::new)
.withRightClickRepo(rightClicks)
Expand All @@ -773,19 +759,8 @@ private JPanel getCombatantsPanel() {
private JPanel getStatusEffectsPanel() {
// Main table
StatusEffectRepository repo = container.getComponent(StatusEffectRepository.class);
TableWithFilterAndDetails<BuffApplied, Map.Entry<Field, Object>> table = TableWithFilterAndDetails.builder("Status Effects", repo::getBuffs,
combatant -> {
if (combatant == null) {
return Collections.emptyList();
}
else {
return Utils.dumpAllFields(combatant)
.entrySet()
.stream()
.filter(e -> !"serialVersionUID".equals(e.getKey().getName()))
.collect(Collectors.toList());
}
})
TableWithFilterAndDetails<BuffApplied, PropertyValue> table = TableWithFilterAndDetails.builder("Status Effects", repo::getBuffs,
GroovyColumns::getValues)
.addMainColumn(new CustomColumn<>("Source", BuffApplied::getSource, c -> c.setCellRenderer(new NameJobRenderer())))
.addMainColumn(new CustomColumn<>("Target", BuffApplied::getTarget, c -> c.setCellRenderer(new NameJobRenderer())))
.addMainColumn(new CustomColumn<>("Buff/Ability", BuffApplied::getBuff, c -> c.setCellRenderer(new ActionAndStatusRenderer())))
Expand All @@ -799,11 +774,7 @@ private JPanel getStatusEffectsPanel() {
c.setMinWidth(100);
c.setMaxWidth(100);
}))
.addDetailsColumn(StandardColumns.fieldName)
.addDetailsColumn(StandardColumns.fieldValue)
.addDetailsColumn(StandardColumns.identity)
.addDetailsColumn(StandardColumns.fieldType)
.addDetailsColumn(StandardColumns.fieldDeclaredIn)
.apply(GroovyColumns::addDetailColumns)
.setSelectionEquivalence(Object::equals)
.addFilter(EventEntityFilter::buffSourceFilter)
.addFilter(EventEntityFilter::buffTargetFilter)
Expand All @@ -827,26 +798,11 @@ private JPanel getActLogPanel() {
// The second way was to stream and filter the raw event storage, but that is inefficient because it scales
// very poorly and causes higher CPU usage.
// The third, not-hacky way is to just have RawEventStorage track events of a particular type for us
TableWithFilterAndDetails<ACTLogLineEvent, Map.Entry<Field, Object>> table = TableWithFilterAndDetails.builder("ACT Log",
TableWithFilterAndDetails<ACTLogLineEvent, PropertyValue> table = TableWithFilterAndDetails.builder("ACT Log",
() -> rawStorage.getEventsOfType(ACTLogLineEvent.class),
currentEvent -> {
if (currentEvent == null) {
return Collections.emptyList();
}
else {
return currentEvent.dumpFields()
.entrySet()
.stream()
.filter(e -> !"serialVersionUID".equals(e.getKey().getName()))
.collect(Collectors.toList());
}
})
GroovyColumns::getValues)
.addMainColumn(new CustomColumn<>("Line", ACTLogLineEvent::getLogLine))
.addDetailsColumn(StandardColumns.fieldName)
.addDetailsColumn(StandardColumns.fieldValue)
.addDetailsColumn(StandardColumns.identity)
.addDetailsColumn(StandardColumns.fieldType)
.addDetailsColumn(StandardColumns.fieldDeclaredIn)
.apply(GroovyColumns::addDetailColumns)
.withRightClickRepo(rightClicks)
.addFilter(ActLineFilter::new)
.addWidget(replayNextPseudoFilter(ACTLogLineEvent.class))
Expand All @@ -867,17 +823,9 @@ private JPanel getSystemLogPanel() {
return panel;
}
else {
TableWithFilterAndDetails<LogEvent, Map.Entry<Field, Object>> table = TableWithFilterAndDetails.builder("System Log",
TableWithFilterAndDetails<LogEvent, PropertyValue> table = TableWithFilterAndDetails.builder("System Log",
instance::getEvents,
e -> {
if (e == null) {
return Collections.emptyList();
}
return Stream.concat(
Utils.dumpAllFields(e).entrySet().stream(),
Utils.dumpAllFields(e.getEvent()).entrySet().stream()
).collect(Collectors.toList());
})
GroovyColumns::getValues)
.addMainColumn(new CustomColumn<>("Time",
e -> Instant.ofEpochMilli(e.getEvent().getTimeStamp())
.atZone(ZoneId.systemDefault())
Expand Down Expand Up @@ -925,11 +873,7 @@ else if (value == Level.WARN) {
col.setPreferredWidth(900);
}))
.withRightClickRepo(rightClicks)
.addDetailsColumn(StandardColumns.fieldName)
.addDetailsColumn(StandardColumns.fieldValue)
.addDetailsColumn(StandardColumns.identity)
.addDetailsColumn(StandardColumns.fieldType)
.addDetailsColumn(StandardColumns.fieldDeclaredIn)
.apply(GroovyColumns::addDetailColumns)
.addFilter(LogLevelVisualFilter::new)
.addFilter(SystemLogThreadFilter::new)
.addFilter(SystemLogLoggerNameFilter::new)
Expand Down Expand Up @@ -957,20 +901,9 @@ private String formatLocalTime(@NotNull Instant t) {

private JPanel getPullsTab() {
PullTracker pulls = state.get(PullTracker.class);
TableWithFilterAndDetails<Pull, Map.Entry<Field, Object>> table = TableWithFilterAndDetails.builder("Pulls",
TableWithFilterAndDetails<Pull, PropertyValue> table = TableWithFilterAndDetails.builder("Pulls",
pulls::getPulls,
currentPull -> {
if (currentPull == null) {
return Collections.emptyList();
}
else {
return Utils.dumpAllFields(currentPull)
.entrySet()
.stream()
.filter(e -> !"serialVersionUID".equals(e.getKey().getName()))
.collect(Collectors.toList());
}
})
GroovyColumns::getValues)
.addMainColumn(new CustomColumn<>("Number", Pull::getPullNum, col -> {
col.setMinWidth(50);
col.setMaxWidth(50);
Expand Down Expand Up @@ -1008,11 +941,7 @@ private JPanel getPullsTab() {
}, col -> {
col.setPreferredWidth(200);
}))
.addDetailsColumn(StandardColumns.fieldName)
.addDetailsColumn(StandardColumns.fieldValue)
.addDetailsColumn(StandardColumns.identity)
.addDetailsColumn(StandardColumns.fieldType)
.addDetailsColumn(StandardColumns.fieldDeclaredIn)
.apply(GroovyColumns::addDetailColumns)
.withRightClickRepo(rightClicks.withMore(CustomRightClickOption.forRow("Filter Events Tab to This", Pull.class, pull -> {
PullNumberFilter pnf = container.getComponent(PullNumberFilter.class);
pnf.setPullNumberExternally(pull.getPullNum());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import gg.xp.xivsupport.gui.components.ReadOnlyText;
import gg.xp.xivsupport.gui.tables.CustomColumn;
import gg.xp.xivsupport.gui.tables.CustomTableModel;
import gg.xp.xivsupport.gui.tables.groovy.GroovyColumns;
import gg.xp.xivsupport.gui.tabs.GroovyTab;
import gg.xp.xivsupport.gui.util.EasyAction;
import gg.xp.xivsupport.persistence.gui.BoundCheckbox;
Expand Down Expand Up @@ -314,7 +315,7 @@ private JTextArea errorDisplayComponent(String text) {

private JTable simpleListDisplay(Collection<?> values) {
return CustomTableModel.builder(() -> new ArrayList<>(values))
.addColumn(new CustomColumn<>("Value", GroovyPanel::singleValueConversion))
.addColumn(new CustomColumn<>("Value", GroovyColumns::singleValueConversion))
.build()
.makeTable();
}
Expand All @@ -323,37 +324,19 @@ private JTable customTableListDisplay(DisplayControl dc, Collection<?> values) {
return dc.getListDisplay().makeTable(sbx, values);
}

private JTable simpleMapDisplay(Map<?, ?> map) {
return CustomTableModel.builder(() -> new ArrayList<>(map.entrySet()))
.addColumn(new CustomColumn<>("Key", e -> singleValueConversion(e.getKey())))
.addColumn(new CustomColumn<>("Value", e -> singleValueConversion(e.getValue())))
private JTable simplePropsDisplay(Object object) {
return CustomTableModel.builder(() -> GroovyColumns.getValues(object))
.apply(GroovyColumns::addColumns)
.build()
.makeTable();
}

// TODO: move this
@SuppressWarnings("MalformedFormatString")
public static String singleValueConversion(Object obj) {
if (obj == null) {
return "(null)";
}
if (obj instanceof Byte || obj instanceof Integer || obj instanceof Long || obj instanceof Short) {
return String.format("%d (0x%x)", obj, obj);
}
// TODO: arrays
// if (obj instanceof Array arr) {
// arr.getClass().arrayType()
// }
if (obj.getClass().isArray()) {
int length = Array.getLength(obj);
List<Object> converted = new ArrayList<>();
for (int i = 0; i < length; i++) {
converted.add(Array.get(obj, i));
}
return converted.stream().map(GroovyPanel::singleValueConversion).collect(Collectors.joining(", ", "[", "]"));
}
return obj.toString();

private JTable simpleMapDisplay(Map<?, ?> map) {
return CustomTableModel.builder(() -> new ArrayList<>(map.entrySet()))
.addColumn(new CustomColumn<>("Key", e -> GroovyColumns.singleValueConversion(e.getKey())))
.addColumn(new CustomColumn<>("Value", e -> GroovyColumns.singleValueConversion(e.getValue())))
.build()
.makeTable();
}

private void submit() {
Expand Down Expand Up @@ -457,19 +440,7 @@ private Component listDisplay(GroovyScriptResult result, Collection<?> coll) {
}

private void setResultDisplay(@Nullable Object obj, Component display) {
Map<?, ?> props;
if (obj == null) {
props = Collections.emptyMap();
}
else {
try {
props = DefaultGroovyMethods.getProperties(obj);
}
catch (Throwable t) {
props = Collections.emptyMap();
}
}
JTable md = simpleMapDisplay(props);
JTable md = simplePropsDisplay(obj);
SwingUtilities.invokeLater(() -> {
resultPropertiesScroll.setViewportView(md);
resultScroll.setViewportView(display);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import gg.xp.xivsupport.gui.tables.CustomColumn;
import gg.xp.xivsupport.gui.tables.CustomTableModel;
import gg.xp.xivsupport.gui.tables.groovy.GroovyColumns;
import org.codehaus.groovy.runtime.DefaultGroovyMethods;
import org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.GroovySandbox;
import org.jetbrains.annotations.Nullable;
Expand All @@ -18,7 +19,6 @@
import java.util.Map;
import java.util.function.Function;

import static gg.xp.xivsupport.gui.groovy.GroovyPanel.singleValueConversion;

public class ListTableDisplay {
private final List<TableColumn> cols;
Expand Down Expand Up @@ -123,7 +123,7 @@ private Object convertValue(@Nullable TableColumn<?, ?, ?> colDef, @Nullable Obj
.filter(td -> td.applicableTo(value))
.findFirst()
.map(td -> td.func().apply(value))
.orElseGet(() -> singleValueConversion(value));
.orElseGet(() -> GroovyColumns.singleValueConversion(value));
}

public static ListTableDisplay autoPropTable() {
Expand Down
24 changes: 5 additions & 19 deletions xivsupport/src/main/java/gg/xp/xivsupport/gui/map/MapTab.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,10 @@
import gg.xp.xivsupport.gui.tables.filters.EventEntityFilter;
import gg.xp.xivsupport.gui.tables.filters.GroovyFilter;
import gg.xp.xivsupport.gui.tables.filters.NonCombatEntityFilter;
import gg.xp.xivsupport.gui.tables.groovy.GroovyColumns;
import gg.xp.xivsupport.models.XivCombatant;
import gg.xp.xivsupport.models.XivEntity;
import groovy.lang.PropertyValue;

import javax.swing.*;
import java.awt.*;
Expand All @@ -30,7 +32,7 @@
@ScanMe
public class MapTab extends JPanel {

private final TableWithFilterAndDetails<XivCombatant, Map.Entry<Field, Object>> table;
private final TableWithFilterAndDetails<XivCombatant, PropertyValue> table;
private final RefreshLoop<MapTab> mapRefresh;
private final MapPanel mapPanel;
private final MapDataController mapDataController;
Expand All @@ -54,18 +56,7 @@ public MapTab(GroovyManager mgr, MapDataController mdc, MapConfig config, MapDis

table = TableWithFilterAndDetails.builder("Combatants",
() -> mdc.getCombatants().stream().sorted(Comparator.comparing(XivEntity::getId)).collect(Collectors.toList()),
combatant -> {
if (combatant == null) {
return Collections.emptyList();
}
else {
return Utils.dumpAllFields(combatant)
.entrySet()
.stream()
.filter(e -> !"serialVersionUID".equals(e.getKey().getName()))
.collect(Collectors.toList());
}
})
GroovyColumns::getValues)
.addMainColumn(StandardColumns.entityIdColumn)
.addMainColumn(StandardColumns.nameJobColumn)
.addMainColumn(StandardColumns.sortedStatusEffectsColumn(mdc::buffsOnCombatant))
Expand All @@ -75,13 +66,8 @@ public MapTab(GroovyManager mgr, MapDataController mdc, MapConfig config, MapDis
.addMainColumn(StandardColumns.hpColumnWithUnresolved(mdc::unresolvedDamage))
// .addMainColumn(StandardColumns.mpColumn)
// .addMainColumn(StandardColumns.posColumn)
.addDetailsColumn(StandardColumns.fieldName)
.addDetailsColumn(StandardColumns.fieldValue)
.addDetailsColumn(StandardColumns.identity)
.addDetailsColumn(StandardColumns.fieldType)
.addDetailsColumn(StandardColumns.fieldDeclaredIn)
.apply(GroovyColumns::addDetailColumns)
.setSelectionEquivalence((a, b) -> a.getId() == b.getId())
.setDetailsSelectionEquivalence((a, b) -> a.getKey().equals(b.getKey()))
.addFilter(EventEntityFilter::selfFilter)
.addFilter(NonCombatEntityFilter::new)
.addFilter(GroovyFilter.forClass(XivCombatant.class, mgr, "it"))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.BiPredicate;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.stream.Collectors;

Expand All @@ -41,6 +43,15 @@ public CustomTableModelBuilder<B> addColumn(CustomColumn<? super B> colDef) {
return this;
}

public CustomTableModelBuilder<B> apply(Consumer<? super CustomTableModelBuilder<B>> func) {
func.accept(this);
return this;
}

public CustomTableModelBuilder<B> transform(Function<? super CustomTableModelBuilder<B>, CustomTableModelBuilder<B>> func) {
return func.apply(this);
}

public CustomTableModel<B> build() {
return new CustomTableModel<B>(dataGetter, columns, selectionEquivalence);
}
Expand Down
Loading

0 comments on commit 7149fee

Please sign in to comment.