mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-06 12:00:04 +02:00
GP-3084: Views listen to Trace without extra queue
This commit is contained in:
parent
5b543c1847
commit
94648ff140
6 changed files with 250 additions and 176 deletions
|
@ -26,6 +26,7 @@ import com.google.common.cache.RemovalNotification;
|
||||||
import db.DBHandle;
|
import db.DBHandle;
|
||||||
import generic.depends.DependentService;
|
import generic.depends.DependentService;
|
||||||
import generic.depends.err.ServiceConstructionException;
|
import generic.depends.err.ServiceConstructionException;
|
||||||
|
import ghidra.framework.model.DomainObjectChangeRecord;
|
||||||
import ghidra.framework.options.Options;
|
import ghidra.framework.options.Options;
|
||||||
import ghidra.lifecycle.Internal;
|
import ghidra.lifecycle.Internal;
|
||||||
import ghidra.program.model.address.*;
|
import ghidra.program.model.address.*;
|
||||||
|
@ -139,6 +140,8 @@ public class DBTrace extends DBCachedDomainObjectAdapter implements Trace, Trace
|
||||||
protected boolean recordChanges = false;
|
protected boolean recordChanges = false;
|
||||||
|
|
||||||
protected Set<DBTraceTimeViewport> viewports = new WeakHashCowSet<>();
|
protected Set<DBTraceTimeViewport> viewports = new WeakHashCowSet<>();
|
||||||
|
protected ListenerSet<DBTraceDirectChangeListener> directListeners =
|
||||||
|
new ListenerSet<>(DBTraceDirectChangeListener.class);
|
||||||
protected DBTraceVariableSnapProgramView programView;
|
protected DBTraceVariableSnapProgramView programView;
|
||||||
protected Set<DBTraceVariableSnapProgramView> programViews = new WeakHashCowSet<>();
|
protected Set<DBTraceVariableSnapProgramView> programViews = new WeakHashCowSet<>();
|
||||||
protected Set<TraceProgramView> programViewsView = Collections.unmodifiableSet(programViews);
|
protected Set<TraceProgramView> programViewsView = Collections.unmodifiableSet(programViews);
|
||||||
|
@ -585,6 +588,23 @@ public class DBTrace extends DBCachedDomainObjectAdapter implements Trace, Trace
|
||||||
fireEvent(event);
|
fireEvent(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void fireEvent(DomainObjectChangeRecord ev) {
|
||||||
|
super.fireEvent(ev);
|
||||||
|
if (directListeners != null) {
|
||||||
|
// Some events fire during construction
|
||||||
|
directListeners.fire.changed(ev);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addDirectChangeListener(DBTraceDirectChangeListener listener) {
|
||||||
|
directListeners.add(listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeDirectChangeListener(DBTraceDirectChangeListener listener) {
|
||||||
|
directListeners.remove(listener);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DBTraceProgramView getFixedProgramView(long snap) {
|
public DBTraceProgramView getFixedProgramView(long snap) {
|
||||||
// NOTE: The new viewport will need to read from the time manager during init
|
// NOTE: The new viewport will need to read from the time manager during init
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
/* ###
|
||||||
|
* IP: GHIDRA
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package ghidra.trace.database;
|
||||||
|
|
||||||
|
import ghidra.framework.model.DomainObjectChangeRecord;
|
||||||
|
|
||||||
|
public interface DBTraceDirectChangeListener {
|
||||||
|
void changed(DomainObjectChangeRecord rec);
|
||||||
|
}
|
|
@ -42,8 +42,7 @@ import ghidra.program.model.util.AddressSetPropertyMap;
|
||||||
import ghidra.program.model.util.PropertyMapManager;
|
import ghidra.program.model.util.PropertyMapManager;
|
||||||
import ghidra.program.util.ChangeManager;
|
import ghidra.program.util.ChangeManager;
|
||||||
import ghidra.program.util.ProgramChangeRecord;
|
import ghidra.program.util.ProgramChangeRecord;
|
||||||
import ghidra.trace.database.DBTrace;
|
import ghidra.trace.database.*;
|
||||||
import ghidra.trace.database.DBTraceTimeViewport;
|
|
||||||
import ghidra.trace.database.listing.DBTraceCodeSpace;
|
import ghidra.trace.database.listing.DBTraceCodeSpace;
|
||||||
import ghidra.trace.database.listing.DBTraceDefinedUnitsView;
|
import ghidra.trace.database.listing.DBTraceDefinedUnitsView;
|
||||||
import ghidra.trace.database.memory.DBTraceMemorySpace;
|
import ghidra.trace.database.memory.DBTraceMemorySpace;
|
||||||
|
@ -82,7 +81,8 @@ public class DBTraceProgramView implements TraceProgramView {
|
||||||
public static final int TIME_INTERVAL = 100;
|
public static final int TIME_INTERVAL = 100;
|
||||||
public static final int BUF_SIZE = 1000;
|
public static final int BUF_SIZE = 1000;
|
||||||
|
|
||||||
protected class EventTranslator extends TraceDomainObjectListener {
|
protected class EventTranslator extends TypedEventDispatcher
|
||||||
|
implements DBTraceDirectChangeListener {
|
||||||
public EventTranslator() {
|
public EventTranslator() {
|
||||||
listenForUntyped(DomainObject.DO_OBJECT_SAVED, this::eventPassthrough);
|
listenForUntyped(DomainObject.DO_OBJECT_SAVED, this::eventPassthrough);
|
||||||
listenForUntyped(DomainObject.DO_DOMAIN_FILE_CHANGED, this::eventPassthrough);
|
listenForUntyped(DomainObject.DO_DOMAIN_FILE_CHANGED, this::eventPassthrough);
|
||||||
|
@ -172,6 +172,11 @@ public class DBTraceProgramView implements TraceProgramView {
|
||||||
listenFor(TraceSymbolChangeType.DELETED, this::symbolDeleted);
|
listenFor(TraceSymbolChangeType.DELETED, this::symbolDeleted);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void changed(DomainObjectChangeRecord event) {
|
||||||
|
handleChangeRecord(event);
|
||||||
|
}
|
||||||
|
|
||||||
private void eventPassthrough(DomainObjectChangeRecord rec) {
|
private void eventPassthrough(DomainObjectChangeRecord rec) {
|
||||||
fireEventAllViews(rec);
|
fireEventAllViews(rec);
|
||||||
}
|
}
|
||||||
|
@ -1376,7 +1381,7 @@ public class DBTraceProgramView implements TraceProgramView {
|
||||||
protected synchronized EventTranslator getEventTranslator() {
|
protected synchronized EventTranslator getEventTranslator() {
|
||||||
if (eventTranslator == null) {
|
if (eventTranslator == null) {
|
||||||
eventTranslator = new EventTranslator();
|
eventTranslator = new EventTranslator();
|
||||||
trace.addListener(eventTranslator);
|
trace.addDirectChangeListener(eventTranslator);
|
||||||
}
|
}
|
||||||
return eventTranslator;
|
return eventTranslator;
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,164 +15,11 @@
|
||||||
*/
|
*/
|
||||||
package ghidra.trace.model;
|
package ghidra.trace.model;
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.function.Consumer;
|
|
||||||
|
|
||||||
import ghidra.framework.model.*;
|
import ghidra.framework.model.*;
|
||||||
import ghidra.trace.util.*;
|
|
||||||
import ghidra.util.TimedMsg;
|
import ghidra.util.TimedMsg;
|
||||||
|
|
||||||
public class TraceDomainObjectListener implements DomainObjectListener {
|
public class TraceDomainObjectListener extends TypedEventDispatcher
|
||||||
|
implements DomainObjectListener {
|
||||||
public interface EventRecordHandler<T, U> {
|
|
||||||
void handle(TraceChangeRecord<T, U> record);
|
|
||||||
}
|
|
||||||
|
|
||||||
public interface FullEventRecordHandler<T, U> extends EventRecordHandler<T, U> {
|
|
||||||
void handle(TraceAddressSpace space, T affectedObject, U oldValue, U newValue);
|
|
||||||
|
|
||||||
@Override
|
|
||||||
default void handle(TraceChangeRecord<T, U> record) {
|
|
||||||
handle(record.getSpace(), record.getAffectedObject(), record.getOldValue(),
|
|
||||||
record.getNewValue());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public interface AffectedObjectHandler<T> extends EventRecordHandler<T, Void> {
|
|
||||||
void handle(TraceAddressSpace space, T affectedObject);
|
|
||||||
|
|
||||||
@Override
|
|
||||||
default void handle(TraceChangeRecord<T, Void> record) {
|
|
||||||
handle(record.getSpace(), record.getAffectedObject());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public interface AffectedObjectOnlyHandler<T> extends EventRecordHandler<T, Void> {
|
|
||||||
void handle(T affectedObject);
|
|
||||||
|
|
||||||
@Override
|
|
||||||
default void handle(TraceChangeRecord<T, Void> record) {
|
|
||||||
handle(record.getAffectedObject());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public interface AffectedAndValuesOnlyHandler<T, U> extends EventRecordHandler<T, U> {
|
|
||||||
void handle(T affectedObject, U oldValue, U newValue);
|
|
||||||
|
|
||||||
@Override
|
|
||||||
default void handle(TraceChangeRecord<T, U> record) {
|
|
||||||
handle(record.getAffectedObject(), record.getOldValue(), record.getNewValue());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public interface SpaceValuesHandler<U> extends EventRecordHandler<Void, U> {
|
|
||||||
void handle(TraceAddressSpace space, U oldValue, U newValue);
|
|
||||||
|
|
||||||
@Override
|
|
||||||
default void handle(TraceChangeRecord<Void, U> record) {
|
|
||||||
handle(record.getSpace(), record.getOldValue(), record.getNewValue());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public interface ValuesOnlyHandler<U> extends EventRecordHandler<Void, U> {
|
|
||||||
void handle(U oldValue, U newValue);
|
|
||||||
|
|
||||||
@Override
|
|
||||||
default void handle(TraceChangeRecord<Void, U> record) {
|
|
||||||
handle(record.getOldValue(), record.getNewValue());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public interface IgnoreValuesHandler extends EventRecordHandler<Object, Object> {
|
|
||||||
void handle(TraceAddressSpace space);
|
|
||||||
|
|
||||||
@Override
|
|
||||||
default void handle(TraceChangeRecord<Object, Object> record) {
|
|
||||||
handle(record.getSpace());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public interface IgnoreAllHandler extends EventRecordHandler<Object, Object> {
|
|
||||||
void handle();
|
|
||||||
|
|
||||||
@Override
|
|
||||||
default void handle(TraceChangeRecord<Object, Object> record) {
|
|
||||||
handle();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private Map<TraceChangeType<?, ?>, EventRecordHandler<?, ?>> typedMap = new HashMap<>();
|
|
||||||
private Map<Integer, Consumer<DomainObjectChangeRecord>> untypedMap = new HashMap<>();
|
|
||||||
private Consumer<DomainObjectChangeRecord> restoredHandler = null;
|
|
||||||
|
|
||||||
protected <T, U> void listenFor(TraceChangeType<T, U> type, EventRecordHandler<T, U> handler) {
|
|
||||||
typedMap.put(type, handler);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected <T, U> void listenFor(TraceChangeType<T, U> type,
|
|
||||||
FullEventRecordHandler<? super T, ? super U> handler) {
|
|
||||||
typedMap.put(type, handler);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected <T, U> void listenFor(TraceChangeType<T, U> type,
|
|
||||||
AffectedObjectHandler<? super T> handler) {
|
|
||||||
typedMap.put(type, handler);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected <T, U> void listenFor(TraceChangeType<T, U> type,
|
|
||||||
AffectedObjectOnlyHandler<? super T> handler) {
|
|
||||||
typedMap.put(type, handler);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Listen for the given event, taking the affected object, the old value, and the new value
|
|
||||||
*
|
|
||||||
* @param <T> the type of the affected object
|
|
||||||
* @param <U> the type of the values
|
|
||||||
* @param type the event type
|
|
||||||
* @param handler the handler
|
|
||||||
*/
|
|
||||||
protected <T, U> void listenFor(TraceChangeType<T, U> type,
|
|
||||||
AffectedAndValuesOnlyHandler<? super T, ? super U> handler) {
|
|
||||||
typedMap.put(type, handler);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected <T, U> void listenFor(TraceChangeType<T, U> type,
|
|
||||||
ValuesOnlyHandler<? super U> handler) {
|
|
||||||
typedMap.put(type, handler);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected <T, U> void listenFor(TraceChangeType<T, U> type,
|
|
||||||
SpaceValuesHandler<? super U> handler) {
|
|
||||||
typedMap.put(type, handler);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void listenFor(TraceChangeType<?, ?> type, IgnoreValuesHandler handler) {
|
|
||||||
typedMap.put(type, handler);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void listenFor(TraceChangeType<?, ?> type, IgnoreAllHandler handler) {
|
|
||||||
typedMap.put(type, handler);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void listenForUntyped(int type, Consumer<DomainObjectChangeRecord> handler) {
|
|
||||||
if (type == DomainObject.DO_OBJECT_RESTORED) {
|
|
||||||
restoredHandler = handler;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
untypedMap.put(type, handler);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
public void handleTraceChangeRecord(TraceChangeRecord<?,?> rec) {
|
|
||||||
@SuppressWarnings("rawtypes")
|
|
||||||
EventRecordHandler handler = typedMap.get(rec.getType());
|
|
||||||
if (handler != null) {
|
|
||||||
handler.handle(rec);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void domainObjectChanged(DomainObjectChangedEvent ev) {
|
public void domainObjectChanged(DomainObjectChangedEvent ev) {
|
||||||
|
@ -189,23 +36,8 @@ public class TraceDomainObjectListener implements DomainObjectListener {
|
||||||
}
|
}
|
||||||
//Map<String, Integer> CountsByType = new TreeMap<>();
|
//Map<String, Integer> CountsByType = new TreeMap<>();
|
||||||
for (DomainObjectChangeRecord rec : ev) {
|
for (DomainObjectChangeRecord rec : ev) {
|
||||||
//String typeName = DefaultTraceChangeType.getName(rec.getEventType());
|
handleChangeRecord(rec);
|
||||||
//CountsByType.compute(typeName, (k, v) -> v == null ? 1 : v + 1);
|
|
||||||
if (rec instanceof TraceChangeRecord) {
|
|
||||||
handleTraceChangeRecord((TraceChangeRecord<?, ?>) rec);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
Consumer<DomainObjectChangeRecord> handler;
|
|
||||||
if (null != (handler = untypedMap.get(rec.getEventType()))) {
|
|
||||||
handler.accept(rec);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
unhandled(rec);
|
|
||||||
}
|
}
|
||||||
//TimedMsg.info(this, " Done: " + CountsByType);
|
//TimedMsg.info(this, " Done: " + CountsByType);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void unhandled(DomainObjectChangeRecord rec) {
|
|
||||||
// Extension point
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,195 @@
|
||||||
|
/* ###
|
||||||
|
* IP: GHIDRA
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package ghidra.trace.model;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
|
import ghidra.framework.model.DomainObject;
|
||||||
|
import ghidra.framework.model.DomainObjectChangeRecord;
|
||||||
|
import ghidra.trace.util.*;
|
||||||
|
|
||||||
|
public class TypedEventDispatcher {
|
||||||
|
|
||||||
|
public interface EventRecordHandler<T, U> {
|
||||||
|
void handle(TraceChangeRecord<T, U> record);
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface FullEventRecordHandler<T, U> extends EventRecordHandler<T, U> {
|
||||||
|
void handle(TraceAddressSpace space, T affectedObject, U oldValue, U newValue);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
default void handle(TraceChangeRecord<T, U> record) {
|
||||||
|
handle(record.getSpace(), record.getAffectedObject(), record.getOldValue(),
|
||||||
|
record.getNewValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface AffectedObjectHandler<T> extends EventRecordHandler<T, Void> {
|
||||||
|
void handle(TraceAddressSpace space, T affectedObject);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
default void handle(TraceChangeRecord<T, Void> record) {
|
||||||
|
handle(record.getSpace(), record.getAffectedObject());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface AffectedObjectOnlyHandler<T> extends EventRecordHandler<T, Void> {
|
||||||
|
void handle(T affectedObject);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
default void handle(TraceChangeRecord<T, Void> record) {
|
||||||
|
handle(record.getAffectedObject());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface AffectedAndValuesOnlyHandler<T, U> extends EventRecordHandler<T, U> {
|
||||||
|
void handle(T affectedObject, U oldValue, U newValue);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
default void handle(TraceChangeRecord<T, U> record) {
|
||||||
|
handle(record.getAffectedObject(), record.getOldValue(), record.getNewValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface SpaceValuesHandler<U> extends EventRecordHandler<Void, U> {
|
||||||
|
void handle(TraceAddressSpace space, U oldValue, U newValue);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
default void handle(TraceChangeRecord<Void, U> record) {
|
||||||
|
handle(record.getSpace(), record.getOldValue(), record.getNewValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface ValuesOnlyHandler<U> extends EventRecordHandler<Void, U> {
|
||||||
|
void handle(U oldValue, U newValue);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
default void handle(TraceChangeRecord<Void, U> record) {
|
||||||
|
handle(record.getOldValue(), record.getNewValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface IgnoreValuesHandler extends EventRecordHandler<Object, Object> {
|
||||||
|
void handle(TraceAddressSpace space);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
default void handle(TraceChangeRecord<Object, Object> record) {
|
||||||
|
handle(record.getSpace());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface IgnoreAllHandler extends EventRecordHandler<Object, Object> {
|
||||||
|
void handle();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
default void handle(TraceChangeRecord<Object, Object> record) {
|
||||||
|
handle();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Map<TraceChangeType<?, ?>, EventRecordHandler<?, ?>> typedMap = new HashMap<>();
|
||||||
|
private Map<Integer, Consumer<DomainObjectChangeRecord>> untypedMap = new HashMap<>();
|
||||||
|
protected Consumer<DomainObjectChangeRecord> restoredHandler = null;
|
||||||
|
|
||||||
|
protected <T, U> void listenFor(TraceChangeType<T, U> type, EventRecordHandler<T, U> handler) {
|
||||||
|
typedMap.put(type, handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected <T, U> void listenFor(TraceChangeType<T, U> type,
|
||||||
|
FullEventRecordHandler<? super T, ? super U> handler) {
|
||||||
|
typedMap.put(type, handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected <T, U> void listenFor(TraceChangeType<T, U> type,
|
||||||
|
AffectedObjectHandler<? super T> handler) {
|
||||||
|
typedMap.put(type, handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected <T, U> void listenFor(TraceChangeType<T, U> type,
|
||||||
|
AffectedObjectOnlyHandler<? super T> handler) {
|
||||||
|
typedMap.put(type, handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Listen for the given event, taking the affected object, the old value, and the new value
|
||||||
|
*
|
||||||
|
* @param <T> the type of the affected object
|
||||||
|
* @param <U> the type of the values
|
||||||
|
* @param type the event type
|
||||||
|
* @param handler the handler
|
||||||
|
*/
|
||||||
|
protected <T, U> void listenFor(TraceChangeType<T, U> type,
|
||||||
|
AffectedAndValuesOnlyHandler<? super T, ? super U> handler) {
|
||||||
|
typedMap.put(type, handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected <T, U> void listenFor(TraceChangeType<T, U> type,
|
||||||
|
ValuesOnlyHandler<? super U> handler) {
|
||||||
|
typedMap.put(type, handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected <T, U> void listenFor(TraceChangeType<T, U> type,
|
||||||
|
SpaceValuesHandler<? super U> handler) {
|
||||||
|
typedMap.put(type, handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void listenFor(TraceChangeType<?, ?> type, IgnoreValuesHandler handler) {
|
||||||
|
typedMap.put(type, handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void listenFor(TraceChangeType<?, ?> type, IgnoreAllHandler handler) {
|
||||||
|
typedMap.put(type, handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void listenForUntyped(int type, Consumer<DomainObjectChangeRecord> handler) {
|
||||||
|
if (type == DomainObject.DO_OBJECT_RESTORED) {
|
||||||
|
restoredHandler = handler;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
untypedMap.put(type, handler);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void handleChangeRecord(DomainObjectChangeRecord rec) {
|
||||||
|
//String typeName = DefaultTraceChangeType.getName(rec.getEventType());
|
||||||
|
//CountsByType.compute(typeName, (k, v) -> v == null ? 1 : v + 1);
|
||||||
|
if (rec instanceof TraceChangeRecord) {
|
||||||
|
handleTraceChangeRecord((TraceChangeRecord<?, ?>) rec);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Consumer<DomainObjectChangeRecord> handler;
|
||||||
|
if (null != (handler = untypedMap.get(rec.getEventType()))) {
|
||||||
|
handler.accept(rec);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
unhandled(rec);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public void handleTraceChangeRecord(TraceChangeRecord<?, ?> rec) {
|
||||||
|
@SuppressWarnings("rawtypes")
|
||||||
|
EventRecordHandler handler = typedMap.get(rec.getType());
|
||||||
|
if (handler != null) {
|
||||||
|
handler.handle(rec);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void unhandled(DomainObjectChangeRecord rec) {
|
||||||
|
// Extension point
|
||||||
|
}
|
||||||
|
}
|
|
@ -65,7 +65,7 @@ class DomainObjectChangeSupport {
|
||||||
this.timer =
|
this.timer =
|
||||||
GhidraTimerFactory.getGhidraTimer(timeInterval, timeInterval, this::sendEventNow);
|
GhidraTimerFactory.getGhidraTimer(timeInterval, timeInterval, this::sendEventNow);
|
||||||
timer.setInitialDelay(25);
|
timer.setInitialDelay(25);
|
||||||
timer.setDelay(500);
|
timer.setDelay(timeInterval);
|
||||||
timer.setRepeats(true);
|
timer.setRepeats(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue