Eclipse CDT 扩展 AdapterFactory
Eclipse CDT extend AdapterFactory
我尝试覆盖 CDT ResumeAtLine、MoveToLine、RunToLine 的功能。出于这个原因,我创建了一个自定义的 SuspendResumeAdapterFactory 但它没有加载但编译和运行没有错误。我可能也需要自定义 adaptableType 吗?
这是我的plugin.xml
的内容。
<extension point="org.eclipse.core.runtime.adapters">
<factory
class="my.package.CustomSuspendResumeAdapterFactory"
adaptableType="org.eclipse.cdt.dsf.ui.viewmodel.IVMContext">
<adapter type="org.eclipse.debug.core.model.ISuspendResume"/>
</factory>
</extension>
而这里我的CustomSuspendResumeAdapterFactory
这个class是从内存中重建的,不能100%确定语法是否正确,但我想应该很清楚我想做什么。
package my.package;
import org.eclipse.cdt.dsf.datamodel.DMContexts;
import org.eclipse.cdt.dsf.debug.internal.ui.actions.MoveToLine;
import org.eclipse.cdt.dsf.debug.internal.ui.actions.ResumeAtLine;
import org.eclipse.cdt.dsf.debug.internal.ui.actions.RunToLine;
import org.eclipse.cdt.dsf.debug.service.IRunControl.IContainerDMContext;
import org.eclipse.cdt.dsf.debug.service.IRunControl.IExecutionDMContext;
import org.eclipse.cdt.dsf.ui.viewmodel.datamodel.IDMVMContext;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IAdapterFactory;
import org.eclipse.debug.core.DebugException;
import org.eclipse.debug.core.model.ISuspendResume;
public class CustomSuspendResumeAdapterFactory implements IAdapterFactory {
static class SuspendResume implements ISuspendResume, IAdaptable {
private final CustomRunToLine fRunToLine;
private final CustomMoveToLine fMoveToLine;
private final CustomResumeAtLine fResumeAtLine;
SuspendResume(IExecutionDMContext execCtx) {
fRunToLine = new CustomRunToLine(execCtx);
fMoveToLine = new CustomMoveToLine(execCtx);
fResumeAtLine = new CustomResumeAtLine(execCtx);
}
@SuppressWarnings("unchecked")
@Override
public <T> T getAdapter(Class<T> adapter) {
if (adapter.isInstance(RunToLine.class)) {
System.out.println("CUSTOM RUNTOLINE");
return (T)fRunToLine;
}
if (adapter.isInstance(MoveToLine.class)) {
System.out.println("CUSTOM MOVETOLINE");
return (T)fMoveToLine;
}
if (adapter.isInstance(ResumeToLine.class)) {
System.out.println("CUSTOM RESUMEATLINE");
return (T)fResumeAtLine;
}
return null;
}
@Override
public boolean canResume() { return false; }
@Override
public boolean canSuspend() { return false; }
// This must return true because the platform
// RunToLineActionDelegate will only enable the
// action if we are suspended
@Override
public boolean isSuspended() { return true; }
@Override
public void resume() throws DebugException {}
@Override
public void suspend() throws DebugException {}
}
@SuppressWarnings("unchecked")
@Override
public <T> T getAdapter(Object adaptableObject, Class<T> adapterType) {
if (ISuspendResume.class.equals(adapterType)) {
if (adaptableObject instanceof IDMVMContext) {
IExecutionDMContext execDmc = DMContexts.getAncestorOfType(
((IDMVMContext)adaptableObject).getDMContext(),
IExecutionDMContext.class);
// It only makes sense to RunToLine, MoveToLine or
// ResumeAtLine if we are dealing with a thread, not a container
if (execDmc != null && !(execDmc instanceof IContainerDMContext)) {
return (T)new SuspendResume(execDmc);
}
}
}
return null;
}
@Override
public Class<?>[] getAdapterList() {
return new Class[] { ISuspendResume.class };
}
}
为什么你的代码不是运行
您提供了一个新的适配器工厂,可以转换已处理的对象类型。即你的 plugin.xml 说你可以将 IVMContext
转换为 ISuspendResume
。但是 DSF 插件已经提供了这样一个适配器工厂。如果您有一个新的目标类型(如 IMySpecialRunToLine),您可以为此安装一个工厂,它需要 IVMContext
并将其转换为 IMySpecialRunToLine
)。
虽然过时了,但如果这是一个新概念,Eclipse Corner Article on Adapter Pattern 可能会有用。
如何自定义运行行实现
如果您想提供运行行的不同实现,您需要提供您自己的org.eclipse.cdt.dsf.debug.service.IRunControl2.runToLine(IExecutionDMContext, String, int, boolean, RequestMonitor)
版本。 org.eclipse.cdt.dsf.debug.internal.ui.actions.RunToLine
class 只是将 UI 特性(例如 buttons/etc 一些直接提供,一些由核心 eclipse 调试)连接到 DSF 后端的胶水。也就是说,如果您查看 RunToLine
的作用,它实际上所做的就是获取 IRunControl2
服务并在其上调用 runToLine
。
提供您自己的 IRunControl2
实现的方法是覆盖 org.eclipse.cdt.dsf.gdb.service.GdbDebugServicesFactory.createRunControlService(DsfSession)
并通过覆盖 org.eclipse.cdt.dsf.gdb.launching.GdbLaunchDelegate.newServiceFactory(ILaunchConfiguration, String)
[=26= 在自定义启动委托中提供您自己的 GdbDebugServicesFactory
]
RunToLine
将在用户从编辑器的弹出菜单中 select 运行 行 时触发,如以下屏幕截图所示:
我尝试覆盖 CDT ResumeAtLine、MoveToLine、RunToLine 的功能。出于这个原因,我创建了一个自定义的 SuspendResumeAdapterFactory 但它没有加载但编译和运行没有错误。我可能也需要自定义 adaptableType 吗?
这是我的plugin.xml
的内容。
<extension point="org.eclipse.core.runtime.adapters">
<factory
class="my.package.CustomSuspendResumeAdapterFactory"
adaptableType="org.eclipse.cdt.dsf.ui.viewmodel.IVMContext">
<adapter type="org.eclipse.debug.core.model.ISuspendResume"/>
</factory>
</extension>
而这里我的CustomSuspendResumeAdapterFactory
这个class是从内存中重建的,不能100%确定语法是否正确,但我想应该很清楚我想做什么。
package my.package;
import org.eclipse.cdt.dsf.datamodel.DMContexts;
import org.eclipse.cdt.dsf.debug.internal.ui.actions.MoveToLine;
import org.eclipse.cdt.dsf.debug.internal.ui.actions.ResumeAtLine;
import org.eclipse.cdt.dsf.debug.internal.ui.actions.RunToLine;
import org.eclipse.cdt.dsf.debug.service.IRunControl.IContainerDMContext;
import org.eclipse.cdt.dsf.debug.service.IRunControl.IExecutionDMContext;
import org.eclipse.cdt.dsf.ui.viewmodel.datamodel.IDMVMContext;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IAdapterFactory;
import org.eclipse.debug.core.DebugException;
import org.eclipse.debug.core.model.ISuspendResume;
public class CustomSuspendResumeAdapterFactory implements IAdapterFactory {
static class SuspendResume implements ISuspendResume, IAdaptable {
private final CustomRunToLine fRunToLine;
private final CustomMoveToLine fMoveToLine;
private final CustomResumeAtLine fResumeAtLine;
SuspendResume(IExecutionDMContext execCtx) {
fRunToLine = new CustomRunToLine(execCtx);
fMoveToLine = new CustomMoveToLine(execCtx);
fResumeAtLine = new CustomResumeAtLine(execCtx);
}
@SuppressWarnings("unchecked")
@Override
public <T> T getAdapter(Class<T> adapter) {
if (adapter.isInstance(RunToLine.class)) {
System.out.println("CUSTOM RUNTOLINE");
return (T)fRunToLine;
}
if (adapter.isInstance(MoveToLine.class)) {
System.out.println("CUSTOM MOVETOLINE");
return (T)fMoveToLine;
}
if (adapter.isInstance(ResumeToLine.class)) {
System.out.println("CUSTOM RESUMEATLINE");
return (T)fResumeAtLine;
}
return null;
}
@Override
public boolean canResume() { return false; }
@Override
public boolean canSuspend() { return false; }
// This must return true because the platform
// RunToLineActionDelegate will only enable the
// action if we are suspended
@Override
public boolean isSuspended() { return true; }
@Override
public void resume() throws DebugException {}
@Override
public void suspend() throws DebugException {}
}
@SuppressWarnings("unchecked")
@Override
public <T> T getAdapter(Object adaptableObject, Class<T> adapterType) {
if (ISuspendResume.class.equals(adapterType)) {
if (adaptableObject instanceof IDMVMContext) {
IExecutionDMContext execDmc = DMContexts.getAncestorOfType(
((IDMVMContext)adaptableObject).getDMContext(),
IExecutionDMContext.class);
// It only makes sense to RunToLine, MoveToLine or
// ResumeAtLine if we are dealing with a thread, not a container
if (execDmc != null && !(execDmc instanceof IContainerDMContext)) {
return (T)new SuspendResume(execDmc);
}
}
}
return null;
}
@Override
public Class<?>[] getAdapterList() {
return new Class[] { ISuspendResume.class };
}
}
为什么你的代码不是运行
您提供了一个新的适配器工厂,可以转换已处理的对象类型。即你的 plugin.xml 说你可以将 IVMContext
转换为 ISuspendResume
。但是 DSF 插件已经提供了这样一个适配器工厂。如果您有一个新的目标类型(如 IMySpecialRunToLine),您可以为此安装一个工厂,它需要 IVMContext
并将其转换为 IMySpecialRunToLine
)。
虽然过时了,但如果这是一个新概念,Eclipse Corner Article on Adapter Pattern 可能会有用。
如何自定义运行行实现
如果您想提供运行行的不同实现,您需要提供您自己的org.eclipse.cdt.dsf.debug.service.IRunControl2.runToLine(IExecutionDMContext, String, int, boolean, RequestMonitor)
版本。 org.eclipse.cdt.dsf.debug.internal.ui.actions.RunToLine
class 只是将 UI 特性(例如 buttons/etc 一些直接提供,一些由核心 eclipse 调试)连接到 DSF 后端的胶水。也就是说,如果您查看 RunToLine
的作用,它实际上所做的就是获取 IRunControl2
服务并在其上调用 runToLine
。
提供您自己的 IRunControl2
实现的方法是覆盖 org.eclipse.cdt.dsf.gdb.service.GdbDebugServicesFactory.createRunControlService(DsfSession)
并通过覆盖 org.eclipse.cdt.dsf.gdb.launching.GdbLaunchDelegate.newServiceFactory(ILaunchConfiguration, String)
[=26= 在自定义启动委托中提供您自己的 GdbDebugServicesFactory
]
RunToLine
将在用户从编辑器的弹出菜单中 select 运行 行 时触发,如以下屏幕截图所示: