1 /* 2 * Copyright 2012, Ingo Weinhold, ingo_weinhold@gmx.de. 3 * Distributed under the terms of the MIT License. 4 */ 5 #ifndef CLI_CONTEXT_H 6 #define CLI_CONTEXT_H 7 8 9 #include <sys/cdefs.h> 10 // Needed in histedit.h. 11 #include <histedit.h> 12 13 #include <Locker.h> 14 15 #include "Team.h" 16 #include "TeamMemoryBlock.h" 17 #include "ValueNodeContainer.h" 18 19 20 class StackFrame; 21 class StackTrace; 22 class Team; 23 class TeamMemoryBlock; 24 class UserInterfaceListener; 25 class ValueNodeManager; 26 27 28 class CliContext : private Team::Listener, 29 public TeamMemoryBlock::Listener, 30 private ValueNodeContainer::Listener { 31 public: 32 enum { 33 EVENT_QUIT = 0x01, 34 EVENT_USER_INTERRUPT = 0x02, 35 EVENT_THREAD_ADDED = 0x04, 36 EVENT_THREAD_REMOVED = 0x08, 37 EVENT_THREAD_STOPPED = 0x10, 38 EVENT_THREAD_STACK_TRACE_CHANGED = 0x20, 39 EVENT_VALUE_NODE_CHANGED = 0x40, 40 EVENT_TEAM_MEMORY_BLOCK_RETRIEVED = 0x80 41 }; 42 43 public: 44 CliContext(); 45 ~CliContext(); 46 47 status_t Init(Team* team, 48 UserInterfaceListener* listener); 49 void Cleanup(); 50 51 void Terminating(); 52 53 bool IsTerminating() const { return fTerminating; } 54 55 // service methods for the input loop thread follow 56 57 Team* GetTeam() const { return fTeam; } 58 UserInterfaceListener* GetUserInterfaceListener() const 59 { return fListener; } 60 ValueNodeManager* GetValueNodeManager() const 61 { return fNodeManager; } 62 StackTrace* GetStackTrace() const 63 { return fCurrentStackTrace; } 64 65 Thread* CurrentThread() const { return fCurrentThread; } 66 thread_id CurrentThreadID() const; 67 void SetCurrentThread(Thread* thread); 68 void PrintCurrentThread(); 69 70 int32 CurrentStackFrameIndex() const 71 { return fCurrentStackFrameIndex; } 72 void SetCurrentStackFrameIndex(int32 index); 73 74 TeamMemoryBlock* CurrentBlock() const { return fCurrentBlock; } 75 76 const char* PromptUser(const char* prompt); 77 void AddLineToInputHistory(const char* line); 78 79 void QuitSession(bool killTeam); 80 81 void WaitForThreadOrUser(); 82 void WaitForEvents(int32 eventMask); 83 void ProcessPendingEvents(); 84 85 private: 86 struct Event; 87 88 typedef DoublyLinkedList<Event> EventList; 89 90 private: 91 // Team::Listener 92 virtual void ThreadAdded(const Team::ThreadEvent& event); 93 virtual void ThreadRemoved(const Team::ThreadEvent& event); 94 95 virtual void ThreadStateChanged( 96 const Team::ThreadEvent& event); 97 virtual void ThreadStackTraceChanged( 98 const Team::ThreadEvent& event); 99 100 // TeamMemoryBlock::Listener 101 virtual void MemoryBlockRetrieved(TeamMemoryBlock* block); 102 103 // ValueNodeContainer::Listener 104 virtual void ValueNodeChanged(ValueNodeChild* nodeChild, 105 ValueNode* oldNode, ValueNode* newNode); 106 virtual void ValueNodeChildrenCreated(ValueNode* node); 107 virtual void ValueNodeChildrenDeleted(ValueNode* node); 108 virtual void ValueNodeValueChanged(ValueNode* node); 109 110 private: 111 void _QueueEvent(Event* event); 112 113 void _PrepareToWaitForEvents(uint32 eventMask); 114 uint32 _WaitForEvents(); 115 void _SignalInputLoop(uint32 events); 116 117 static const char* _GetPrompt(EditLine* editLine); 118 119 private: 120 BLocker fLock; 121 Team* fTeam; 122 UserInterfaceListener* fListener; 123 ValueNodeManager* fNodeManager; 124 EditLine* fEditLine; 125 History* fHistory; 126 const char* fPrompt; 127 sem_id fBlockingSemaphore; 128 uint32 fInputLoopWaitingForEvents; 129 uint32 fEventsOccurred; 130 bool fInputLoopWaiting; 131 volatile bool fTerminating; 132 133 Thread* fCurrentThread; 134 StackTrace* fCurrentStackTrace; 135 int32 fCurrentStackFrameIndex; 136 TeamMemoryBlock* fCurrentBlock; 137 138 EventList fPendingEvents; 139 }; 140 141 142 #endif // CLI_CONTEXT_H 143