24 output: Map[String, Command.Results] = Map.empty) // thread name ~> output messages |
24 output: Map[String, Command.Results] = Map.empty) // thread name ~> output messages |
25 { |
25 { |
26 def set_session(new_session: Session): State = |
26 def set_session(new_session: Session): State = |
27 copy(session = new_session) |
27 copy(session = new_session) |
28 |
28 |
29 def inc_active: (Boolean, State) = (active == 0, copy(active = active + 1)) |
29 def is_active: Boolean = active > 0 |
30 def dec_active: (Boolean, State) = (active == 1, copy(active = active - 1)) |
30 def inc_active: State = copy(active = active + 1) |
|
31 def dec_active: State = copy(active = active - 1) |
31 |
32 |
32 def toggle_breakpoint(breakpoint: Long): (Boolean, State) = |
33 def toggle_breakpoint(breakpoint: Long): (Boolean, State) = |
33 { |
34 { |
34 val active_breakpoints1 = |
35 val active_breakpoints1 = |
35 if (active_breakpoints(breakpoint)) active_breakpoints - breakpoint |
36 if (active_breakpoints(breakpoint)) active_breakpoints - breakpoint |
60 copy(threads = threads - thread_name, output = output - thread_name) |
61 copy(threads = threads - thread_name, output = output - thread_name) |
61 else this |
62 else this |
62 } |
63 } |
63 |
64 |
64 private val global_state = Synchronized(State()) |
65 private val global_state = Synchronized(State()) |
65 def current_state(): State = global_state.value |
|
66 |
66 |
67 |
67 |
68 /* protocol handler */ |
68 /* protocol handler */ |
69 |
69 |
70 sealed case class Update(thread_names: Set[String]) |
70 sealed case class Update(thread_names: Set[String]) |
71 |
71 |
72 class Handler extends Session.Protocol_Handler |
72 class Handler extends Session.Protocol_Handler |
73 { |
73 { |
74 private var updated = Set.empty[String] |
74 private var updated = Set.empty[String] |
75 private val delay_update = |
75 private val delay_update = |
76 Simple_Thread.delay_first(current_state().session.output_delay) { |
76 Simple_Thread.delay_first(global_state.value.session.output_delay) { |
77 current_state().session.debugger_updates.post(Update(updated)) |
77 global_state.value.session.debugger_updates.post(Update(updated)) |
78 updated = Set.empty |
78 updated = Set.empty |
79 } |
79 } |
80 private def update(name: String) |
80 private def update(name: String) |
81 { |
81 { |
82 updated += name |
82 updated += name |
132 /* protocol commands */ |
132 /* protocol commands */ |
133 |
133 |
134 def set_session(session: Session): Unit = |
134 def set_session(session: Session): Unit = |
135 global_state.change(_.set_session(session)) |
135 global_state.change(_.set_session(session)) |
136 |
136 |
137 def is_active(): Boolean = current_state().active > 0 |
137 def is_active(): Boolean = global_state.value.is_active |
138 |
138 |
139 def inc_active(): Unit = |
139 def inc_active(): Unit = |
140 global_state.change(state => |
140 global_state.change(state => |
141 { |
141 { |
142 val (init, state1) = state.inc_active |
142 val state1 = state.inc_active |
143 if (init) state1.session.protocol_command("Debugger.init") |
143 if (!state.is_active && state1.is_active) |
|
144 state1.session.protocol_command("Debugger.init") |
144 state1 |
145 state1 |
145 }) |
146 }) |
146 |
147 |
147 def dec_active(): Unit = |
148 def dec_active(): Unit = |
148 global_state.change(state => |
149 global_state.change(state => |
149 { |
150 { |
150 val (exit, state1) = state.dec_active |
151 val state1 = state.dec_active |
151 if (exit) state1.session.protocol_command("Debugger.exit") |
152 if (state.is_active && !state1.is_active) |
|
153 state1.session.protocol_command("Debugger.exit") |
152 state1 |
154 state1 |
153 }) |
155 }) |
154 |
156 |
155 def active_breakpoint_state(breakpoint: Long): Option[Boolean] = |
157 def active_breakpoint_state(breakpoint: Long): Option[Boolean] = |
156 { |
158 { |
157 val state = current_state() |
159 val state = global_state.value |
158 if (state.active > 0) Some(state.active_breakpoints(breakpoint)) else None |
160 if (state.active > 0) Some(state.active_breakpoints(breakpoint)) else None |
159 } |
161 } |
160 |
162 |
161 def breakpoint_state(breakpoint: Long): Boolean = |
163 def breakpoint_state(breakpoint: Long): Boolean = |
162 current_state().active_breakpoints(breakpoint) |
164 global_state.value.active_breakpoints(breakpoint) |
163 |
165 |
164 def toggle_breakpoint(command: Command, breakpoint: Long) |
166 def toggle_breakpoint(command: Command, breakpoint: Long) |
165 { |
167 { |
166 global_state.change(state => |
168 global_state.change(state => |
167 { |
169 { |
177 } |
179 } |
178 |
180 |
179 def focus(new_focus: Option[Position.T]): Boolean = |
181 def focus(new_focus: Option[Position.T]): Boolean = |
180 global_state.change_result(state => (state.focus != new_focus, state.set_focus(new_focus))) |
182 global_state.change_result(state => (state.focus != new_focus, state.set_focus(new_focus))) |
181 |
183 |
|
184 def threads(): Map[String, List[Debug_State]] = global_state.value.threads |
|
185 |
|
186 def output(): Map[String, Command.Results] = global_state.value.output |
|
187 |
182 def input(thread_name: String, msg: String*): Unit = |
188 def input(thread_name: String, msg: String*): Unit = |
183 current_state().session.protocol_command("Debugger.input", (thread_name :: msg.toList):_*) |
189 global_state.value.session.protocol_command("Debugger.input", (thread_name :: msg.toList):_*) |
184 |
190 |
185 def step(thread_name: String): Unit = input(thread_name, "step") |
191 def step(thread_name: String): Unit = input(thread_name, "step") |
186 def step_over(thread_name: String): Unit = input(thread_name, "step_over") |
192 def step_over(thread_name: String): Unit = input(thread_name, "step_over") |
187 def step_out(thread_name: String): Unit = input(thread_name, "step_out") |
193 def step_out(thread_name: String): Unit = input(thread_name, "step_out") |
188 def continue(thread_name: String): Unit = input(thread_name, "continue") |
194 def continue(thread_name: String): Unit = input(thread_name, "continue") |