Skip to content

Commit 6cea5c9

Browse files
committed
Cancelling wiring with escape, deleting wires and rewiring
1 parent c5ec316 commit 6cea5c9

File tree

6 files changed

+132
-12
lines changed

6 files changed

+132
-12
lines changed

build.zig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ pub fn build(b: *std.Build) void {
6565
} else {
6666
cflags.appendSlice(&.{
6767
"-g",
68-
"-O1",
68+
"-O0",
6969
"-fno-omit-frame-pointer",
7070
"-fno-optimize-sibling-calls",
7171
"-Wall",

src/autoroute/autoroute.c

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@ struct AutoRoute {
4848

4949
RT_Graph *graph;
5050

51+
bool needsRefresh;
52+
5153
int timeIndex;
5254
int timeLength;
5355
uint64_t buildTimes[TIME_SAMPLES];
@@ -171,6 +173,34 @@ static void autoroute_on_waypoint_update(void *user, WaypointID id, void *ptr) {
171173
ar, waypoint->net, circuit_net_ptr(ar->circuit, waypoint->net));
172174
}
173175

176+
static void autoroute_on_any_delete(void *user, ID id, void *ptr) {
177+
AutoRoute *ar = user;
178+
ar->needsRefresh = true;
179+
}
180+
181+
static void autoroute_refresh_data(AutoRoute *ar) {
182+
for (int i = 0; i < circuit_component_len(ar->circuit); i++) {
183+
Component *comp = &ar->circuit->components[i];
184+
autoroute_on_component_update(
185+
ar, circuit_component_id(ar->circuit, i), comp);
186+
}
187+
for (int i = 0; i < circuit_net_len(ar->circuit); i++) {
188+
Net *net = &ar->circuit->nets[i];
189+
autoroute_on_net_update(ar, circuit_net_id(ar->circuit, i), net);
190+
}
191+
for (int i = 0; i < circuit_endpoint_len(ar->circuit); i++) {
192+
Endpoint *endpoint = &ar->circuit->endpoints[i];
193+
autoroute_on_endpoint_update(
194+
ar, circuit_endpoint_id(ar->circuit, i), endpoint);
195+
}
196+
for (int i = 0; i < circuit_waypoint_len(ar->circuit); i++) {
197+
Waypoint *waypoint = &ar->circuit->waypoints[i];
198+
autoroute_on_waypoint_update(
199+
ar, circuit_waypoint_id(ar->circuit, i), waypoint);
200+
}
201+
ar->needsRefresh = false;
202+
}
203+
174204
AutoRoute *autoroute_create(Circuit *circuit) {
175205
AutoRoute *ar = malloc(sizeof(AutoRoute));
176206
*ar = (AutoRoute){
@@ -180,23 +210,27 @@ AutoRoute *autoroute_create(Circuit *circuit) {
180210
&circuit->sm.components, (void **)&ar->boxes, sizeof(*ar->boxes));
181211
circuit_on_component_create(circuit, ar, autoroute_on_component_update);
182212
circuit_on_component_update(circuit, ar, autoroute_on_component_update);
213+
circuit_on_component_delete(circuit, ar, autoroute_on_any_delete);
183214

184215
smap_add_synced_array(
185216
&circuit->sm.nets, (void **)&ar->nets, sizeof(*ar->nets));
186217
smap_add_synced_array(
187218
&circuit->sm.nets, (void **)&ar->netViews, sizeof(*ar->netViews));
188219
circuit_on_net_create(circuit, ar, autoroute_on_net_update);
189220
circuit_on_net_update(circuit, ar, autoroute_on_net_update);
221+
circuit_on_net_delete(circuit, ar, autoroute_on_any_delete);
190222

191223
smap_add_synced_array(
192224
&circuit->sm.endpoints, (void **)&ar->endpoints, sizeof(*ar->endpoints));
193225
circuit_on_endpoint_create(circuit, ar, autoroute_on_endpoint_update);
194226
circuit_on_endpoint_update(circuit, ar, autoroute_on_endpoint_update);
227+
circuit_on_endpoint_delete(circuit, ar, autoroute_on_any_delete);
195228

196229
smap_add_synced_array(
197230
&circuit->sm.waypoints, (void **)&ar->waypoints, sizeof(*ar->waypoints));
198231
circuit_on_waypoint_create(circuit, ar, autoroute_on_waypoint_update);
199232
circuit_on_waypoint_update(circuit, ar, autoroute_on_waypoint_update);
233+
circuit_on_waypoint_delete(circuit, ar, autoroute_on_any_delete);
200234

201235
RT_Result res = RT_graph_new(&ar->graph);
202236
assert(res == RT_RESULT_SUCCESS);
@@ -317,6 +351,10 @@ static void autoroute_prepare_routing(AutoRoute *ar, RoutingConfig config) {
317351
return;
318352
}
319353

354+
if (ar->needsRefresh) {
355+
autoroute_refresh_data(ar);
356+
}
357+
320358
RT_Result res = RT_graph_build(
321359
ar->graph, (RT_Slice_Anchor){ar->anchors, arrlen(ar->anchors)},
322360
(RT_Slice_BoundingBox){ar->boxes, circuit_component_len(ar->circuit)},

src/core/circuit.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -218,8 +218,8 @@ static void circuit_port_deleted(void *user, ID id, void *ptr) {
218218

219219
if (circuit_has(circuit, port->endpoint)) {
220220
Endpoint *endpoint = circuit_endpoint_ptr(circuit, port->endpoint);
221-
circuit_update_id(circuit, port->endpoint);
222221
endpoint->port = NO_PORT;
222+
circuit_update_id(circuit, port->endpoint);
223223
}
224224

225225
circuit_del(circuit, port->label);

src/main.c

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -424,9 +424,9 @@ void event(const sapp_event *event, void *user_data) {
424424
bv_set(app->circuit.ux.input.keysDown, event->key_code);
425425
bv_set(app->circuit.ux.input.keysPressed, event->key_code);
426426
app->circuit.ux.input.modifiers = event->modifiers;
427-
if (event->key_code == SAPP_KEYCODE_ESCAPE) {
428-
sapp_request_quit();
429-
}
427+
// if (event->key_code == SAPP_KEYCODE_ESCAPE) {
428+
// sapp_request_quit();
429+
// }
430430
break;
431431

432432
case SAPP_EVENTTYPE_KEY_UP:
@@ -472,6 +472,11 @@ sapp_desc sokol_main(int argc, char *argv[]) {
472472

473473
log_info("Global setup complete");
474474

475+
#ifndef _WIN32
476+
init_exceptions(argv[0]);
477+
log_info("Exceptions hooked");
478+
#endif
479+
475480
my_app_t *app = malloc(sizeof(my_app_t));
476481
*app = (my_app_t){
477482
.filename = "testdata/alu_1bit_2gatemux.dig",

src/ux/input.c

Lines changed: 81 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
*/
1616

1717
#include "core/core.h"
18+
#include "core/structs.h"
1819
#include "handmade_math.h"
1920
#include "render/draw.h"
2021
#include "stb_ds.h"
@@ -39,29 +40,36 @@ static const char *stateNames[] = {
3940
[STATE_SELECT_AREA] = "SelArea",
4041
[STATE_SELECT_ONE] = "SelOne",
4142
[STATE_MOVE_SELECTION] = "MoveSel",
43+
[STATE_CLICK_ENDPOINT] = "ClickEndpoint",
4244
[STATE_CLICK_PORT] = "ClickPort",
4345
[STATE_DRAG_WIRING] = "DragWiring",
4446
[STATE_START_CLICK_WIRING] = "StartClickWiring",
4547
[STATE_CLICK_WIRING] = "ClickWiring",
4648
[STATE_CONNECT_PORT] = "ConnectPort",
4749
[STATE_FLOATING_WIRE] = "FloatingWire",
50+
[STATE_CANCEL_WIRE] = "CancelWire",
4851
[STATE_ADDING_COMPONENT] = "AddingComponent",
4952
[STATE_ADD_COMPONENT] = "AddComponent",
5053
};
5154

5255
static void ux_mouse_down_state_machine(CircuitUX *ux, HMM_Vec2 worldMousePos) {
5356
bool rightDown = ux->input.modifiers & MODIFIER_RMB;
5457
bool leftDown = ux->input.modifiers & MODIFIER_LMB;
58+
bool shiftDown = ux->input.modifiers & MODIFIER_SHIFT;
59+
bool escDown = bv_is_set(ux->input.keysDown, KEYCODE_ESCAPE);
5560

5661
bool overPort = false;
5762
bool overItem = false;
63+
bool overEndpoint = false;
5864

5965
for (size_t i = 0; i < arrlen(ux->view.hovered); i++) {
6066
ID id = ux->view.hovered[i];
6167
if (id_type(id) == ID_PORT) {
6268
overPort = true;
6369
} else if (id_type(id) == ID_COMPONENT || id_type(id) == ID_WAYPOINT) {
6470
overItem = true;
71+
} else if (id_type(id) == ID_ENDPOINT) {
72+
overEndpoint = true;
6573
}
6674
}
6775

@@ -102,6 +110,12 @@ static void ux_mouse_down_state_machine(CircuitUX *ux, HMM_Vec2 worldMousePos) {
102110
if (leftDown) {
103111
if (inSelection) {
104112
state = STATE_MOVE_SELECTION;
113+
} else if (overEndpoint) {
114+
if (shiftDown && overPort) {
115+
state = STATE_CLICK_PORT;
116+
} else {
117+
state = STATE_CLICK_ENDPOINT;
118+
}
105119
} else if (overPort) {
106120
state = STATE_CLICK_PORT;
107121
} else if (overItem) {
@@ -152,6 +166,7 @@ static void ux_mouse_down_state_machine(CircuitUX *ux, HMM_Vec2 worldMousePos) {
152166
state = STATE_UP;
153167
}
154168
break;
169+
case STATE_CLICK_ENDPOINT: // fallthrough
155170
case STATE_CLICK_PORT:
156171
if (!leftDown) {
157172
state = STATE_START_CLICK_WIRING;
@@ -160,7 +175,9 @@ static void ux_mouse_down_state_machine(CircuitUX *ux, HMM_Vec2 worldMousePos) {
160175
}
161176
break;
162177
case STATE_DRAG_WIRING:
163-
if (overPort && !leftDown) {
178+
if (escDown) {
179+
state = STATE_CANCEL_WIRE;
180+
} else if (overPort && !leftDown) {
164181
state = STATE_CONNECT_PORT;
165182
} else if (!overPort && !leftDown) {
166183
state = STATE_FLOATING_WIRE;
@@ -178,6 +195,8 @@ static void ux_mouse_down_state_machine(CircuitUX *ux, HMM_Vec2 worldMousePos) {
178195
} else if (!overPort) {
179196
state = STATE_FLOATING_WIRE;
180197
}
198+
} else if (escDown) {
199+
state = STATE_CANCEL_WIRE;
181200
}
182201
break;
183202
case STATE_CONNECT_PORT:
@@ -190,6 +209,11 @@ static void ux_mouse_down_state_machine(CircuitUX *ux, HMM_Vec2 worldMousePos) {
190209
state = STATE_UP;
191210
}
192211
break;
212+
case STATE_CANCEL_WIRE:
213+
if (!leftDown && !escDown) {
214+
state = STATE_UP;
215+
}
216+
break;
193217
case STATE_ADDING_COMPONENT:
194218
if (leftDown) {
195219
state = STATE_ADD_COMPONENT;
@@ -282,6 +306,16 @@ static void ux_mouse_down_state_machine(CircuitUX *ux, HMM_Vec2 worldMousePos) {
282306
}
283307
break;
284308

309+
case STATE_CLICK_ENDPOINT:
310+
for (size_t i = 0; i < arrlen(ux->view.hovered); i++) {
311+
ID id = ux->view.hovered[i];
312+
if (id_type(id) == ID_ENDPOINT) {
313+
ux_continue_wire(ux, id);
314+
break;
315+
}
316+
}
317+
break;
318+
285319
case STATE_CLICK_PORT:
286320
for (size_t i = 0; i < arrlen(ux->view.hovered); i++) {
287321
ID id = ux->view.hovered[i];
@@ -305,11 +339,23 @@ static void ux_mouse_down_state_machine(CircuitUX *ux, HMM_Vec2 worldMousePos) {
305339
ID id = ux->view.hovered[i];
306340
if (id_type(id) == ID_PORT) {
307341
ux_connect_wire(ux, id);
342+
ux_route(ux);
308343
break;
309344
}
310345
}
311346
break;
312347

348+
case STATE_CANCEL_WIRE:
349+
ux_cancel_wire(ux);
350+
351+
// rebuild the BVH after removing things
352+
ux_build_bvh(ux);
353+
354+
log_debug("routing after cancel");
355+
ux_route(ux);
356+
log_debug("cancelled wire, finished routing");
357+
break;
358+
313359
default:
314360
break;
315361
}
@@ -559,19 +605,48 @@ void ux_start_wire(CircuitUX *ux, PortID portID) {
559605
circuit_add_endpoint(&ux->view.circuit, netID, NO_PORT, HMM_V2(0, 0));
560606
}
561607

608+
void ux_continue_wire(CircuitUX *ux, EndpointID endpointID) {
609+
ux->newNet = false;
610+
ux->endpointStart = NO_ENDPOINT;
611+
ux->endpointEnd = endpointID;
612+
Endpoint *endpoint = circuit_endpoint_ptr(&ux->view.circuit, endpointID);
613+
if (endpoint->port != NO_PORT) {
614+
// disconnect endpoint from port
615+
Port *port = circuit_port_ptr(&ux->view.circuit, endpoint->port);
616+
port->endpoint = NO_ENDPOINT;
617+
endpoint->port = NO_PORT;
618+
}
619+
Net *net = circuit_net_ptr(&ux->view.circuit, endpoint->net);
620+
int count = 0;
621+
EndpointID netEndpointID = net->endpointFirst;
622+
EndpointID otherEndpointID = NO_ENDPOINT;
623+
while (circuit_has(&ux->view.circuit, netEndpointID)) {
624+
Endpoint *endpoint = circuit_endpoint_ptr(&ux->view.circuit, netEndpointID);
625+
if (netEndpointID != endpointID) {
626+
otherEndpointID = netEndpointID;
627+
}
628+
count++;
629+
netEndpointID = endpoint->next;
630+
}
631+
if (count <= 2) {
632+
ux->newNet = true;
633+
ux->endpointStart = otherEndpointID;
634+
}
635+
}
636+
562637
void ux_cancel_wire(CircuitUX *ux) {
638+
NetID netID = circuit_endpoint_ptr(&ux->view.circuit, ux->endpointEnd)->net;
563639
circuit_del(&ux->view.circuit, ux->endpointEnd);
564640
if (ux->newNet) {
565-
Endpoint *endpoint =
566-
circuit_endpoint_ptr(&ux->view.circuit, ux->endpointStart);
567-
NetID netID = endpoint->net;
568-
circuit_del(&ux->view.circuit, ux->endpointStart);
641+
if (circuit_has(&ux->view.circuit, ux->endpointStart)) {
642+
circuit_del(&ux->view.circuit, ux->endpointStart);
643+
}
569644
circuit_del(&ux->view.circuit, netID);
570645
}
646+
571647
ux->newNet = false;
572648
ux->endpointStart = NO_ENDPOINT;
573649
ux->endpointEnd = NO_ENDPOINT;
574-
ux_route(ux);
575650
}
576651

577652
void ux_connect_wire(CircuitUX *ux, PortID portID) {
@@ -583,7 +658,6 @@ void ux_connect_wire(CircuitUX *ux, PortID portID) {
583658
}
584659

585660
circuit_endpoint_connect(&ux->view.circuit, ux->endpointEnd, portID);
586-
ux_route(ux);
587661

588662
ux->newNet = false;
589663
ux->endpointStart = NO_ENDPOINT;

src/ux/ux.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,11 +166,13 @@ typedef enum MouseDownState {
166166
STATE_SELECT_AREA,
167167
STATE_SELECT_ONE,
168168
STATE_MOVE_SELECTION,
169+
STATE_CLICK_ENDPOINT,
169170
STATE_CLICK_PORT,
170171
STATE_DRAG_WIRING,
171172
STATE_START_CLICK_WIRING,
172173
STATE_CLICK_WIRING,
173174
STATE_CONNECT_PORT,
175+
STATE_CANCEL_WIRE,
174176
STATE_FLOATING_WIRE,
175177
STATE_ADDING_COMPONENT,
176178
STATE_ADD_COMPONENT,
@@ -355,6 +357,7 @@ void ux_stop_adding_component(CircuitUX *ux);
355357
void ux_change_adding_component(CircuitUX *ux, ComponentDescID descID);
356358

357359
void ux_start_wire(CircuitUX *ux, PortID portID);
360+
void ux_continue_wire(CircuitUX *ux, EndpointID endpointID);
358361
void ux_cancel_wire(CircuitUX *ux);
359362
void ux_connect_wire(CircuitUX *ux, PortID portID);
360363

0 commit comments

Comments
 (0)