📄 circuit.cpp
字号:
t->d.lookUpTable.editAsString = 0;
AddLeaf(ELEM_LOOK_UP_TABLE, t);
}
void AddPiecewiseLinear(void)
{
if(!CanInsertEnd) return;
ElemLeaf *t = AllocLeaf();
strcpy(t->d.piecewiseLinear.dest, "yvar");
strcpy(t->d.piecewiseLinear.index, "xvar");
t->d.piecewiseLinear.count = 0;
AddLeaf(ELEM_PIECEWISE_LINEAR, t);
}
void AddMove(void)
{
if(!CanInsertEnd) return;
ElemLeaf *t = AllocLeaf();
strcpy(t->d.move.dest, "dest");
strcpy(t->d.move.src, "src");
AddLeaf(ELEM_MOVE, t);
}
void AddMath(int which)
{
if(!CanInsertEnd) return;
ElemLeaf *t = AllocLeaf();
strcpy(t->d.math.dest, "dest");
strcpy(t->d.math.op1, "src");
strcpy(t->d.math.op2, "1");
AddLeaf(which, t);
}
void AddCmp(int which)
{
if(!CanInsertOther) return;
ElemLeaf *t = AllocLeaf();
strcpy(t->d.cmp.op1, "var");
strcpy(t->d.cmp.op2, "1");
AddLeaf(which, t);
}
void AddCounter(int which)
{
if(which == ELEM_CTC) {
if(!CanInsertEnd) return;
} else {
if(!CanInsertOther) return;
}
ElemLeaf *t = AllocLeaf();
strcpy(t->d.counter.name, "Cnew");
t->d.counter.max = 0;
AddLeaf(which, t);
}
void AddReadAdc(void)
{
if(!CanInsertEnd) return;
ElemLeaf *t = AllocLeaf();
strcpy(t->d.readAdc.name, "Anew");
AddLeaf(ELEM_READ_ADC, t);
}
void AddSetPwm(void)
{
if(!CanInsertEnd) return;
ElemLeaf *t = AllocLeaf();
strcpy(t->d.setPwm.name, "duty_cycle");
t->d.setPwm.targetFreq = 1000;
AddLeaf(ELEM_SET_PWM, t);
}
void AddUart(int which)
{
if(!CanInsertOther) return;
ElemLeaf *t = AllocLeaf();
strcpy(t->d.uart.name, "char");
AddLeaf(which, t);
}
void AddPersist(void)
{
if(!CanInsertEnd) return;
ElemLeaf *t = AllocLeaf();
strcpy(t->d.persist.var, "saved");
AddLeaf(ELEM_PERSIST, t);
}
//-----------------------------------------------------------------------------
// Any subcircuit containing only one element should be collapsed into its
// parent. Call ourselves recursively to do this on every child of the passed
// subcircuit. The passed subcircuit will not be collapsed itself, so that
// the rung subcircuit may contain only one element as a special case. Returns
// TRUE if it or a child made any changes, and for completeness must be
// called iteratively on the root till it doesn't do anything.
//-----------------------------------------------------------------------------
static BOOL CollapseUnnecessarySubckts(int which, void *any)
{
BOOL modified = FALSE;
ok();
switch(which) {
case ELEM_SERIES_SUBCKT: {
ElemSubcktSeries *s = (ElemSubcktSeries *)any;
int i;
for(i = 0; i < s->count; i++) {
if(s->contents[i].which == ELEM_PARALLEL_SUBCKT) {
ElemSubcktParallel *p = s->contents[i].d.parallel;
if(p->count == 1) {
if(p->contents[0].which == ELEM_SERIES_SUBCKT) {
// merge the two series subcircuits
ElemSubcktSeries *s2 = p->contents[0].d.series;
int makeSpaces = s2->count - 1;
memmove(&s->contents[i+makeSpaces+1],
&s->contents[i+1],
(s->count - i - 1)*sizeof(s->contents[0]));
memcpy(&s->contents[i], &s2->contents[0],
(s2->count)*sizeof(s->contents[0]));
s->count += makeSpaces;
CheckFree(s2);
} else {
s->contents[i].which = p->contents[0].which;
s->contents[i].d.any = p->contents[0].d.any;
}
CheckFree(p);
modified = TRUE;
} else {
if(CollapseUnnecessarySubckts(ELEM_PARALLEL_SUBCKT,
s->contents[i].d.parallel))
{
modified = TRUE;
}
}
}
// else a leaf, not a problem
}
break;
}
case ELEM_PARALLEL_SUBCKT: {
ElemSubcktParallel *p = (ElemSubcktParallel *)any;
int i;
for(i = 0; i < p->count; i++) {
if(p->contents[i].which == ELEM_SERIES_SUBCKT) {
ElemSubcktSeries *s = p->contents[i].d.series;
if(s->count == 1) {
if(s->contents[0].which == ELEM_PARALLEL_SUBCKT) {
// merge the two parallel subcircuits
ElemSubcktParallel *p2 = s->contents[0].d.parallel;
int makeSpaces = p2->count - 1;
memmove(&p->contents[i+makeSpaces+1],
&p->contents[i+1],
(p->count - i - 1)*sizeof(p->contents[0]));
memcpy(&p->contents[i], &p2->contents[0],
(p2->count)*sizeof(p->contents[0]));
p->count += makeSpaces;
CheckFree(p2);
} else {
p->contents[i].which = s->contents[0].which;
p->contents[i].d.any = s->contents[0].d.any;
}
CheckFree(s);
modified = TRUE;
} else {
if(CollapseUnnecessarySubckts(ELEM_SERIES_SUBCKT,
p->contents[i].d.series))
{
modified = TRUE;
}
}
}
// else a leaf, not a problem
}
break;
}
default:
oops();
break;
}
ok();
return modified;
}
//-----------------------------------------------------------------------------
// Delete the selected leaf element from the circuit. Just pull it out of the
// subcircuit that it was in before, and don't worry about creating
// subcircuits with only one element; we will clean that up later in a second
// pass. Returns TRUE if it or a child (calls self recursively) found and
// removed the element.
//-----------------------------------------------------------------------------
static BOOL DeleteSelectedFromSubckt(int which, void *any)
{
ok();
switch(which) {
case ELEM_SERIES_SUBCKT: {
ElemSubcktSeries *s = (ElemSubcktSeries *)any;
int i;
for(i = 0; i < s->count; i++) {
if(s->contents[i].d.any == Selected) {
ForgetFromGrid(s->contents[i].d.any);
CheckFree(s->contents[i].d.any);
memmove(&s->contents[i], &s->contents[i+1],
(s->count - i - 1)*sizeof(s->contents[0]));
(s->count)--;
return TRUE;
}
if(s->contents[i].which == ELEM_PARALLEL_SUBCKT) {
if(DeleteSelectedFromSubckt(ELEM_PARALLEL_SUBCKT,
s->contents[i].d.any))
{
return TRUE;
}
}
}
break;
}
case ELEM_PARALLEL_SUBCKT: {
ElemSubcktParallel *p = (ElemSubcktParallel *)any;
int i;
for(i = 0; i < p->count; i++) {
if(p->contents[i].d.any == Selected) {
ForgetFromGrid(p->contents[i].d.any);
CheckFree(p->contents[i].d.any);
memmove(&p->contents[i], &p->contents[i+1],
(p->count - i - 1)*sizeof(p->contents[0]));
(p->count)--;
return TRUE;
}
if(p->contents[i].which == ELEM_SERIES_SUBCKT) {
if(DeleteSelectedFromSubckt(ELEM_SERIES_SUBCKT,
p->contents[i].d.any))
{
return TRUE;
}
}
}
break;
}
default:
oops();
break;
}
return FALSE;
}
//-----------------------------------------------------------------------------
// Delete the selected item from the program. Just call
// DeleteSelectedFromSubckt on every rung till we find it.
//-----------------------------------------------------------------------------
void DeleteSelectedFromProgram(void)
{
if(!Selected || Selected->selectedState == SELECTED_NONE) return;
int i = RungContainingSelected();
if(i < 0) return;
if(Prog.rungs[i]->count == 1 &&
Prog.rungs[i]->contents[0].which != ELEM_PARALLEL_SUBCKT)
{
Prog.rungs[i]->contents[0].which = ELEM_PLACEHOLDER;
SelectedWhich = ELEM_PLACEHOLDER;
Selected->selectedState = SELECTED_LEFT;
WhatCanWeDoFromCursorAndTopology();
return;
}
int gx, gy;
if(!FindSelected(&gx, &gy)) {
gx = 0;
gy = 0;
}
if(DeleteSelectedFromSubckt(ELEM_SERIES_SUBCKT, Prog.rungs[i])) {
while(CollapseUnnecessarySubckts(ELEM_SERIES_SUBCKT, Prog.rungs[i]))
;
WhatCanWeDoFromCursorAndTopology();
MoveCursorNear(gx, gy);
return;
}
}
//-----------------------------------------------------------------------------
// Free a circuit and all of its subcircuits. Calls self recursively to do
// so.
//-----------------------------------------------------------------------------
void FreeCircuit(int which, void *any)
{
ok();
switch(which) {
case ELEM_SERIES_SUBCKT: {
ElemSubcktSeries *s = (ElemSubcktSeries *)any;
int i;
for(i = 0; i < s->count; i++) {
FreeCircuit(s->contents[i].which, s->contents[i].d.any);
}
CheckFree(s);
break;
}
case ELEM_PARALLEL_SUBCKT: {
ElemSubcktParallel *p = (ElemSubcktParallel *)any;
int i;
for(i = 0; i < p->count; i++) {
FreeCircuit(p->contents[i].which, p->contents[i].d.any);
}
CheckFree(p);
break;
}
CASE_LEAF
ForgetFromGrid(any);
CheckFree(any);
break;
default:
oops();
break;
}
ok();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -