/*
* #%~
* org.overture.ide.debug
* %%
* Copyright (C) 2008 - 2014 Overture
* %%
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this program. If not, see
* <http://www.gnu.org/licenses/gpl-3.0.html>.
* #~%
*/
package org.overture.ide.debug.core.model.internal;
import org.overture.ide.debug.core.VdmDebugPlugin;
import org.overture.ide.debug.core.dbgp.IDbgpStackLevel;
import org.overture.ide.debug.core.dbgp.exceptions.DbgpException;
import org.overture.ide.debug.core.model.DebugEventHelper;
import org.overture.ide.debug.core.model.IVdmStack;
import org.overture.ide.debug.core.model.IVdmStackFrame;
import org.overture.ide.debug.logging.LogItem;
public class VdmStack implements IVdmStack
{
public static final IVdmStackFrame[] NO_STACK_FRAMES = new IVdmStackFrame[0];
private IVdmStackFrame[] frames;
private final Object framesLock = new Object();
private final VdmThread thread;
public VdmStack(VdmThread thread)
{
this.thread = thread;
this.frames = NO_STACK_FRAMES;
}
public void update(boolean logErrors)
{
try
{
readFrames();
// updateFrames();
} catch (DbgpException e)
{
if (logErrors)
{
VdmDebugPlugin.log(e);
}
}
}
protected IDbgpStackLevel[] requrestStackLevels() throws DbgpException
{
return thread.getDbgpSession().getCoreCommands().getStackLevels();
}
protected void readFrames() throws DbgpException
{
thread.getVdmDebugTarget().printLog(new LogItem(((VdmThread) thread).getDbgpSession().getInfo(), "REQUEST", true, "Stack Levels"));
final IDbgpStackLevel[] levels = requrestStackLevels();
thread.getVdmDebugTarget().printLog(new LogItem(((VdmThread) thread).getDbgpSession().getInfo(), "RESPONSE", false, "Stack Levels"));
synchronized (framesLock)
{
final int newSize = levels.length;
final int oldSize = frames.length;
final int numToRebind = Math.min(newSize, oldSize);
final VdmStackFrame[] newFrames = new VdmStackFrame[newSize];
for (int depth = 0; depth < numToRebind; ++depth)
{
final VdmStackFrame oldFrame = (VdmStackFrame) frames[oldSize
- depth - 1];
newFrames[newSize - depth - 1] = oldFrame.bind(levels[newSize
- depth - 1]);
}
final int newCount = newSize - oldSize;
for (int i = 0; i < newCount; ++i)
{
newFrames[i] = new VdmStackFrame(this, levels[i]);
}
frames = newFrames;
DebugEventHelper.fireChangeEvent(getThread());// todo FOLLOWUP added for debug view
}
}
public VdmThread getThread()
{
return thread;
}
public int size()
{
synchronized (framesLock)
{
return frames.length;
}
}
public boolean hasFrames()
{
synchronized (framesLock)
{
return frames.length > 0;
}
}
public IVdmStackFrame[] getFrames()
{
synchronized (framesLock)
{
return frames;
}
}
public IVdmStackFrame getTopFrame()
{
synchronized (framesLock)
{
return frames.length > 0 ? frames[0] : null;
}
}
public void updateFrames()
{
synchronized (framesLock)
{
for (int i = 0; i < frames.length; i++)
{
((VdmStackFrame) frames[i]).updateVariables();
}
}
}
/**
* @return
*/
public boolean isInitialized()
{
synchronized (framesLock)
{
return frames != NO_STACK_FRAMES;
}
}
}