valuemodificationchecker.java

来自「Python Development Environment (Python I」· Java 代码 · 共 132 行

JAVA
132
字号
/*
 * Created on Jun 23, 2006
 * @author Fabio
 */
package org.python.pydev.debug.model;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;

import org.eclipse.debug.core.DebugException;
import org.eclipse.debug.core.model.IStackFrame;
import org.eclipse.debug.core.model.IVariable;
import org.python.pydev.plugin.PydevPlugin;

/**
 * This class should check for value modifications in the stacks while debugging.
 * Its public interface is completely synchronized.
 * 
 * @author Fabio
 */
public class ValueModificationChecker {

    /**
     * compares stack frames to check for modified variables (and mark them as modified in the new stack)
     * 
     * @param newFrame the new frame
     * @param oldFrame the old frame
     */
    private void verifyVariablesModified(IVariable[] newFrameVariables, PyStackFrame oldFrame ) {
        PyVariable newVariable = null;
        
        try {
            Map<String, IVariable> variablesAsMap = oldFrame.getVariablesAsMap();
            
            //we have to check for each new variable
            for( int i=0; i<newFrameVariables.length; i++ ) {
                newVariable = (PyVariable)newFrameVariables[i];
            
                PyVariable oldVariable = (PyVariable)variablesAsMap.get(newVariable.getName());
            
                if( oldVariable != null) {
                    boolean equals = newVariable.getValueString().equals( oldVariable.getValueString() );
                    
                    //if it is not equal, it was modified
                    newVariable.setModified( !equals );
                    
                }else{ //it didn't exist before...
                    newVariable.setModified( true );
                }
            }
            
        } catch (DebugException e) {        
            PydevPlugin.log(e);
        }
    }

    private Map<String,Map<String, PyStackFrame>> cache = new HashMap<String,Map<String, PyStackFrame>>();
    private Object lock = new Object();
    
    /**
     * Synched access to verify the modification
     * @param frame the frame that we're checking
     * @param newFrameVariables the variables that were added to the stack.
     */
    public synchronized void verifyModified(PyStackFrame frame, IVariable[] newFrameVariables) {
        synchronized(lock){
            Map<String, PyStackFrame> threadIdCache = cache.get(frame.getThreadId());
            if(threadIdCache == null){
                threadIdCache = new HashMap<String, PyStackFrame>();
                cache.put(frame.getThreadId(), threadIdCache);
            }
            
            PyStackFrame cacheFrame = threadIdCache.get(frame.getId());
            if(cacheFrame == null){
                threadIdCache.put(frame.getId(), frame);
                return;
            }
            //not null
            if(cacheFrame == frame){ //if is same, it has already been checked.
                return;
            }
            
            //if it is not the same, we have to check it and mark it as the new frame.
            verifyVariablesModified(newFrameVariables, cacheFrame);
            threadIdCache.put(frame.getId(), frame);
        }
    }

    /**
     * Removes from the cache all the threads that are not present in the threads passed.
     */
    public synchronized void onlyLeaveThreads(PyThread[] threads) {
        synchronized(lock){
            HashSet<String> ids = new HashSet<String>();
            for (PyThread thread : threads) {
                ids.add(thread.getId());
            }
            for(String id: cache.keySet()){
                if(!ids.contains(id)){
                    cache.remove(id);
                }
            }
        }
    }

    /**
     * Removes from the cache all the stacks that are not present in the new stack frame passed (those 
     * are already outdated).
     */
    public synchronized void onlyLeaveStack(PyThread t, IStackFrame[] stackFrame) {
        synchronized(lock){
            Map<String, PyStackFrame> threadIdCache = this.cache.get(t);
            if(threadIdCache == null){
                return;
            }
            HashSet<String> ids = new HashSet<String>();
            
            for (int i = 0; i < stackFrame.length; i++) {
                ids.add(((PyStackFrame)stackFrame[i]).getId());
            }
            
            for(String id: threadIdCache.keySet()){
                if(!ids.contains(id)){
                    threadIdCache.remove(id);
                }
            }
            
        }
    }
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?