aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSan Jacobs2023-05-20 09:03:25 +0200
committerSan Jacobs2023-05-20 09:03:25 +0200
commit74ed85075819146fe9be4310bb709d80fa96c294 (patch)
treed44e2e8b6c86b5b4f015dc1507d91f5794905b91 /src
parent46fdf2827e80e1dab0efd7173c9f518af8e38831 (diff)
downloadsatscalc-74ed85075819146fe9be4310bb709d80fa96c294.tar.gz
satscalc-74ed85075819146fe9be4310bb709d80fa96c294.tar.bz2
satscalc-74ed85075819146fe9be4310bb709d80fa96c294.zip
Implemented lunch() like a boss
The lunch() function was pretty broken in v0.2.0-alpha, so a long lunch would cause all sorts of problems. Not anymore, friends!
Diffstat (limited to 'src')
-rw-r--r--src/main.odin19
-rw-r--r--src/time.odin115
2 files changed, 122 insertions, 12 deletions
diff --git a/src/main.odin b/src/main.odin
index 89ff39e..d64d5e3 100644
--- a/src/main.odin
+++ b/src/main.odin
@@ -4,12 +4,23 @@ import "core:fmt"
main :: proc() {
//test()
- new_workday({10, 22, 1, 5, 2023},
- {00, 08, 5, 5, 2023},
- {00, 05, 6, 5, 2023},
- {30, 21, 5, 5, 2023})
+ workday: = new_workday({10, 22, 4, 5, 2023},
+ {00, 08, 5, 5, 2023},
+ {00, 05, 6, 5, 2023},
+ {30, 21, 5, 5, 2023})
+ //lunch(&workday, {00, 16, 5, 5, 2023}, {00, 17, 5, 5, 2023})
+ lunch(&workday, {00, 12, 5, 5, 2023}, {45, 22, 5, 5, 2023})
+ //lunch(&workday, {00, 12, 5, 5, 2023}, {30, 12, 5, 5, 2023})
+ //lunch(&workday, {30, 16, 5, 5, 2023}, {30, 17, 5, 5, 2023})
+ //lunch(&workday, {30, 19, 5, 5, 2023}, {30, 22, 5, 5, 2023})
+ for each_block, i in workday.blocks {
+ fmt.printf("Block %2i: %s $f: %i%% %s\n", i+1, toString(each_block), int((each_block.value-1)*100), each_block.reason)
+ }
}
+// TODO: Separate tests into different procedures
+// TODO: Write dedicated tests for lunch
+
test :: proc() {
fmt.println("\n--- TESTING PRINT STUFFS ---")
diff --git a/src/time.odin b/src/time.odin
index d5fec73..a3e4b3b 100644
--- a/src/time.odin
+++ b/src/time.odin
@@ -46,8 +46,11 @@ Workday :: struct {
call : Moment,
wrap : Moment,
planned_wrap : Moment,
-
- blocks : [12]Timeblock,
+
+ // blocks is over 12,
+ // because lunch breaks
+ // cause more blocks
+ blocks : [16]Timeblock,
total_timeblocks : int,
}
@@ -180,15 +183,85 @@ new_workday :: proc(previous_wrap : Moment,
}
lunch :: proc(workday: ^Workday, lunch_start: Moment, lunch_end: Moment) {
- // TODO: Implement lunch!
+
//
- // This version of lunch needs to fix the issue where when lunch spans multiple Timeblocks,
- // it would... not act like a proper adult.
+ // This basically cuts out part of the workday
//
// |-------|---|-------|----|---------|--------------|
// |--lunch--|
// |-------|---|----| |-------|--------------|
- // This ^ must work!
+ // This ^ works now!
+
+ if lunch_start == lunch_end do return
+ assert(less(lunch_start, lunch_end), "ERROR: Bad Lunch! Lunch ends before it starts")
+
+ start_index: int
+ end_index: int
+ for block, i in workday.blocks {
+ if (great(lunch_start, block.start) && less(lunch_start, block.end)) || (block.start == lunch_start) {
+ start_index = i
+ }
+ if (great(lunch_end, block.start) && less(lunch_end, block.end)) || (block.end == lunch_end) {
+ end_index = i
+ }
+ }
+
+ assert(start_index <= end_index, "ERROR: Bad Lunch! start_index greater than end_index")
+
+ span: int = end_index - start_index
+
+ // TODO: This is bad and can definitely be simplified and done in a more principled way
+ // But right now it works perfectly, and is much better than it used to be in the C++ version
+ switch span {
+ case 0:
+ fmt.println("Start and end are in the same block")
+ switch {
+ case (lunch_start == workday.blocks[start_index].start) && (lunch_end == workday.blocks[end_index].end):
+ popBlock(workday, start_index)
+ case lunch_start == workday.blocks[start_index].start:
+ workday.blocks[start_index].start = lunch_end
+ case lunch_end == workday.blocks[end_index].end:
+ workday.blocks[end_index].end = lunch_start
+ case:
+ growBlocks(workday, start_index)
+ end_index += 1
+ workday.blocks[start_index].end = lunch_start
+ workday.blocks[end_index].start = lunch_end
+ }
+
+ case 1:
+ fmt.println("Start and end span one gap")
+ switch {
+ case (lunch_start == workday.blocks[start_index].start) && (lunch_end == workday.blocks[end_index].end):
+ popBlock(workday, start_index, 2)
+ case lunch_start == workday.blocks[start_index].start:
+ workday.blocks[end_index].start = lunch_end
+ popBlock(workday, start_index)
+ case lunch_end == workday.blocks[end_index].end:
+ workday.blocks[start_index].end = lunch_start
+ popBlock(workday, end_index)
+ case:
+ workday.blocks[end_index].start = lunch_end
+ workday.blocks[start_index].end = lunch_start
+ }
+
+ case 2..=len(workday.blocks):
+ fmt.println("Start and end span more than one gap")
+ switch {
+ case (lunch_start == workday.blocks[start_index].start) && (lunch_end == workday.blocks[end_index].end):
+ popBlock(workday, start_index, span+1)
+ case lunch_start == workday.blocks[start_index].start:
+ workday.blocks[end_index].start = lunch_end
+ popBlock(workday, start_index, span)
+ case lunch_end == workday.blocks[end_index].end:
+ workday.blocks[start_index].end = lunch_start
+ popBlock(workday, start_index+1, span)
+ case:
+ workday.blocks[end_index].start = lunch_end
+ workday.blocks[start_index].end = lunch_start
+ popBlock(workday, start_index+1, span-1)
+ }
+ }
}
windIndividual :: proc(input_moment: ^Moment,
@@ -244,12 +317,12 @@ windIndividual :: proc(input_moment: ^Moment,
return
}
-windDelta :: proc(moment: ^Moment, delta: Delta) {
+windByDelta :: proc(moment: ^Moment, delta: Delta) {
using delta
wind(moment, minutes, hours, days)
return
}
-wind :: proc{windIndividual, windDelta}
+wind :: proc{windIndividual, windByDelta}
timesplit :: proc(block: Timeblock, splitpoint: Moment) -> (first_half: Timeblock, second_half: Timeblock) {
// Splits a timeblock at splitpoint.
@@ -514,6 +587,32 @@ clockprintTimeblock :: proc(block: Timeblock) -> string {
}
timeprint :: proc{clockprintTimeblock, clockprintMoment}
+popBlock :: proc(workday: ^Workday, index: int, count: int = 1) {
+ using workday
+ when ODIN_DEBUG do fmt.printf("popBlock() running to remove %i block(s) from index %i\n", count, index)
+ for i in index..<len(blocks)-count {
+ when ODIN_DEBUG do fmt.printf("Putting the contents of %i/%i into %i\n", i+count, len(blocks)-1, i)
+ blocks[i] = blocks[i+count]
+ }
+ for i in len(blocks)-count-1..<len(blocks) {
+ blocks[i] = {{0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, 0, ""}
+ }
+ total_timeblocks -= count
+}
+
+growBlocks :: proc(workday: ^Workday, index: int, count: int = 1) {
+ using workday
+ fmt.printf("growBlocks() running to make space for %i block(s) at index %i\n", count, index)
+ for i: int = len(blocks)-1-count; i>=index; i-=1 {
+ fmt.printf("Putting the contents of %i/%i into %i\n", i+count, len(blocks)-1, i)
+ blocks[i+count] = blocks[i]
+ }
+ //for i in index..<index+count {
+ // blocks[i] = {{0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, 0, ""}
+ //}
+ total_timeblocks += count
+}
+
days_in :: proc(month: int, year: int) -> int {
switch month {
case 1: