CDT之DSF-GDB分析
GdbAdapterFactory
是Launch对象的适配器工厂,他主要使用GdbSessionAdapters来创建所有和Launch有关的适配器
public class GdbAdapterFactory {
public <T> T getAdapter(Object adaptableObject, Class<T> adapterType) {
GdbSessionAdapters adapterSet = createGdbSessionAdapters(launch, session);
fgLaunchAdapterSets.put(launch, adapterSet);
return adapterSet.getLaunchAdapter(adapterType);
}
protected GdbSessionAdapters createGdbSessionAdapters(ILaunch launch, DsfSession session) {
return new GdbSessionAdapters(launch, session, getAdapterList());
}
}
//用来创建和保存适配器实例
public class GdbSessionAdapters {
private final Map<Class<?>, Object> fLaunchAdapters = new HashMap<>(); // 保存plugin.xml中定义的与Launch关联的几个适配器
private final Class<?>[] fLaunchAdapterTypes;
public GdbSessionAdapters(ILaunch launch, DsfSession session, Class<?>[] launchAdapterTypes) {
fLaunch = launch;
fSession = session;
fLaunchAdapterTypes = launchAdapterTypes;
createAdapters(); //创建所有的适配器
}
protected void createAdapters() {
for (Class<?> adapterType : getModelAdapters()) {//创建所有的适配器并且关联到session中
Object adapter = createModelAdapter(adapterType, getLaunch(), getSession());
getSession().registerModelAdapter(adapterType, adapter);
}
for (Class<?> adapterType : fLaunchAdapterTypes) {//创建与Launch关联的适配器
Object adapter = createLaunchAdapter(adapterType, getLaunch(), getSession());
fLaunchAdapters.put(adapterType, adapter);
}
}
protected <T> T createModelAdapter(Class<T> adapterType, ILaunch launch, DsfSession session) {
if (IViewerInputProvider.class.equals(adapterType)) {
//注意此处,GdbViewModelAdapter实现了跟UI相关的所有接口,和UI相关的适配器都会返回这个实例
return (T) new GdbViewModelAdapter(session, getSteppingController());
}
// ... ... ...
if (IDebugModelProvider.class.equals(adapterType)) {
return (T) new IDebugModelProvider() {
@Override
public String[] getModelIdentifiers() {
//在这里添加自己的model id
return new String[] { GdbLaunchDelegate.GDB_DEBUG_MODEL_ID,
ICBreakpoint.C_BREAKPOINTS_DEBUG_MODEL_ID, "org.eclipse.cdt.gdb" //$NON-NLS-1$
};
}
};
}
return null;
}
protected <T> T createLaunchAdapter(Class<T> adapterType, ILaunch launch, DsfSession session) {
if (adapterType.equals(IElementContentProvider.class) || adapterType.equals(IModelProxyFactory.class)
|| adapterType.equals(IColumnPresentationFactory.class)) {
return (T) getViewModelAdapter(); //和UI相关的适配器就是IViewerInputProvider的适配器,他们是同一个
}
if (adapterType.equals(ISuspendTrigger.class)) {
return (T) new GdbSuspendTrigger(session, launch);
}
return null;
}
}
GdbViewModelAdapter
IVMAdapter
他的主要作用就是管理IVMProvider,通过IPresentationContext的id把逻辑处理转给对应的IVMProvider
public interface IVMAdapter
extends IElementContentProvider,
IModelProxyFactory,
IColumnPresentationFactory,
IViewerInputProvider {
/**
* Returns the View Model Provider that is registered for the given presentation
* context. Returns <code>null</code> if there is none.
*/
// 根据presentationContext中的view id,返回对应的IVMProvider,如果没有的话则创建
public IVMProvider getVMProvider(IPresentationContext presentationContext);
/**
* Retrieves the currently active VM providers in this adapter.
* @return array of VM providers
*/
public IVMProvider[] getActiveProviders();
}
public class GdbViewModelAdapter extends AbstractDebugVMAdapter {
//根据presentationContext中的view id,创建IVMProvider
protected IVMProvider createViewModelProvider(IPresentationContext context) {
if (IDebugUIConstants.ID_DEBUG_VIEW.equals(context.getId())) {
return new LaunchVMProvider(this, context, getSession());
}
// ... ... ...
else if (IDebugUIConstants.ID_REGISTER_VIEW.equals(context.getId())) {
return new RegisterVMProvider(this, context, getSession());
}
return null;
}
}
IVMProvider
与IVMAdapter的继承结构相似,IVMAdapter虽然继承了与视图相关的4个接口,但他不会直接处理或提供与视图相关的功能数据,而是再实例化一个或多个IVMProvider对象(目测一个view对应一个IVMProvider),IVMAdapter会调用IVMProvider对应的方法来提供视图相关的功能数据。例如:
IVMAdapter:createModelProxy()->IVMProvider:createModelProxy()
abstract public class AbstractVMAdapter implements IVMAdapter {
// ...
@Override
public IModelProxy createModelProxy(Object element, IPresentationContext context) {
IVMProvider provider = getVMProvider(context); //拿到对应view的provider
if (provider != null) {
return provider.createModelProxy(element, context);//看此处
}
return null;
}
// ...
}
DefaultVMContentProviderStrategy, DefaultVMModelProxyStrategy
继承了IElementContentProvider接口,AbstractVMProvider也不会直接提供对应的功能数据,而是通过createContentStrategy()方法创建一个IElementContentProvider对象,然后在对应的update()方法中调用后者中的update()方法。大致如下:
IVMAdapter.update()->IVMProvider.update()->DefaultVMModelProxyStrategy.update()