diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterLayoutNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterLayoutNode.java index 5021006acdc..77c05d42d19 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterLayoutNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/register/RegisterLayoutNode.java @@ -12,14 +12,19 @@ package org.eclipse.dd.dsf.debug.ui.viewmodel.register; import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; import org.eclipse.dd.dsf.concurrent.RequestMonitor; -import org.eclipse.dd.dsf.datamodel.IDMContext; import org.eclipse.dd.dsf.datamodel.IDMEvent; +import org.eclipse.dd.dsf.datamodel.IDMService; +import org.eclipse.dd.dsf.debug.service.IFormattedValues; import org.eclipse.dd.dsf.debug.service.IRegisters; import org.eclipse.dd.dsf.debug.service.IRunControl; +import org.eclipse.dd.dsf.debug.service.IFormattedValues.FormattedValueDMContext; +import org.eclipse.dd.dsf.debug.service.IFormattedValues.FormattedValueDMData; +import org.eclipse.dd.dsf.debug.service.IRegisters.IRegisterChangedDMEvent; import org.eclipse.dd.dsf.debug.service.IRegisters.IRegisterDMContext; import org.eclipse.dd.dsf.debug.service.IRegisters.IRegisterDMData; import org.eclipse.dd.dsf.debug.service.IRegisters.IRegisterGroupDMContext; import org.eclipse.dd.dsf.service.DsfSession; +import org.eclipse.dd.dsf.service.IDsfService; import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMProvider; import org.eclipse.dd.dsf.ui.viewmodel.VMDelta; import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMLayoutNode; @@ -34,6 +39,168 @@ public class RegisterLayoutNode extends AbstractDMVMLayoutNode super(provider, session, IRegisters.IRegisterDMContext.class); } + /** + * Private data access routine which performs the extra level of data access needed to + * get the formatted data value for a specific register. + */ + private void updateFormattedRegisterValue(final ILabelUpdate update, final int labelIndex, final IRegisterDMContext dmc) + { + final IRegisters regService = getServicesTracker().getService(IRegisters.class); + /* + * PREFPAGE : We are using a default format until the preference page is created + * + * First select the format to be used. This involves checking so see that the preference + * page format is supported by the register service. If the format is not supported then + * we will pick the first available format. + */ + + final String preferencePageFormatId = IFormattedValues.HEX_FORMAT; + + regService.getAvailableFormattedValues( + dmc, + new DataRequestMonitor(getSession().getExecutor(), null) { + @Override + public void handleCompleted() { + if (!getStatus().isOK()) { + handleFailedUpdate(update); + return; + } + + /* + * See if the desired format is supported. + */ + String[] formatIds = getData(); + String finalFormatId = IFormattedValues.HEX_FORMAT; + boolean requestedFormatIsSupported = false; + + for ( String fId : formatIds ) { + if ( preferencePageFormatId.equals(fId) ) { + /* + * Desired format is supported. + */ + finalFormatId = preferencePageFormatId; + requestedFormatIsSupported = true; + break; + } + } + + if ( ! requestedFormatIsSupported ) { + /* + * Desired format is not supported. If there are any formats supported + * then use the first available. + */ + if ( formatIds.length != 0 ) { + finalFormatId = formatIds[0]; + } + else { + /* + * Register service does not support any format. + */ + handleFailedUpdate(update); + return; + } + } + + /* + * Format has been validated. Get the formatted value. + */ + FormattedValueDMContext valueDmc = regService.getFormattedValue(dmc, finalFormatId); + + regService.getModelData( + valueDmc, + new DataRequestMonitor(getSession().getExecutor(), null) { + @Override + public void handleCompleted() { + if (!getStatus().isOK()) { + handleFailedUpdate(update); + return; + } + + /* + * Fill the label/column with the properly formatted data value. + */ + update.setLabel(getData().getFormattedValue(), labelIndex); + update.done(); + } + } + ); + } + } + ); + } + + /* + * We override the Abstract method because we now need to perform an extra level of data fetch + * to get the formatted value represenatation of the register. Before we obtained the data from + * the IDMData returned for the Register DMC. Now basically the level of information returned + * is attribute information and the formatted value requires a separate transaction. + * + * @see org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMLayoutNode#updateLabelInSessionThread(org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate[]) + */ + @Override + protected void updateLabelInSessionThread(ILabelUpdate[] updates) { + for (final ILabelUpdate update : updates) { + + final IRegisterDMContext dmc = findDmcInPath(update.getElementPath(), IRegisters.IRegisterDMContext.class); + + ((IDMService)getServicesTracker().getService(null, dmc.getServiceFilter())).getModelData( + dmc, + new DataRequestMonitor(getSession().getExecutor(), null) { + @Override + protected void handleCompleted() { + /* + * Check that the request was evaluated and data is still + * valid. The request could fail if the state of the + * service changed during the request, but the view model + * has not been updated yet. + */ + if (!getStatus().isOK() || !getData().isValid()) { + assert getStatus().isOK() || + getStatus().getCode() != IDsfService.INTERNAL_ERROR || + getStatus().getCode() != IDsfService.NOT_SUPPORTED; + handleFailedUpdate(update); + return; + } + + /* + * If columns are configured, extract the selected values for each + * understood column. First we fill all of those columns which can + * be filled without the extra data mining. We also note if we do + * have to datamine. Any columns need to set the processing flag + * so we know we have further work to do. If there are more columns + * which need data extraction they need to be added in both "for" + * loops. + */ + String[] localColumns = update.getPresentationContext().getColumns(); + if (localColumns == null) localColumns = new String[] { null }; + + boolean weAreExtractingFormattedData = false; + + for (int idx = 0; idx < localColumns.length; idx++) { + if (RegisterColumnPresentation.COL_NAME.equals(localColumns[idx])) { + update.setLabel(getData().getName(), idx); + } else if (RegisterColumnPresentation.COL_VALUE.equals(localColumns[idx])) { + weAreExtractingFormattedData = true; + } else if (RegisterColumnPresentation.COL_DESCRIPTION.equals(localColumns[idx])) { + update.setLabel(getData().getDescription(), idx); + } + } + + if ( ! weAreExtractingFormattedData ) { + update.done(); + } else { + for (int idx = 0; idx < localColumns.length; idx++) { + if (RegisterColumnPresentation.COL_VALUE.equals(localColumns[idx])) { + updateFormattedRegisterValue(update, idx, dmc); + } + } + } + } + } + ); + } + } + @Override protected void updateElementsInSessionThread(final IChildrenUpdate update) { final IRegisterGroupDMContext execDmc = findDmcInPath(update.getElementPath(), IRegisterGroupDMContext.class); @@ -58,19 +225,6 @@ public class RegisterLayoutNode extends AbstractDMVMLayoutNode }); } - @Override - protected void fillColumnLabel(IDMContext dmContext, IRegisterDMData dmData, String columnId, - int idx, ILabelUpdate update) - { - if (RegisterColumnPresentation.COL_NAME.equals(columnId)) { - update.setLabel(dmData.getName(), idx); - } else if (RegisterColumnPresentation.COL_VALUE.equals(columnId)) { - update.setLabel(dmData.getHexValue(), idx); - } else if (RegisterColumnPresentation.COL_DESCRIPTION.equals(columnId)) { - update.setLabel(dmData.getDescription(), idx); - } - } - @Override protected int getNodeDeltaFlagsForDMEvent(IDMEvent e) { if (e instanceof IRunControl.ISuspendedDMEvent) { @@ -88,7 +242,7 @@ public class RegisterLayoutNode extends AbstractDMVMLayoutNode parent.addFlags(IModelDelta.CONTENT); } if (e instanceof IRegisters.IRegisterChangedDMEvent) { - parent.addNode( new DMVMContext(((IRegisters.IRegisterChangedDMEvent)e).getDMContext()), IModelDelta.STATE ); + parent.addNode( new DMVMContext(((IRegisterChangedDMEvent)e).getDMContext()), IModelDelta.STATE ); } super.buildDeltaForDMEvent(e, parent, nodeOffset, rm); diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IFormattedValues.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IFormattedValues.java index 80fc136846b..b092e37f43a 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IFormattedValues.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IFormattedValues.java @@ -7,6 +7,7 @@ package org.eclipse.dd.dsf.debug.service; import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; +import org.eclipse.dd.dsf.datamodel.AbstractDMContext; import org.eclipse.dd.dsf.datamodel.IDMContext; import org.eclipse.dd.dsf.datamodel.IDMData; import org.eclipse.dd.dsf.datamodel.IDMService; @@ -14,7 +15,7 @@ import org.eclipse.dd.dsf.datamodel.IDMService; public interface IFormattedValues extends IDMService { /** Marker interface for a DMC that has a formatted value. */ - public interface IDataDMContext extends IDMContext {} + public interface IFormattedDataDMContext extends IDMContext {} /** * These strings represent the standard known formats for any bit stream @@ -27,27 +28,6 @@ public interface IFormattedValues extends IDMService { public final static String BINARY_FORMAT = "BINARY.Format" ; //$NON-NLS-1$ public final static String NATURAL_FORMAT = "NATURAL.Format" ; //$NON-NLS-1$ - /** - * DMC that represents a value with specific format. The format ID can be - * persisted and used for comparison. - */ - public interface IValueDMContext extends IDMContext - { - public String getID(); - } - - /** - * DM Data returned when a formatted value DMC is evaluated. It contains - * only the properly formatted string. - * - * @param includePrefix Should the resulting formatted string contain the - * typical prefix ( if any exists for this format - e.g. 0x, 0b, 0 ). - * @param leadingZeros Should the resulting formatted string contain leading 0's. - */ - public interface IValueDMData extends IDMData { - String getFormattedValue(); - } - /** * Retrieves the available formats that the given data is available in. * This method is asynchronous because the service may need to retrieve @@ -55,9 +35,9 @@ public interface IFormattedValues extends IDMService { * available for the given data context. * * @param dmc Context for which to retrieve available formatted values. - * @param formatIDs Currently supported format IDs. + * @param rm Completion monitor returns an array of support formatIds. */ - public void getAvailableFormattedValues(IDataDMContext dmc, DataRequestMonitor formatIDs); + public void getAvailableFormattedValues(IFormattedDataDMContext dmc, DataRequestMonitor rm); /** * Retrieves the available formats that the given data is available in. @@ -68,5 +48,57 @@ public interface IFormattedValues extends IDMService { * @param dmc Context for which to retrieve a IValueDMContext. * @param formatId Defines format to be supplied from the returned context. */ - public IValueDMContext getFormattedValue(IDataDMContext dmc, String formatId); + public FormattedValueDMContext getFormattedValue(IFormattedDataDMContext dmc, String formatId); + + /** + * DMC that represents a value with specific format. The format ID can be + * persisted and used for comparison. + */ + + public static class FormattedValueDMContext extends AbstractDMContext + { + private final String fFormatID; + + public FormattedValueDMContext(IDMService service, IDMContext parent, String formatId) { + super(service, new IDMContext[] { parent }); + fFormatID = formatId; + } + + public FormattedValueDMContext(String sessionId, String filter, IDMContext parent, String formatId) { + super(sessionId, filter, new IDMContext[] { parent }); + fFormatID = formatId; + } + + public String getFormatID() { + return fFormatID; + } + + @Override + public boolean equals(Object obj) { + return baseEquals(obj) && ((FormattedValueDMContext)obj).getFormatID().equals(getFormatID()); + } + + @Override + public int hashCode() { + return baseHashCode() + getFormatID().hashCode(); + } + } + + public static class FormattedValueDMData implements IDMData { + + private final String fValue; + + public FormattedValueDMData(String value) { + fValue = value; + } + + public String getFormattedValue() { + return fValue; + } + + public boolean isValid() { + return true; + } + + } } \ No newline at end of file diff --git a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IRegisters.java b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IRegisters.java index 7113a38c512..7725b253332 100644 --- a/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IRegisters.java +++ b/plugins/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/IRegisters.java @@ -12,21 +12,19 @@ package org.eclipse.dd.dsf.debug.service; import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; import org.eclipse.dd.dsf.concurrent.RequestMonitor; -import org.eclipse.dd.dsf.datamodel.IDMContext; import org.eclipse.dd.dsf.datamodel.IDMData; import org.eclipse.dd.dsf.datamodel.IDMEvent; -import org.eclipse.dd.dsf.datamodel.IDMService; /** * Service for accessing register data. */ -public interface IRegisters extends IDMService { +public interface IRegisters extends IFormattedValues { /** Event indicating groups have changed. */ public interface IGroupsChangedDMEvent extends IDMEvent {} /** Register group context */ - public interface IRegisterGroupDMContext extends IDMContext {} + public interface IRegisterGroupDMContext extends IFormattedDataDMContext {} /** Event indicating registers in a group have changed. */ public interface IRegistersChangedDMEvent extends IDMEvent {} @@ -41,13 +39,13 @@ public interface IRegisters extends IDMService { } /** Register context */ - public interface IRegisterDMContext extends IDMContext {} + public interface IRegisterDMContext extends IFormattedDataDMContext {} /** Event indicating register value changed. */ public interface IRegisterChangedDMEvent extends IDMEvent {} /** Register information */ - public interface IRegisterDMData extends IDMData, INumericalValue { + public interface IRegisterDMData extends IDMData { String getName(); String getDescription(); boolean isReadable(); @@ -60,7 +58,7 @@ public interface IRegisters extends IDMService { } /** Bit field context */ - public interface IBitFieldDMContext extends IDMContext {} + public interface IBitFieldDMContext extends IFormattedDataDMContext {} /** Event indicating register value changed. */ public interface IBitFieldChangedDMEvent extends IDMEvent {} @@ -69,7 +67,7 @@ public interface IRegisters extends IDMService { * Bitfield data, big groups and mnemonics are retrieved at the same * time as rest of bit field data */ - public interface IBitFieldDMData extends IDMData, INumericalValue { + public interface IBitFieldDMData extends IDMData { String getName(); String getDescription(); boolean isReadable(); @@ -81,6 +79,7 @@ public interface IRegisters extends IDMService { boolean isZeroBitLeftMost(); IBitGroup[] getBitGroup(); IMnemonic[] getMnemonics(); + IMnemonic getCurrentMnemonicValue(); } /** Bit group definition */ @@ -90,22 +89,11 @@ public interface IRegisters extends IDMService { } /** Bit field mnemonic */ - public interface IMnemonic extends INumericalValue { + public interface IMnemonic { String getShortName(); String getLongName(); } - /** - * Common interface for describing a number value for various register - * data objects - */ - public interface INumericalValue { - String getNaturalValue(); - String getHexValue(); - String getOctalValue(); - String getBinaryValue(); - } - /** * Retrieves the list of register groups. * @param execCtx Execution DMC, this is required.