Callback With Static Class Interface in JRuby
Previously I had only experience of implementing java callbacks with instance interfaces, but in the PixelFlow library by Thomas Diewald he has created static java interfaces
in DWFluid2D.java
:-
The java interfaces
public void addCallback_FluiData(FluidData cb_fluid_data){
CB_fluid_data = cb_fluid_data;
}
public void addCallback_Advect(Advect cb_advect){
CB_advect = cb_advect;
}
static public interface FluidData{
public void update(DwFluid2D fluid);
}
static public interface Advect{
public void update(DwFluid2D fluid);
}
Implementing the FluidData interface in a JRubyArt sketch
See cb_fluid_data
lambda below
load_library :PixelFlow
java_import 'com.thomasdiewald.pixelflow.java.DwPixelFlow'
java_import 'com.thomasdiewald.pixelflow.java.fluid.DwFluid2D'
#
# PixelFlow | Copyright (C) 2016-17 Thomas Diewald - http://thomasdiewald.com
# Modified for JrubyArt by Martin Prout
# A Processing/Java library for high performance GPU-Computing (GLSL).
# MIT License: https://opensource.org/licenses/MIT
#
# Simple example that shows how to add Data (density, velocity) to the fluid.
#
# controls:
#
# LMB: add Density + Velocity
# MMB: add Velocity
# RMB: add Velocity
VIEWPORT_W = 1280
VIEWPORT_H = 720
VIEWPORT_X = 230
VIEWPORT_Y = 0
BACKGROUND_COLOR = 255
attr_reader :fluidgrid_scale, :fluid, :pg_fluid, :pg_obstacles, :context
def settings
size(VIEWPORT_W, VIEWPORT_H, P2D)
smooth(2)
end
def setup
surface.setLocation(VIEWPORT_X, VIEWPORT_Y)
# main library context
@context = DwPixelFlow.new(self)
context.print
context.printGL
# fluid simulation
@fluid = DwFluid2D.new(context, VIEWPORT_W, VIEWPORT_H, fluidgrid_scale)
cb_fluid_data = lambda do |obj| # obj required for signature (but unused)
if mouse_pressed?
vscale = 15
px = mouse_x
py = height - mouse_y
vx = (mouse_x - pmouse_x) * +vscale
vy = (mouse_y - pmouse_y) * -vscale
radius = 20
intensity = 1.0
temperature = 5.0
fluid.add_velocity(px, py, radius, vx, vy)
if mouse_button == LEFT
fluid.add_temperature(px, py, radius, temperature)
radius = 20
fluid.add_density(px, py, radius, 0, 0, 0, intensity)
radius = 16
fluid.add_density(px, py, radius, 0, 0.4, 1, intensity)
end
end
end
@fluidgrid_scale = 1
# set some simulation parameters
fluid.param.dissipation_density = 0.98
fluid.param.dissipation_velocity = 0.92
fluid.param.dissipation_temperature = 0.69
fluid.param.vorticity = 0.10
# interface for adding data to the fluid simulation
fluid.addCallback_FluiData(cb_fluid_data)
# pgraphics for fluid
@pg_fluid = create_graphics(VIEWPORT_W, VIEWPORT_H, P2D)
pg_fluid.smooth(4)
# pgraphics for obstacles
@pg_obstacles = create_graphics(VIEWPORT_W, VIEWPORT_H, P2D)
pg_obstacles.no_smooth
pg_obstacles.begin_draw
pg_obstacles.clear
# rand obstacles
pg_obstacles.rect_mode(CENTER)
pg_obstacles.no_stroke
pg_obstacles.fill(64)
srand(0)
80.times do
px = rand(width)
py = rand(height)
sx = rand(15..60)
sy = rand(15..60)
pg_obstacles.rect(px, py, sx, sy)
end
# border-obstacle
pg_obstacles.rect_mode(CORNER)
pg_obstacles.stroke_weight(20)
pg_obstacles.stroke(64)
pg_obstacles.no_fill
pg_obstacles.rect(0, 0, pg_obstacles.width, pg_obstacles.height)
pg_obstacles.end_draw
# add to the fluid-solver
fluid.add_obstacles(pg_obstacles)
frame_rate(60)
end
def draw
# update simulation
fluid.update
# clear render target
pg_fluid.begin_draw
pg_fluid.background(BACKGROUND_COLOR)
pg_fluid.end_draw
# render fluid stuff
fluid.render_fluid_textures(pg_fluid, 0)
# display
image(pg_fluid, 0, 0)
image(pg_obstacles, 0, 0)
# info
format_string = 'Fluid Minimal [size %d/%d] [frame %d] [fps: (%6.2f)]'
surface.set_title(format(format_string, fluid.fluid_w, fluid.fluid_h, fluid.simulation_step, frame_rate))
end