Eclipse CDT扩展了AdapterFactory

时间:2015-12-09 09:55:45

标签: eclipse eclipse-plugin eclipse-cdt

我尝试覆盖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这个类是从内存重建而不是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 };
    }
}

1 个答案:

答案 0 :(得分:1)

为什么你的代码没有运行

您提供了一个新的适配器工厂,用于转换已处理的对象类型。即你的plugin.xml表示你可以将IVMContext转换为ISuspendResume。但是DSF插件已经提供了这样的适配器工厂。如果您有一个新的目标类型(如IMySpecialRunToLine),您可以为此安装工厂,它将需要IVMContext并将其转换为IMySpecialRunToLine)。

虽然注明日期,但如果这是一个新概念,Eclipse Corner Article on Adapter Pattern可能会有用。

如何进行自定义“运行到行”实施

如果您想提供 Run To Line 的不同实现,则需要提供自己的org.eclipse.cdt.dsf.debug.service.IRunControl2.runToLine(IExecutionDMContext, String, int, boolean, RequestMonitor)版本。 org.eclipse.cdt.dsf.debug.internal.ui.actions.RunToLine类只是将UI功能(例如一些直接提供的按钮/等,有些是通过核心eclipse调试)连接到DSF后端的粘合剂。也就是说,如果你看看RunToLine做了什么,它实际做的就是获得IRunControl2服务并在其上调用runToLine

提供您自己的IRunControl2实施方式的方法是覆盖org.eclipse.cdt.dsf.gdb.service.GdbDebugServicesFactory.createRunControlService(DsfSession)并通过覆盖GdbDebugServicesFactory

在您的自定义启动委托中提供您自己的org.eclipse.cdt.dsf.gdb.launching.GdbLaunchDelegate.newServiceFactory(ILaunchConfiguration, String) 当用户从编辑器的弹出菜单中选择 Run To Line 时,将触发

RunToLine,如此屏幕截图所示:

runtoline