Skip to content

Commit 238fdb6

Browse files
committed
wip: add other gates
1 parent 70eb030 commit 238fdb6

File tree

1 file changed

+126
-3
lines changed

1 file changed

+126
-3
lines changed

complogic-gui/src/app.rs

Lines changed: 126 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use eframe::{
66
};
77
use egui_node_graph::*;
88

9-
use complogic::{And, Compiler, Gate, Simulation};
9+
use complogic::{And, Compiler, Gate, Nand, Not, Simulation};
1010

1111
// ========= First, define your user data types =============
1212

@@ -60,6 +60,8 @@ impl ValueType {
6060
#[derive(Clone, Copy, serde::Serialize, serde::Deserialize)]
6161
pub enum NodeTempl {
6262
And,
63+
Not,
64+
Nand,
6365
Immediate,
6466
}
6567

@@ -120,6 +122,8 @@ impl NodeTemplateTrait for NodeTempl {
120122
) -> Cow<'_, str> {
121123
Cow::Borrowed(match self {
122124
NodeTempl::And => "And Gate",
125+
NodeTempl::Not => "Not Gate",
126+
NodeTempl::Nand => "Nand Gate",
123127
NodeTempl::Immediate => "Immediate",
124128
})
125129
}
@@ -130,7 +134,7 @@ impl NodeTemplateTrait for NodeTempl {
130134
_user_state: &mut Self::UserState,
131135
) -> Vec<&'static str> {
132136
match self {
133-
NodeTempl::And => vec!["Gate"],
137+
NodeTempl::And | NodeTempl::Not | NodeTempl::Nand => vec!["Gates"],
134138
NodeTempl::Immediate => vec!["Tools"],
135139
}
136140
}
@@ -172,6 +176,7 @@ impl NodeTemplateTrait for NodeTempl {
172176
};
173177

174178
match self {
179+
// Gates
175180
NodeTempl::And => {
176181
// The first input param doesn't use the closure so we can comment
177182
// it in more detail.
@@ -193,6 +198,17 @@ impl NodeTemplateTrait for NodeTempl {
193198
input_scalar(graph, "B");
194199
output_scalar(graph, "out");
195200
}
201+
NodeTempl::Not => {
202+
input_scalar(graph, "A");
203+
output_scalar(graph, "out");
204+
}
205+
NodeTempl::Nand => {
206+
input_scalar(graph, "A");
207+
input_scalar(graph, "B");
208+
output_scalar(graph, "out");
209+
}
210+
211+
// Tools
196212
NodeTempl::Immediate => {
197213
// The first input param doesn't use the closure so we can comment
198214
// it in more detail.
@@ -225,7 +241,12 @@ impl NodeTemplateIter for AllNodeTempls {
225241
// This function must return a list of node kinds, which the node finder
226242
// will use to display it to the user. Crates like strum can reduce the
227243
// boilerplate in enumerating all variants of an enum.
228-
vec![NodeTempl::And, NodeTempl::Immediate]
244+
vec![
245+
NodeTempl::And,
246+
NodeTempl::Not,
247+
NodeTempl::Nand,
248+
NodeTempl::Immediate,
249+
]
229250
}
230251
}
231252

@@ -484,6 +505,84 @@ impl eframe::App for NodeGraphExample {
484505
let gate = And { a, b, out };
485506
self.user_state.gates.insert(id, Gate::from(gate));
486507
}
508+
NodeTempl::Not => {
509+
let mut in_ids = data.input_ids();
510+
let mut out_ids = data.output_ids();
511+
512+
let a_out = self.state.graph.connection(in_ids.next().unwrap());
513+
514+
if a_out.is_none() {
515+
continue;
516+
}
517+
518+
let a_out = a_out.unwrap();
519+
520+
let a = match self.user_state.outs_to_regs.get(&a_out) {
521+
Some(reg) => *reg,
522+
None => {
523+
let reg = self.user_state.compiler.alloc();
524+
self.user_state.outs_to_regs.insert(a_out, reg);
525+
reg
526+
}
527+
};
528+
529+
let out_id = out_ids.next().unwrap();
530+
let out = match self.user_state.outs_to_regs.get(&out_id) {
531+
Some(reg) => *reg,
532+
None => {
533+
let reg = self.user_state.compiler.alloc();
534+
self.user_state.outs_to_regs.insert(out_id, reg);
535+
reg
536+
}
537+
};
538+
539+
let gate = Not { a, out };
540+
self.user_state.gates.insert(id, Gate::from(gate));
541+
}
542+
NodeTempl::Nand => {
543+
let mut in_ids = data.input_ids();
544+
let mut out_ids = data.output_ids();
545+
546+
let a_out = self.state.graph.connection(in_ids.next().unwrap());
547+
let b_out = self.state.graph.connection(in_ids.next().unwrap());
548+
549+
if a_out.is_none() || b_out.is_none() {
550+
continue;
551+
}
552+
553+
let a_out = a_out.unwrap();
554+
let b_out = b_out.unwrap();
555+
556+
let a = match self.user_state.outs_to_regs.get(&a_out) {
557+
Some(reg) => *reg,
558+
None => {
559+
let reg = self.user_state.compiler.alloc();
560+
self.user_state.outs_to_regs.insert(a_out, reg);
561+
reg
562+
}
563+
};
564+
let b = match self.user_state.outs_to_regs.get(&b_out) {
565+
Some(reg) => *reg,
566+
None => {
567+
let reg = self.user_state.compiler.alloc();
568+
self.user_state.outs_to_regs.insert(b_out, reg);
569+
reg
570+
}
571+
};
572+
573+
let out_id = out_ids.next().unwrap();
574+
let out = match self.user_state.outs_to_regs.get(&out_id) {
575+
Some(reg) => *reg,
576+
None => {
577+
let reg = self.user_state.compiler.alloc();
578+
self.user_state.outs_to_regs.insert(out_id, reg);
579+
reg
580+
}
581+
};
582+
583+
let gate = Nand { a, b, out };
584+
self.user_state.gates.insert(id, Gate::from(gate));
585+
}
487586

488587
// TODO: Implement
489588
NodeTempl::Immediate => {}
@@ -691,6 +790,30 @@ pub fn evaluate_node(
691790

692791
evaluator.output_scalar("out", value)
693792
}
793+
NodeTempl::Not => {
794+
let mut outs = node.output_ids();
795+
let out_id = outs.next().unwrap();
796+
797+
let value = if let Some(reg) = user_state.outs_to_regs.get(&out_id) {
798+
user_state.simulation.register(*reg)
799+
} else {
800+
false
801+
};
802+
803+
evaluator.output_scalar("out", !value)
804+
}
805+
NodeTempl::Nand => {
806+
let mut outs = node.output_ids();
807+
let out_id = outs.next().unwrap();
808+
809+
let value = if let Some(reg) = user_state.outs_to_regs.get(&out_id) {
810+
user_state.simulation.register(*reg)
811+
} else {
812+
false
813+
};
814+
815+
evaluator.output_scalar("out", !value)
816+
}
694817
NodeTempl::Immediate => {
695818
let a = evaluator.input_scalar("A", user_state)?;
696819
evaluator.output_scalar("out", a)

0 commit comments

Comments
 (0)