CDT之扩展Debug视图
IModelProxy是何时被创建的
Launch是最顶端的调试模型,一个new Launch会被添加到launchManager,launchManager是Debug视图的input对象
public class LaunchConfiguration {
public ILaunch launch() { // 启动Launch时由Eclipse平台调用
launch = delegate2.getLaunch(this, mode); // 从delegate对象拿到launch实例
getLaunchManager().addLaunch(launch); // 把Launch实例添加到Manager,这会触发事件
}
}
当一个launch对象被add到launchManager中时,launchManager会通知所有对该add事件感兴趣的对象,其中包含launchManager的LaunchManagerProxy对象
public class LaunchManager {
public void addLaunch(ILaunch launch) {
fireUpdate(new ILaunch[] {launch}, ADDED); // 此处会通知到LaunchManagerProxy
}
public void notify(ILaunch[] launches, int update) {
// 循环异步通知每一个LaunchListener,此处会通知到LaunchManagerProxy
for (ILaunchesListener iLaunchesListener : fLaunchesListeners) {
fListener = iLaunchesListener;
SafeRunner.run(this);
}
}
}
LaunchManagerProxy会为该add事件创建一个ModelDelta对象,ModelDelta描述了相关model的增量变化内容(此处为新增一个node,并且标记为ADDED和INSTALL),LaunchManagerProxy会将ModelDelta通知出去
public class LaunchManagerProxy {
public void launchesAdded(ILaunch[] launches) {
//将Launch这个模型被添加的信息发布出去
fireDelta(launches, IModelDelta.ADDED | IModelDelta.INSTALL);
}
// fLaunchManager是Debug视图的最顶层model
protected void fireDelta(ILaunch[] launches, int launchFlags) {
ModelDelta delta = new ModelDelta(fLaunchManager, IModelDelta.NO_CHANGE);
for (int i = 0; i < launches.length; i++) {
//新启动的Launch就是fLaunchManager的一个子节点
delta.addNode(launches[i], launchFlags);
}
fireModelChanged(delta); // 只发布模型的增量部分事件
}
public void fireModelChanged(IModelDelta delta) {
final IModelDelta root = getRootDelta(delta);
// 会通知到对Launch模型改变感兴趣的TreeModelContentProvider
for (IModelChangedListener iModelChangedListener : getListeners()) {
final IModelChangedListener listener = iModelChangedListener;
ISafeRunnable safeRunnable = new ISafeRunnable() {
@Override
public void handleException(Throwable exception) {
DebugUIPlugin.log(exception);
}
@Override
public void run() throws Exception {
// 会通知到对LaunchManager模型改变感兴趣的TreeModelContentProvider,
// 并且说明是哪个modelProxy生成delta
listener.modelChanged(root, AbstractModelProxy.this);
}
};
SafeRunner.run(safeRunnable);
}
}
}
注:上述ModelDelta的描述
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiIwczX0xiRGZkRGZ0Xy9GbvNGL2EzXlpXazxSP9cWY2ETbhZTMtFmNx0WY2EjMMBjVtJWd0ckW65UbM5WOHJWa5kHT20ESjBjUIF2X0hXZ0xCMx81dvRWYoNHLrdEZwZ1Rh5WNXp1bwNjW1ZUba9VZwlHdssmch1mclRXY39CXldWYtlWPzNXZj9mcw1ycz9WL49zZuBnL3kDN2IjNwkTMwMjNwAjMwIzLc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
debug视图中的TreeModelContentProvider对象得知ModelDelta后,会对LaunchManager的改变做出处理,对子node的ADDED标志和INSTALL标志做出不同的处理。
ADDED:表示该模型被添加,此时会调用ElementContentProvider中的update
INSTALL:此时会生成Launch的modelProxy对象,然后Debug视图把自己注册到modelProxy中的监听列表中,然后调用proxy的initialize()(或init()和installed()方法),在installed是就可以自由的向viewer注册感兴趣的事件,比如该model节点对双击感兴趣,那么就可以在installed里加上。
一个Launch对应一个ModelProxy,ModelProxy主要用来代替Model处理事件、维护对该Model感兴趣的监听器,以及生成合适的delta
public class TreeModelContentProvider {
protected void updateNodes(IModelDelta[] nodes, int mask) {
for (int i = 0; i < nodes.length; i++) {
IModelDelta node = nodes[i];
int flags = node.getFlags() & mask;
if (flags != 0) {
if ((flags & IModelDelta.ADDED) != 0) {
handleAdd(node);
}
if ((flags & IModelDelta.REMOVED) != 0) {
handleRemove(node);
}
// 触发新模型也就是新建的Launch模型的安装
if ((flags & IModelDelta.INSTALL) != 0) {
handleInstall(node);
}
}
}
}
private void installModelProxy(Object input, TreePath path) {
//TreeModelContentProvider的根input是fLaunchManager
//从Launch模型关联的AdapterFactory中拿到IModelProxyFactory实例
IModelProxyFactory modelProxyFactory = ViewerAdapterService.getModelProxyFactory(element);
if (modelProxyFactory != null) {
proxy = modelProxyFactory.createModelProxy(element, getPresentationContext());
if (proxy != null) {
fModelProxies.put(element, proxy);
}
}
//debug视图的TreeModelContentProvider会把自己添加到launch的modelProxy中
proxy.addModelChangedListener(this);
//modelProxy初始化在这里
((IModelProxy2)proxy).initialize(getViewer());
}
}