SCENARIO: Imagine you have an image and you want to go through every pixel (For y = 1 to height, and For x = 1 to width), but you want to be able to do a different operation to each pixel each time - perhaps fill each pixel a certain color, or invert every pixel etc, but you don't want to create different versions of the same large procedure where they only have one line different.
Lets say we have 5 operations to choose from. You might use something like this:
Code: Select all
Procedure ModifyAllPixels(Operation, width, height)
For y = 1 To height
For x = 1 To width
Select Operation
Case PIXELOP_FILL:
;DoFill
Case PIXELOP_ADD:
;DoAdd
Case PIXELOP_SUB:
;DoSub
Case PIXELOP_INVERT:
;DoInvert
Case PIXELOP_REPLACE:
;DoReplace
EndSelect
Next x
Next y
EndProcedure
But the WORST CASE scenario - it has to test all 5 case statements if it's the last one (PIXELOP_REPLACE). And that's for EVERY pixel so it could get really slow especially with more operations/case statements to test!
That's called O(somethingorrather)-time... or something.
Using a JUMP TABLE allows us to instead jump straight to the operation we want (best case scenario every time):
Code: Select all
Enumeration PIXELOPS 0 Step SizeOf(Integer)
#PIXELOP_REPLACE ;their values are 32bit-x86 (0,4,8..) or 64bit-x64 (0,8,16..) indexes
#PIXELOP_ADD
#PIXELOP_SUB
#PIXELOP_FILL
#PIXELOP_INVERT
#PIXELOPEND
EndEnumeration
Procedure ModifyAllPixels(Operation, width, height)
If Operation < 0 Or Operation => #PIXELOPEND: ProcedureReturn 0: EndIf ;ensure valid Operation index
Protected OpFunc = PeekI(?PIXELOP_JMPTABLE + Operation) ;the address of the specified PIXELOP_xxx label
For y = 1 To height
For x = 1 To width
! jmp dword [p.v_OpFunc] ;Jump to the specified Operation using the jump table. Change dword to qword on x64
;These can be in any order...
PIXELOP_FILL:
;DoFill
GOTO PixelOpEnd
PIXELOP_ADD:
;DoAdd
GOTO PixelOpEnd
PIXELOP_SUB:
;DoSub
GOTO PixelOpEnd
PIXELOP_INVERT:
;DoInvert
GOTO PixelOpEnd
PIXELOP_REPLACE:
;DoReplace
;GOTO PixelOpEnd ;not needed on last
PixelOpEnd:
Next x
Next y
DataSection ;the DataSection MUST be WITHIN the Procedure code for labels to be recognised by the compiler
PIXELOP_JMPTABLE: ;these MUST be listed in the same order as listed in Enumeration PIXELOPS
Data.i ?PIXELOP_REPLACE, ?PIXELOP_ADD, ?PIXELOP_SUB, ?PIXELOP_FILL, ?PIXELOP_INVERT ;addresses of labels
EndDataSection
EndProcedure