xref: /haiku/src/apps/debugger/user_interface/cli/CliContext.h (revision f5821a1aee77d3b9a979b42c68a79e50b5ebaefe)
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