Skip to content

Instantly share code, notes, and snippets.

@Vaguery
Created May 12, 2010 19:54
Show Gist options
  • Select an option

  • Save Vaguery/399057 to your computer and use it in GitHub Desktop.

Select an option

Save Vaguery/399057 to your computer and use it in GitHub Desktop.
# class name MUST match /[AnythingCamelCased]Instruction/
class MyNewNudgeInstruction < Instruction
# preconditions? should return true if everything works
#
# use the #needs method for simple argument requirements checking:
# test will pass if there are at least that many items on the named stack(s)
def preconditions?
needs :foo, 2
needs :bar, 1
end
# use #setup to pop arguments from the stacks or gather them
# from the environment more generally
# (we won't reach here anyway if we don't pass #preconditions?)
# convenience methods include:
# #pop_value(stack_name) -> pop an item AND return its #value attribute
# #pop(stack_name) -> pop an item
# #peek_value(stack_name)-> peek at the top item AND return its #value attribute
# #peek (stack_name) -> peek at the top item
# #depth(stack_name)
# the values will be returned by way of [NudgeType].from_string, so for example
# peek_value(:int) -> an integer, not a string
def setup
@arg3 = @context.pop_value(:foo)
@arg2 = @context.pop_value(:foo)
@arg1 = @context.pop_value(:bar)
# remember the convention here is that the original CODE read like "1 2 divide", so
# the first argument was pushed before the second one
end
# use #derive to build the values or set up whatever else you need to determine what to do;
# if you need to create new Interpreter instances, or access file storage, or
# invoke external scripts, this is where to do it
#
# remember that you are going to be building a ValuePoint object, not the actual result
# of your calculations
#
# Exceptions raised by instruction execution are by convention converted into ValuePoints
# of type :error and pushed to that stack (by the Interpreter's error catching methods)
#
# a few include NotEnoughStackItems (raised when #needs fails), InstructionMethodError (for
# complex failures that might come up, like trying to change the value of a variable),
# NaNResultError (for the obvious math errors like div0 and float overflow),
# MissingInstructionError (in case your instruction calls another, and it's not defined),
# CodeOversizeError (used to enforce a Push3 rule which makes sense). Add your own!
def derive
input_image = GetFromHardDrive(@arg1)
mask = MyFancyLibrary.to_mask(@arg2)
alpha = MyFancyLibrary.alphaize(@arg3)
begin
munged = MyFancyLibrary.munge_now!(input_image, mask, ginger=alpha)
rescue LibraryFuckupError => e
raise InstructionMethodError, "#{self.class} had a foobie bletch"
end
@result1 = ValuePoint.new(:bar, munged)
@result2 = ValuePoint.new(:foo, munged.width)
end
# #cleanup is when stuff is actually written to the stacks
#
# don't be worried about exception handling; stacks are created on demand
# and nobody ever checks the values you push unless another Instruction
# pops them and tries to read what they are
#
# use the #pushes convenience method for the obvious thing
def cleanup
pushes :bar, @result1
pushes :foo, @result2
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment