aboutsummaryrefslogtreecommitdiff
path: root/site/udo/twigs/checkpointing.udo
diff options
context:
space:
mode:
Diffstat (limited to 'site/udo/twigs/checkpointing.udo')
-rwxr-xr-xsite/udo/twigs/checkpointing.udo120
1 files changed, 120 insertions, 0 deletions
diff --git a/site/udo/twigs/checkpointing.udo b/site/udo/twigs/checkpointing.udo
new file mode 100755
index 0000000..bd2594e
--- /dev/null
+++ b/site/udo/twigs/checkpointing.udo
@@ -0,0 +1,120 @@
+#ifndef UDO_TWIGS_CHECKPOINTING
+#define UDO_TWIGS_CHECKPOINTING ##
+
+gitwgs_maxundolevels = 32
+gitwgs_checkpoints[] init gitwgs_maxundolevels
+gitwgs_checkpointstate = 0
+gitwgs_checkpointencodemult = 10000
+
+
+opcode twgs_checkpoint_encode, i, ii
+ ifnL, ifnR xin
+ iencoded = (ifnL * gitwgs_checkpointencodemult) + (ifnR / gitwgs_checkpointencodemult)
+ xout iencoded
+endop
+
+opcode twgs_checkpoint_decode, ii, i
+ iencoded xin
+ ifnL = int(iencoded) / gitwgs_checkpointencodemult
+ ifnR = frac(iencoded) * gitwgs_checkpointencodemult
+ xout ifnL, ifnR
+endop
+
+opcode twgs_checkpoint_clear, 0, 0
+ icheckpointnumber = gitwgs_checkpointstate
+ while (icheckpointnumber >= 0) do
+ ifnL, ifnR twgs_checkpoint_decode gitwgs_checkpoints[icheckpointnumber]
+ if (ifnL > 0 && ftexists(ifnL) == 1) then
+ tpvf_destroy ifnL
+ endif
+ if (ifnR > 0 && ftexists(ifnR) == 1) then
+ tpvf_destroy ifnR
+ endif
+ icheckpointnumber -= 1
+ od
+ gitwgs_checkpointstate = 0
+endop
+
+opcode twgs_checkpoint, 0, 0
+ imaxundo chnget "twgs_maxundo"
+ imaxundo = (imaxundo == -1) ? gitwgs_maxundolevels : imaxundo
+ if (imaxundo == 0 || imaxundo > gitwgs_maxundolevels) then
+ goto complete
+ endif
+
+ icheckpointnumber = gitwgs_checkpointstate
+ if (icheckpointnumber >= imaxundo) then
+ ifnL, ifnR twgs_checkpoint_decode gitwgs_checkpoints[0]
+ if (ifnL > 0 && ftexists(ifnL) == 1) then
+ tpvf_destroy ifnL
+ endif
+ if (ifnR > 0 && ftexists(ifnR) == 1) then
+ tpvf_destroy ifnR
+ endif
+ index = 1
+ itemp[] = gitwgs_checkpoints
+ while (index <= imaxundo) do
+ gitwgs_checkpoints[index - 1] = itemp[index]
+ index += 1
+ od
+ gitwgs_checkpointstate = icheckpointnumber ;- 1
+ else
+ gitwgs_checkpointstate = icheckpointnumber + 1
+ endif
+
+ ifnL = gitwgs_tpvfHandleL
+ ifnR = gitwgs_tpvfHandleR
+
+ ifnCheckpointL tpvf_clone ifnL
+print ifnCheckpointL
+ if (ifnR > 0) then
+ ifnCheckpointR tpvf_clone ifnR
+ else
+ ifnCheckpointR = 0
+ endif
+
+ iencoded twgs_checkpoint_encode ifnCheckpointL, ifnCheckpointR
+ gitwgs_checkpoints[icheckpointnumber] = iencoded
+
+complete:
+endop
+
+opcode twgs_undo, i, p
+ iapplyundo xin
+
+ icheckpointnumber = gitwgs_checkpointstate
+
+ icheckpointnumber -= 1
+ if (icheckpointnumber < 0) then
+ istatus = -1
+ goto complete
+ endif
+
+ gitwgs_checkpointstate = icheckpointnumber
+ ifnL, ifnR twgs_checkpoint_decode gitwgs_checkpoints[icheckpointnumber]
+
+ if (iapplyundo == 1) then ; apply or just step back and forget
+ if (ifnL > 0 && ftexists(ifnL) = 1) then
+ tpvf_destroy gitwgs_tpvfHandleL
+ gitwgs_tpvfHandleL = ifnL
+ endif
+ if (ifnR > 0 && ftexists(ifnR) == 1) then
+ tpvf_destroy gitwgs_tpvfHandleR
+ gitwgs_tpvfHandleR = ifnR
+ endif
+ else
+ if (ifnL > 0 && ftexists(ifnL) = 1) then
+ tpvf_destroy ifnL
+ endif
+ if (ifnL > 0 && ftexists(ifnR) = 1) then
+ tpvf_destroy ifnR
+ endif
+ endif
+
+ istatus = 1
+
+complete:
+ xout istatus
+endop
+
+#end