mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-05 19:42:36 +02:00
GP-2076 domain object event refactor
This commit is contained in:
parent
daca354c47
commit
856aa904aa
143 changed files with 3621 additions and 3652 deletions
|
@ -156,7 +156,7 @@ public abstract class DomainObjectAdapter implements DomainObject {
|
|||
name = newName;
|
||||
changed = true;
|
||||
}
|
||||
fireEvent(new DomainObjectChangeRecord(DO_OBJECT_RENAMED));
|
||||
fireEvent(new DomainObjectChangeRecord(DomainObjectEvent.RENAMED));
|
||||
}
|
||||
|
||||
private void clearDomainObj() {
|
||||
|
@ -195,7 +195,7 @@ public abstract class DomainObjectAdapter implements DomainObject {
|
|||
clearDomainObj();
|
||||
DomainFile oldDf = domainFile;
|
||||
domainFile = df;
|
||||
fireEvent(new DomainObjectChangeRecord(DO_DOMAIN_FILE_CHANGED, oldDf, df));
|
||||
fireEvent(new DomainObjectChangeRecord(DomainObjectEvent.FILE_CHANGED, oldDf, df));
|
||||
fileChangeListeners.invoke().domainFileChanged(this);
|
||||
|
||||
}
|
||||
|
@ -314,7 +314,8 @@ public abstract class DomainObjectAdapter implements DomainObject {
|
|||
if (eventsEnabled != v) {
|
||||
eventsEnabled = v;
|
||||
if (eventsEnabled) {
|
||||
DomainObjectChangeRecord docr = new DomainObjectChangeRecord(DO_OBJECT_RESTORED);
|
||||
DomainObjectChangeRecord docr =
|
||||
new DomainObjectChangeRecord(DomainObjectEvent.RESTORED);
|
||||
docs.fireEvent(docr);
|
||||
for (DomainObjectChangeSupport queue : changeSupportMap.values()) {
|
||||
queue.fireEvent(docr);
|
||||
|
|
|
@ -477,8 +477,8 @@ public abstract class DomainObjectAdapterDB extends DomainObjectAdapter
|
|||
*/
|
||||
protected boolean propertyChanged(String propertyName, Object oldValue, Object newValue) {
|
||||
setChanged(true);
|
||||
fireEvent(
|
||||
new DomainObjectChangeRecord(DomainObject.DO_PROPERTY_CHANGED, propertyName, newValue));
|
||||
fireEvent(new DomainObjectChangeRecord(DomainObjectEvent.PROPERTY_CHANGED, propertyName,
|
||||
newValue));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -534,7 +534,7 @@ public abstract class DomainObjectAdapterDB extends DomainObjectAdapter
|
|||
}
|
||||
|
||||
if (wasSaved) {
|
||||
fireEvent(new DomainObjectChangeRecord(DomainObject.DO_OBJECT_SAVED));
|
||||
fireEvent(new DomainObjectChangeRecord(DomainObjectEvent.SAVED));
|
||||
|
||||
DomainFile df = getDomainFile();
|
||||
if (df instanceof GhidraFile) {
|
||||
|
|
|
@ -190,7 +190,7 @@ class DomainObjectChangeSupport {
|
|||
|
||||
Runnable errorTask = () -> {
|
||||
List<DomainObjectChangeRecord> records =
|
||||
Arrays.asList(new DomainObjectChangeRecord(DomainObject.DO_OBJECT_ERROR, null, t));
|
||||
Arrays.asList(new DomainObjectChangeRecord(DomainObjectEvent.ERROR, null, t));
|
||||
DomainObjectChangedEvent ev = new DomainObjectChangedEvent(src, records);
|
||||
for (DomainObjectListener l : listenersCopy) {
|
||||
try {
|
||||
|
|
|
@ -92,7 +92,7 @@ class DomainObjectTransactionManager extends AbstractTransactionManager {
|
|||
domainObj.clearCache(false);
|
||||
}
|
||||
|
||||
domainObj.fireEvent(new DomainObjectChangeRecord(DomainObject.DO_OBJECT_RESTORED));
|
||||
domainObj.fireEvent(new DomainObjectChangeRecord(DomainObjectEvent.RESTORED));
|
||||
if (notify) {
|
||||
notifyEndTransaction();
|
||||
}
|
||||
|
@ -182,7 +182,7 @@ class DomainObjectTransactionManager extends AbstractTransactionManager {
|
|||
if (notify) {
|
||||
notifyEndTransaction();
|
||||
}
|
||||
domainObj.fireEvent(new DomainObjectChangeRecord(DomainObject.DO_OBJECT_RESTORED));
|
||||
domainObj.fireEvent(new DomainObjectChangeRecord(DomainObjectEvent.RESTORED));
|
||||
transaction.restoreToolStates(true);
|
||||
transaction = null;
|
||||
}
|
||||
|
@ -272,7 +272,7 @@ class DomainObjectTransactionManager extends AbstractTransactionManager {
|
|||
if (domainObj.changeSet != null) {
|
||||
domainObj.changeSet.redo();
|
||||
}
|
||||
domainObj.fireEvent(new DomainObjectChangeRecord(DomainObject.DO_OBJECT_RESTORED));
|
||||
domainObj.fireEvent(new DomainObjectChangeRecord(DomainObjectEvent.RESTORED));
|
||||
undoList.addLast(t);
|
||||
t.restoreToolStates(false);
|
||||
if (notify) {
|
||||
|
@ -291,7 +291,7 @@ class DomainObjectTransactionManager extends AbstractTransactionManager {
|
|||
domainObj.changeSet.undo();
|
||||
}
|
||||
domainObj.clearCache(false);
|
||||
domainObj.fireEvent(new DomainObjectChangeRecord(DomainObject.DO_OBJECT_RESTORED));
|
||||
domainObj.fireEvent(new DomainObjectChangeRecord(DomainObjectEvent.RESTORED));
|
||||
redoList.addLast(t);
|
||||
t.restoreToolStates(true);
|
||||
if (notify) {
|
||||
|
|
|
@ -31,48 +31,69 @@ import ghidra.util.task.TaskMonitor;
|
|||
* data objects that are persistent. <CODE>DomainObject</CODE>s maintain an
|
||||
* association with a <CODE>DomainFile</CODE>. A <CODE>DomainObject</CODE> that
|
||||
* has never been saved will have a null <CODE>DomainFile</CODE>.
|
||||
* <P>
|
||||
* Note: Previously (before 11.1), domain object change event types were defined in this file as
|
||||
* integer constants. Event ids have since been converted to enum types. The defines in this file
|
||||
* have been converted to point to the new enum values to make it easier to convert to this new way
|
||||
* and to clearly see how the old values map to the new enums. In future releases, these defines
|
||||
* will be removed.
|
||||
*/
|
||||
public interface DomainObject {
|
||||
|
||||
/**
|
||||
* Event type generated when the domain object is saved.
|
||||
* @deprecated Event type numeric constants have been changed to enums. Use the enum directly.
|
||||
*/
|
||||
@Deprecated
|
||||
public final static EventType DO_OBJECT_SAVED = DomainObjectEvent.SAVED;
|
||||
|
||||
/**
|
||||
* Event type generated when the domain file associated with
|
||||
* the domain object changes.
|
||||
* @deprecated Event type numeric constants have been changed to enums. Use the enum directly.
|
||||
*/
|
||||
@Deprecated
|
||||
public final static EventType DO_DOMAIN_FILE_CHANGED = DomainObjectEvent.FILE_CHANGED;
|
||||
|
||||
/**
|
||||
* Event type generated when the object name changes.
|
||||
* @deprecated Event type numeric constants have been changed to enums. Use the enum directly.
|
||||
*/
|
||||
@Deprecated
|
||||
public final static EventType DO_OBJECT_RENAMED = DomainObjectEvent.RENAMED;
|
||||
|
||||
/**
|
||||
* Event type generated when domain object is restored.
|
||||
* @deprecated Event type numeric constants have been changed to enums. Use the enum directly.
|
||||
*/
|
||||
@Deprecated
|
||||
public static final EventType DO_OBJECT_RESTORED = DomainObjectEvent.RESTORED;
|
||||
|
||||
/**
|
||||
* Event type generated when a property on this DomainObject is changed.
|
||||
* @deprecated Event type numeric constants have been changed to enums. Use the enum directly.
|
||||
*/
|
||||
@Deprecated
|
||||
public static final EventType DO_PROPERTY_CHANGED = DomainObjectEvent.PROPERTY_CHANGED;
|
||||
|
||||
/**
|
||||
* Event type generated when this domain object is closed.
|
||||
* @deprecated Event type numeric constants have been changed to enums. Use the enum directly.
|
||||
*/
|
||||
@Deprecated
|
||||
public static final EventType DO_OBJECT_CLOSED = DomainObjectEvent.CLOSED;
|
||||
|
||||
/**
|
||||
* Event type generated when a fatal error occurs which renders the domain object invalid.
|
||||
* @deprecated Event type numeric constants have been changed to enums. Use the enum directly.
|
||||
*/
|
||||
@Deprecated
|
||||
public static final EventType DO_OBJECT_ERROR = DomainObjectEvent.ERROR;
|
||||
|
||||
/**
|
||||
* Object to synchronize on for undo/redo operations.
|
||||
*/
|
||||
public final static Object undoLock = new Object();
|
||||
/**
|
||||
* Event type generated when the domain object is saved.
|
||||
*/
|
||||
public final static int DO_OBJECT_SAVED = 1;
|
||||
|
||||
/**
|
||||
* Event type generated when the domain file associated with
|
||||
* the domain object changes.
|
||||
*/
|
||||
public final static int DO_DOMAIN_FILE_CHANGED = 2;
|
||||
|
||||
/**
|
||||
* Event type generated when the object name changes.
|
||||
*/
|
||||
public final static int DO_OBJECT_RENAMED = 3;
|
||||
|
||||
/**
|
||||
* Event type generated when domain object is restored.
|
||||
*/
|
||||
public static final int DO_OBJECT_RESTORED = 4;
|
||||
|
||||
/**
|
||||
* Event type generated when a property on this DomainObject is changed.
|
||||
*/
|
||||
public static final int DO_PROPERTY_CHANGED = 5;
|
||||
|
||||
/**
|
||||
* Event type generated when this domain object is closed.
|
||||
*/
|
||||
public static final int DO_OBJECT_CLOSED = 6;
|
||||
|
||||
/**
|
||||
* Event type generated when a fatal error occurs which renders the domain object invalid.
|
||||
*/
|
||||
public static final int DO_OBJECT_ERROR = 8;
|
||||
|
||||
/**
|
||||
* Returns whether the object has changed.
|
||||
|
|
|
@ -19,82 +19,58 @@ import java.io.Serializable;
|
|||
|
||||
/**
|
||||
* Information about a change that was made to a domain object. The
|
||||
* record is delivered as part of the change notification. The event
|
||||
* types correspond to the constants in
|
||||
* {@link ghidra.program.util.ChangeManager ChangeManager}.
|
||||
* @see ghidra.program.util.ChangeManager ChangeManager
|
||||
* record is delivered as part of the change notification. The event types
|
||||
* correspond to Enums defined in {@link DomainObjectEvent} and
|
||||
* other Enums or objects that implement the {@link EventType} interface.
|
||||
*
|
||||
* Each event record contains the event type and optionally an old value and a new value.
|
||||
* The old value and new value meaning are determined by the event type.
|
||||
*/
|
||||
public class DomainObjectChangeRecord implements Serializable {
|
||||
private final static long serialVersionUID = 1;
|
||||
|
||||
private int eventType;
|
||||
private int subEventType;
|
||||
private EventType eventType;
|
||||
private Object oldValue;
|
||||
private Object newValue;
|
||||
|
||||
/**
|
||||
* Construct a new DomainObjectChangeRecord.
|
||||
* @param eventType the type of event
|
||||
*/
|
||||
public DomainObjectChangeRecord() {
|
||||
this(0, 0, null, null);
|
||||
public DomainObjectChangeRecord(EventType eventType) {
|
||||
this(eventType, null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a new DomainObjectChangeRecord.
|
||||
* @param type event type
|
||||
*/
|
||||
public DomainObjectChangeRecord(int type) {
|
||||
this(type, 0, null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a new DomainObjectChangeRecord.
|
||||
* @param type event type
|
||||
* @param eventType the type of
|
||||
* @param oldValue old value
|
||||
* @param newValue new value
|
||||
*/
|
||||
public DomainObjectChangeRecord(int type, Object oldValue, Object newValue) {
|
||||
this(type, 0, oldValue, newValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a new DomainObjectChangeRecord.
|
||||
* @param type event type
|
||||
* @param subType sub-event type (use 0 if unspecified)
|
||||
* @param oldValue old value
|
||||
* @param newValue new value
|
||||
*/
|
||||
public DomainObjectChangeRecord(int type, int subType, Object oldValue, Object newValue) {
|
||||
eventType = type;
|
||||
subEventType = subType;
|
||||
public DomainObjectChangeRecord(EventType eventType, Object oldValue, Object newValue) {
|
||||
this.eventType = eventType;
|
||||
this.oldValue = oldValue;
|
||||
this.newValue = newValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the event type for this change record.
|
||||
* Returns the event type for this change.
|
||||
* @return the event type for this change
|
||||
*/
|
||||
public int getEventType() {
|
||||
public EventType getEventType() {
|
||||
return eventType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the sub-event type for this change record.
|
||||
* A value of 0 is the default if unspecified.
|
||||
*/
|
||||
public int getSubEventType() {
|
||||
return subEventType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the old value.
|
||||
* Return the old value for this event or null if not applicable.
|
||||
* @return the old value or null if not applicable
|
||||
*/
|
||||
public Object getOldValue() {
|
||||
return oldValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the new value.
|
||||
* Return the new value for this event or null if not applicable.
|
||||
* @return the old value or null if not applicable for this event.
|
||||
*/
|
||||
public Object getNewValue() {
|
||||
return newValue;
|
||||
|
@ -102,13 +78,18 @@ public class DomainObjectChangeRecord implements Serializable {
|
|||
|
||||
@Override
|
||||
public String toString() {
|
||||
//@formatter:off
|
||||
return "{\n" +
|
||||
"\tnewValue: " + newValue + ",\n" +
|
||||
"\toldValue: " + oldValue + ",\n" +
|
||||
"\teventType: " + eventType + ",\n" +
|
||||
"\tsubEventType: " + subEventType + "\n" +
|
||||
"\n}";
|
||||
//@formatter:on
|
||||
StringBuilder buf = new StringBuilder();
|
||||
buf.append(getClass().getSimpleName());
|
||||
buf.append(": event = ");
|
||||
buf.append(eventType);
|
||||
if (oldValue != null) {
|
||||
buf.append(", old = ");
|
||||
buf.append(oldValue);
|
||||
}
|
||||
if (newValue != null) {
|
||||
buf.append(", new = ");
|
||||
buf.append(newValue);
|
||||
}
|
||||
return buf.toString();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
package ghidra.framework.model;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
/**
|
||||
* An event indicating a DomainObject has changed. This event is actually
|
||||
|
@ -45,19 +46,52 @@ public class DomainObjectChangedEvent extends EventObject
|
|||
super(src);
|
||||
this.subEvents = subEvents;
|
||||
for (DomainObjectChangeRecord record : subEvents) {
|
||||
eventBits.set(record.getEventType());
|
||||
eventBits.set(record.getEventType().getId());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the number of change records contained within this event.
|
||||
* @return the number of change records contained within this event
|
||||
*/
|
||||
public int numRecords() {
|
||||
return subEvents.size();
|
||||
}
|
||||
|
||||
public boolean containsEvent(int eventType) {
|
||||
return eventBits.get(eventType);
|
||||
/**
|
||||
* Returns true if this event contains a record with the given event type
|
||||
* @param eventType the event type to check
|
||||
* @return the number of change records contained within this event.
|
||||
*/
|
||||
public boolean contains(EventType eventType) {
|
||||
return eventBits.get(eventType.getId());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this event contains a record with any of the given event types.
|
||||
* @param types the event types to check for
|
||||
* @return true if this event contains a record with any of the given event types
|
||||
*/
|
||||
public boolean contains(EventType... types) {
|
||||
for (EventType eventType : types) {
|
||||
if (eventBits.get(eventType.getId())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this event contains a record with the given event type.
|
||||
* @param eventType the event type to check
|
||||
* @return the number of change records contained within this event.
|
||||
* @deprecated use {@link #contains(EventType)} instead. This is here to help
|
||||
* transition older code from using integer constants for even types to the new enum way
|
||||
* that uses enums instead.
|
||||
*/
|
||||
@Deprecated
|
||||
public boolean containsEvent(EventType eventType) {
|
||||
return eventBits.get(eventType.getId());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -76,4 +110,21 @@ public class DomainObjectChangedEvent extends EventObject
|
|||
public Iterator<DomainObjectChangeRecord> iterator() {
|
||||
return subEvents.iterator();
|
||||
}
|
||||
|
||||
/**
|
||||
* Loops over all records in this event and calls the consumer for each record that matches
|
||||
* the given type.
|
||||
* @param type the event type to apply the consumer
|
||||
* @param consumer the consumer to call for each record of the given type
|
||||
*/
|
||||
public void forEach(EventType type, Consumer<DomainObjectChangeRecord> consumer) {
|
||||
if (!contains(type)) {
|
||||
return;
|
||||
}
|
||||
for (DomainObjectChangeRecord docr : subEvents) {
|
||||
if (docr.getEventType() == type) {
|
||||
consumer.accept(docr);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
/* ###
|
||||
* 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.framework.model;
|
||||
|
||||
/**
|
||||
* Basic event types for all Domain Objects.
|
||||
*/
|
||||
public enum DomainObjectEvent implements EventType {
|
||||
SAVED, // the DomainObject was saved
|
||||
FILE_CHANGED, // the associated DomainFile changed (file moved, renamed, etc.)
|
||||
RENAMED, // the DomainObject was renamed
|
||||
RESTORED, // the DomainObject was changed, all data should be assumed stale
|
||||
PROPERTY_CHANGED, // a generic property of this DomainObject changed
|
||||
CLOSED, // the DomainObject was closed
|
||||
ERROR; // a fatal error occurred
|
||||
|
||||
private final int id = DomainObjectEventIdGenerator.next();
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
/* ###
|
||||
* 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.framework.model;
|
||||
|
||||
/**
|
||||
* Class for providing unique, compact ids for domain object event types.
|
||||
*/
|
||||
public class DomainObjectEventIdGenerator {
|
||||
private static int nextId = 0;
|
||||
|
||||
public synchronized static int next() {
|
||||
return ++nextId;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
/* ###
|
||||
* 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.framework.model;
|
||||
|
||||
/**
|
||||
* Interface for objects that represent event types. This interface has only one method and that
|
||||
* method exists to facilitate fast checking if an event type is present in a collection of events.
|
||||
* The value returned from getId() is arbitrary and can change from run to run. Its only purpose
|
||||
* is to give each event type a unique compact id that can be used as an index into a bit set. It is
|
||||
* important that implementers of this interface get their id values by calling
|
||||
* {@link DomainObjectEventIdGenerator#next()} so that all event ids are coordinated and as
|
||||
* small as possible.
|
||||
* <P>
|
||||
* The preferred implementation of EventType is an enum that enumerates the valid event types
|
||||
* for any application sub-system. See {@link DomainObjectEvent} for an example implementation.
|
||||
*
|
||||
*/
|
||||
public interface EventType {
|
||||
|
||||
/**
|
||||
* Returns the unique id assigned to this event type. The value is guaranteed to be constant
|
||||
* for any given run of the application, but can vary from run to run.
|
||||
* @return the unique event id assigned to this EventType.
|
||||
*/
|
||||
public int getId();
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue