namespace Implab.Diagnostics { struct OperationContext { readonly LogicalOperation m_initial; public readonly static OperationContext EMPTY = new OperationContext(LogicalOperation.EMPTY, false); LogicalOperation m_current; readonly bool m_ownership; public OperationContext(LogicalOperation operation, bool ownership) { Safe.ArgumentNotNull(operation, "operation"); m_initial = operation; m_current = operation; m_ownership = ownership; } public LogicalOperation CurrentOperation { get { return m_current; } } public void BeginLogicalOperation(string name) { m_current = new LogicalOperation(name, m_current); } public LogicalOperation DetachLogicalOperation() { var detached = m_current; if (m_current != LogicalOperation.EMPTY) { if (m_current != m_initial) m_current = m_current.Parent; else if (m_ownership) m_current = LogicalOperation.EMPTY; else { TraceLog.TraceWarning("DetachLogicalOperation can't be applied in the current context"); detached = LogicalOperation.EMPTY; } } else { TraceLog.TraceWarning("DetachLogicalOperation can't be applied in the current context"); } return detached; } public void EndLogicalOperation() { if (m_current != m_initial) { m_current = m_current.Parent; } else if (m_current != LogicalOperation.EMPTY && m_ownership) { m_current = LogicalOperation.EMPTY; } else { TraceLog.TraceWarning("EndLogicalOperation can't be applied in the current context"); } } public void Leave() { if ((m_ownership && m_current != LogicalOperation.EMPTY) || (!m_ownership && m_current != m_initial) ) TraceLog.TraceWarning("Trying to leave unfinished logical operation {0}", m_current.Name); } } }