/*
* #%~
* 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;
import java.util.List;
import java.util.Vector;
import org.eclipse.core.runtime.Assert;
/**
* State controller for IDebugTarget and IThreads
*
* @author kela
*/
public class VdmDebugState
{
private List<DebugState> states = new Vector<DebugState>();
/**
* Legal states
*
* @author kela
*/
public enum DebugState
{
Terminated, Suspended, Disconnected, IsStepping, Resumed, Deadlocked
};
public VdmDebugState(DebugState initialState)
{
if (initialState != null)
{
this.states.add(initialState);
}
}
/**
* Sets a new state, an Assert.IsLegal is asserted if the given state is not valid based on the current state
*
* @param newState
* the new state to change into
*/
public synchronized void setState(DebugState newState)
{
if (!states.contains(newState))
{
switch (newState)
{
case Disconnected:
Assert.isLegal(canChange(DebugState.Disconnected), "Cannot disconnect a terminated state");
case Terminated:
Assert.isLegal(canChange(DebugState.Terminated), "Cannot terminate a terminated state");
states.clear();
states.add(newState);
break;
case Suspended:
Assert.isLegal(canChange(DebugState.Suspended), "Can only suspend if resumed");
states.remove(DebugState.Resumed);
states.add(newState);
break;
case IsStepping:
Assert.isLegal(canChange(DebugState.IsStepping), "Cannot step if not suspended");
states.add(newState);
break;
case Resumed:
Assert.isLegal(canChange(DebugState.Resumed), "Cannot resume in a terminated state");
if (states.contains(DebugState.IsStepping))
{
states.clear();
states.add(DebugState.IsStepping);
} else
{
states.clear();
}
states.add(newState);
break;
case Deadlocked:
states.add(newState);
break;
}
}
}
/**
* Checks the current state
*
* @param state
* the state to check for
* @return true if in the requested state else false
*/
public synchronized boolean inState(DebugState state)
{
return states.contains(state);
}
/**
* Checks if a change to the newState is allowed
*
* @param newState
* the new state requested
* @return true if allowed else false
*/
public synchronized boolean canChange(DebugState newState)
{
switch (newState)
{
case Disconnected:
return !inState(DebugState.Terminated)
&& !inState(DebugState.Disconnected);
case Terminated:
return !inState(DebugState.Terminated);
case Suspended:
return inState(DebugState.Resumed);// states.size()==1 &&
case IsStepping:
return (!inState(DebugState.Terminated)
|| !inState(DebugState.Disconnected) || !inState(DebugState.Deadlocked))
&& inState(DebugState.Suspended);
case Resumed:
return states.size() == 0 || inState(DebugState.IsStepping)
|| inState(DebugState.Suspended);
default:
return false;
}
}
@Override
public String toString()
{
StringBuffer string = new StringBuffer();
for (DebugState s : states)
{
string.append(s);
string.append(" ");
}
return string.toString();
}
}