| /****************************************************************************  | 
| **  | 
| ** Copyright (C) 2018 The Qt Company Ltd.  | 
| ** Contact: https://www.qt.io/licensing/  | 
| **  | 
| ** This file is part of the Qt VS Tools.  | 
| **  | 
| ** $QT_BEGIN_LICENSE:GPL-EXCEPT$  | 
| ** Commercial License Usage  | 
| ** Licensees holding valid commercial Qt licenses may use this file in  | 
| ** accordance with the commercial license agreement provided with the  | 
| ** Software or, alternatively, in accordance with the terms contained in  | 
| ** a written agreement between you and The Qt Company. For licensing terms  | 
| ** and conditions see https://www.qt.io/terms-conditions. For further  | 
| ** information use the contact form at https://www.qt.io/contact-us.  | 
| **  | 
| ** GNU General Public License Usage  | 
| ** Alternatively, this file may be used under the terms of the GNU  | 
| ** General Public License version 3 as published by the Free Software  | 
| ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT  | 
| ** included in the packaging of this file. Please review the following  | 
| ** information to ensure the GNU General Public License requirements will  | 
| ** be met: https://www.gnu.org/licenses/gpl-3.0.html.  | 
| **  | 
| ** $QT_END_LICENSE$  | 
| **  | 
| ****************************************************************************/  | 
|   | 
| using Microsoft.VisualStudio;  | 
| using Microsoft.VisualStudio.Debugger.Interop;  | 
| using System;  | 
|   | 
| namespace QtVsTools.Qml.Debug.AD7  | 
| {  | 
|     abstract class DebugEvent :  | 
|   | 
|         IDebugEvent2 // "This interface is used to communicate both critical debug information,  | 
|                      //  such as stopping at a breakpoint, and non-critical information, such as a  | 
|                      //  debugging message."  | 
|     {  | 
|         public Guid InterfaceId { get; protected set; }  | 
|         public uint Attributes { get; protected set; }  | 
|   | 
|         protected const uint ASYNCHRONOUS = (uint)enum_EVENTATTRIBUTES.EVENT_ASYNCHRONOUS;  | 
|         protected const uint STOPPING = (uint)enum_EVENTATTRIBUTES.EVENT_ASYNC_STOP;  | 
|         protected const uint SYNCHRONOUS = (uint)enum_EVENTATTRIBUTES.EVENT_SYNCHRONOUS;  | 
|         protected const uint SYNCHRONOUS_STOPPING =  | 
|               (uint)enum_EVENTATTRIBUTES.EVENT_STOPPING  | 
|             | (uint)enum_EVENTATTRIBUTES.EVENT_SYNCHRONOUS;  | 
|   | 
|         protected QmlEngine Engine { get; set; }  | 
|         protected IDebugProgram2 Program { get; set; }  | 
|         protected IDebugThread2 Thread { get; set; }  | 
|         protected IDebugEventCallback2 Callback { get; set; }  | 
|   | 
|         protected DebugEvent(  | 
|             QmlEngine engine,  | 
|             Guid interfaceId,  | 
|             uint attributes,  | 
|             IDebugProgram2 program = null,  | 
|             IDebugThread2 thread = null,  | 
|             IDebugEventCallback2 callback = null)  | 
|         {  | 
|             InterfaceId = interfaceId;  | 
|             Attributes = attributes;  | 
|             Engine = engine;  | 
|             Program = program;  | 
|             Thread = thread;  | 
|             Callback = (callback != null) ? callback : engine;  | 
|         }  | 
|   | 
|         protected void Send()  | 
|         {  | 
|             if (Callback != null) {  | 
|                 var interfaceId = InterfaceId;  | 
|                 Callback.Event(  | 
|                     Engine, null, Program, Thread,  | 
|                     this, ref interfaceId, Attributes);  | 
|             }  | 
|         }  | 
|   | 
|         public int /*IDebugEvent2*/ GetAttributes(out uint eventAttributes)  | 
|         {  | 
|             eventAttributes = Attributes;  | 
|             return VSConstants.S_OK;  | 
|         }  | 
|   | 
|         public static void Send(DebugEvent debugEvent)  | 
|         {  | 
|             debugEvent.Send();  | 
|         }  | 
|     }  | 
|   | 
|     class EngineCreateEvent : DebugEvent, IDebugEngineCreateEvent2  | 
|     {  | 
|         public EngineCreateEvent(QmlEngine engine)  | 
|         : base(engine, typeof(IDebugEngineCreateEvent2).GUID, ASYNCHRONOUS)  | 
|         { }  | 
|   | 
|         int IDebugEngineCreateEvent2.GetEngine(out IDebugEngine2 pEngine)  | 
|         {  | 
|             pEngine = Engine as IDebugEngine2;  | 
|             return VSConstants.S_OK;  | 
|         }  | 
|     }  | 
|   | 
|     class ProgramCreateEvent : DebugEvent, IDebugProgramCreateEvent2  | 
|     {  | 
|         public ProgramCreateEvent(Program program)  | 
|         : base(program.Engine, typeof(IDebugProgramCreateEvent2).GUID,  | 
|               ASYNCHRONOUS, program)  | 
|         { }  | 
|     }  | 
|   | 
|     class ProgramDestroyEvent : DebugEvent, IDebugProgramDestroyEvent2  | 
|     {  | 
|         uint exitCode;  | 
|         public new Program Program { get; private set; }  | 
|   | 
|         public ProgramDestroyEvent(Program program, uint exitCode)  | 
|         : base(program.Engine, typeof(IDebugProgramDestroyEvent2).GUID,  | 
|               SYNCHRONOUS, program)  | 
|         {  | 
|             Program = program;  | 
|             this.exitCode = exitCode;  | 
|         }  | 
|   | 
|         int IDebugProgramDestroyEvent2.GetExitCode(out uint exitCode)  | 
|         {  | 
|             exitCode = this.exitCode;  | 
|             return VSConstants.S_OK;  | 
|         }  | 
|     }  | 
|   | 
|     class ThreadCreateEvent : DebugEvent, IDebugThreadCreateEvent2  | 
|     {  | 
|         public ThreadCreateEvent(Program program)  | 
|         : base(program.Engine, typeof(IDebugThreadCreateEvent2).GUID,  | 
|               ASYNCHRONOUS, program, program)  | 
|         { }  | 
|     }  | 
|   | 
|     class ThreadDestroyEvent : DebugEvent, IDebugThreadDestroyEvent2  | 
|     {  | 
|         uint exitCode;  | 
|   | 
|         public ThreadDestroyEvent(Program program, uint exitCode)  | 
|         : base(program.Engine, typeof(IDebugThreadDestroyEvent2).GUID,  | 
|               SYNCHRONOUS, program, program)  | 
|         {  | 
|             this.exitCode = exitCode;  | 
|         }  | 
|   | 
|         int IDebugThreadDestroyEvent2.GetExitCode(out uint exitCode)  | 
|         {  | 
|             exitCode = this.exitCode;  | 
|             return VSConstants.S_OK;  | 
|         }  | 
|     }  | 
|   | 
|     class LoadCompleteEvent : DebugEvent, IDebugLoadCompleteEvent2  | 
|     {  | 
|         public LoadCompleteEvent(Program program)  | 
|         : base(program.Engine, typeof(IDebugLoadCompleteEvent2).GUID,  | 
|               STOPPING, program, program)  | 
|         { }  | 
|     }  | 
|   | 
|     class EntryPointEvent : DebugEvent, IDebugEntryPointEvent2  | 
|     {  | 
|         public EntryPointEvent(Program program)  | 
|         : base(program.Engine, typeof(IDebugEntryPointEvent2).GUID,  | 
|               STOPPING, program, program)  | 
|         { }  | 
|     }  | 
|   | 
|     class BreakpointBoundEvent : DebugEvent, IDebugBreakpointBoundEvent2  | 
|     {  | 
|         public Breakpoint Breakpoint { get; private set; }  | 
|         public BreakpointBoundEvent(Breakpoint breakpoint)  | 
|         : base(breakpoint.Program.Engine, typeof(IDebugBreakpointBoundEvent2).GUID,  | 
|               ASYNCHRONOUS, breakpoint.Program, breakpoint.Program)  | 
|         {  | 
|             Breakpoint = breakpoint;  | 
|         }  | 
|   | 
|         int IDebugBreakpointBoundEvent2.GetPendingBreakpoint(  | 
|             out IDebugPendingBreakpoint2 ppPendingBP)  | 
|         {  | 
|             ppPendingBP = Breakpoint.Parent;  | 
|             return VSConstants.S_OK;  | 
|         }  | 
|   | 
|         int IDebugBreakpointBoundEvent2.EnumBoundBreakpoints(  | 
|             out IEnumDebugBoundBreakpoints2 ppEnum)  | 
|         {  | 
|             ppEnum = BoundBreakpointsEnum.Create(Breakpoint);  | 
|             return VSConstants.S_OK;  | 
|         }  | 
|     }  | 
|   | 
|     class BreakpointEvent : DebugEvent, IDebugBreakpointEvent2  | 
|     {  | 
|         IEnumDebugBoundBreakpoints2 boundBreakpoints;  | 
|   | 
|         public BreakpointEvent(Program program,  | 
|             IEnumDebugBoundBreakpoints2 boundBreakpoints)  | 
|         : base(program.Engine, typeof(IDebugBreakpointEvent2).GUID,  | 
|               STOPPING, program, program)  | 
|         {  | 
|             this.boundBreakpoints = boundBreakpoints;  | 
|         }  | 
|   | 
|         int IDebugBreakpointEvent2.EnumBreakpoints(out IEnumDebugBoundBreakpoints2 ppEnum)  | 
|         {  | 
|             ppEnum = boundBreakpoints;  | 
|             return VSConstants.S_OK;  | 
|         }  | 
|     }  | 
|   | 
|     class StepCompleteEvent : DebugEvent, IDebugStepCompleteEvent2  | 
|     {  | 
|         public StepCompleteEvent(Program program)  | 
|         : base(program.Engine, typeof(IDebugStepCompleteEvent2).GUID,  | 
|               STOPPING, program, program)  | 
|         { }  | 
|     }  | 
|   | 
|     class ExpressionEvaluationCompleteEvent : DebugEvent, IDebugExpressionEvaluationCompleteEvent2  | 
|     {  | 
|         public Expression Expression { get; private set; }  | 
|         public Property Property { get; private set; }  | 
|   | 
|         public ExpressionEvaluationCompleteEvent(  | 
|             IDebugEventCallback2 callback,  | 
|             Expression expression,  | 
|             Property property)  | 
|             : base(expression.Engine, typeof(IDebugExpressionEvaluationCompleteEvent2).GUID,  | 
|                 SYNCHRONOUS, expression.Program, expression.Program, callback)  | 
|         {  | 
|             Expression = expression;  | 
|             Property = property;  | 
|         }  | 
|   | 
|         int IDebugExpressionEvaluationCompleteEvent2.GetExpression(out IDebugExpression2 ppExpr)  | 
|         {  | 
|             ppExpr = Expression;  | 
|             return VSConstants.S_OK;  | 
|         }  | 
|   | 
|         int IDebugExpressionEvaluationCompleteEvent2.GetResult(out IDebugProperty2 ppResult)  | 
|         {  | 
|             ppResult = Property;  | 
|             return VSConstants.S_OK;  | 
|         }  | 
|     }  | 
|   | 
|     class OutputStringEvent : DebugEvent, IDebugOutputStringEvent2  | 
|     {  | 
|         string outputString;  | 
|   | 
|         public OutputStringEvent(QmlEngine engine, string outputString)  | 
|         : base(engine, typeof(IDebugOutputStringEvent2).GUID, ASYNCHRONOUS)  | 
|         {  | 
|             this.outputString = outputString;  | 
|         }  | 
|   | 
|         int IDebugOutputStringEvent2.GetString(out string pbstrString)  | 
|         {  | 
|             pbstrString = outputString;  | 
|             return VSConstants.S_OK;  | 
|         }  | 
|     }  | 
| }  |