Extracting draw() method on a separate loop (PApplet as a JADE Agent) - java

I am creating a JADE-based agent system on Java, and I want to use Processing for visualizing these agents. Now the JADE framework runs on it's own, and a Processing PApplet is instantiated as one of the agents, which is a singleton.
Every time one of the (other types of) agents change, they call the redraw() method of the PApplet. The problem is, the PApplet doesn't call it's draw() method, since it's not running on it's own thread.
How do I fix this?
EDIT:
public class Manager extends Agent{
//The Agent object that runs as a separate thread under JADE framework.
protected void setup(){
...
javax.swing.SwingUtilities.invokeLater(new VisualizerThreadRunnable(this));
...
}
}
class VisualizerThreadRunnable implements Runnable {
public VisualizerThreadRunnable(Manager m){
...
}
public void run(){
System.out.println("visualizer being launched...");
Visualizer visualizer = new Visualizer(manager);
visualizer.setVisible(true);
}
}
public class Visualizer extends PApplet {
//from examples on http://processing.org/tutorials/eclipse/
public Visualizer(Manager m){
this.m = m;
...
}
public void setup() {
size(200,200);
background(0);
}
public void draw() {
stroke(255);
if (mousePressed) {
line(mouseX,mouseY,pmouseX,pmouseY);
}
}
}

In the visualizer thread you also need to initialize the PApplet using init():
public void run(){
System.out.println("visualizer being launched...");
Visualizer visualizer = new Visualizer(manager);
visualizer.init();//This is pretty important
visualizer.setVisible(true);
}
For more information checkout PApplet's javadocs.
This should solve the Processing side of the problem. I've never used Jade before,
so I don't know if the thread will stay on. Do check if that happens, if not maybe you should keep that thread running.

Related

Running code x ticks after opening an inventory (Minecraft spigot)

I have heard of ways to run code later like run task later and other scheduler methods but I want to do it inside of an event which I am having trouble with. Here is some code for an example of where I want to run it:
public class InventoryEvents implements Listener {
#EventHandler
public void onOpen(InventoryOpenEvent e) {
// Run later code here
}
}
When I try using code for something like run task later here or outside of it or even in another class I get a lot of errors relating to the class not extending JavaPlugin or me trying to use it in an event.
Any help is appreciated, thanks :)
You will need to create your scheduled task inside the onOpen method that's handling the InventoryOpenEvent.
Bukkit.getScheduler().runTaskLater(main, new Runnable() {
#Override
public void run() {
//Run your delayed code in here
}
}, 100L);//replace 100 with how many ticks you want to wait before the code executes
The main is where your errors are coming from. You need to use an instance of whatever class extends JavaPlugin (this would be your main class). I recommend passing the instance of your main into the Listener class in the constructor so you can use it as needed. An example would be as follows:
public class NamedListener implements Listener {
private Main main;
public NamedListener(Main main){
this.main = main;
}
}

Several threads for run render in Android 3D game. Thread-safe?

For a long time I tried to make smooth animation for the application. And I got this solution: several threads launch draw frame of SceneRenderer:
public class OGLView extends GLSurfaceView {
public void init(Context context, int versionGLES) {
...
renderer = new SceneRenderer(context, versionGLES);
setRenderer(renderer);
...
}
}
public class SurfaceRunnable implements Runnable {
...
#Override
public void run() {
while(true) {
surfaceView.requestRender(); // draw frame
if (Thread.currentThread().isInterrupted()) break;
}
}
}
public class SurfaceExecutor implements Executor {
private List<Thread> threads = new ArrayList<>();
#Override
public void execute(#NonNull Runnable runnable) {
Thread thread = new Thread(runnable);
thread.setPriority(10);
thread.start();
threads.add(thread);
}
...
}
public class GameActivity extends AppCompatActivity {
private SurfaceExecutor executor = new SurfaceExecutor();
#Override
protected void onResume() {
...
SurfaceRunnable sr = new SurfaceRunnable(oglView);
/* run four threads for SceneRender */
executor.execute(sr);
executor.execute(sr);
executor.execute(sr);
executor.execute(sr);
...
}
}
As a result, the animation has become smoother. Long testing of the application did not lead to errors. Testing on different device configurations did not detect changes in the animation rate. Question: How much is this approach thread safe? All drawing and operations with matrices are done in SceneRenderer. Thank you all. Please, excuse my English.
Without a complete application it's impossible to say whether this is safe or not, as that entirely depends on what those 4 threads are doing and what resources are shared across them.
In all honesty though, this looks like a nasty hack. All 4 threads seem to be doing the same thing, any any fix of "just run 4 copies of the same thing and hope" seems to be running better by luck rather than any particular intentional design benefit.

How do you get event notifications back to the main program class of a Java console app?

I'm coming to Java from C#, and I'm really just trying to figure out how to do things in Java world. I'm running Java 8 in IntelliJ IDEA. I found this explaining events in Java as basically being hand-made through manual registration and an interface method call. The code example has enough problems that I assume it was never compiled. After cleaning that up a bit I have this:
Interface MetronomeEvent:
public interface MetronomeEvent {
void Tick(Date tickDate);
}
Class EventFiringSource:
public class EventFiringSource {
// Our collection of classes that are subscribed as listeners of our
protected List<MetronomeEvent> _listeners=new ArrayList();
// Method for listener classes to register themselves
public void addMetronomeEventListener(MetronomeEvent listener)
{
_listeners.add(listener);
}
// "fires" the event
protected void fireMetronomeEvent()
{
if (_listeners != null && !_listeners.isEmpty())
{
for (MetronomeEvent e:_listeners)
{
e.Tick(new Date());
}
}
}
public void Start()
{
fireMetronomeEvent();
}
}
Main console application:
public class MainApp implements MetronomeEvent {
public static void main(String[] args) {
EventFiringSource source = new EventFiringSource();
source.addMetronomeEventListener(this); // Adds itself as a listener for the event
source.Start();
}
public void Tick(Date tickDate)
{
System.out.println(tickDate.toString());
}
}
The one remaining error is source.addMetronomeEventListener(this); where the compiler complains that it cannot reference MyApp.this from a static context. That makes sense, but I don't see any way then that I could, after implementing the MetronomeEvent interface on the main program class, actually pass it to source.addMetronomeEventListener() for registration. Is it impossible to directly register the main program class for events? Am I supposed to create and register a Listener class that implements MetronomeEvent and will act on behalf of the main application? Like this?
public class Listener implements MetronomeEvent {
public void Tick(Date tickDate){
System.out.println(tickDate.toString());
}
}
And then:
public static void main(String[] args) {
EventFiringSource source = new EventFiringSource();
Listener l=new Listener();
source.addMetronomeEventListener(l); // Adds another object to listen on behalf of main()
source.Start();
}
This is not about events, it's about main() and static methods in general.
I would suggest writing your main() as
public static void main(String[] args) {
new MainApp(args).execute();
}
This way you're immediately jumping from static function world into object-oriented world.
Based on Vince Emigh's comment/answer I was led to this Oracle doc on lamda expressions and to this one on method references. I've found 3 ways to do this so far.
1) Anonymous class:
source.addMetronomeEventListener(
new MetronomeEvent() {
#Override
public void Tick(Date tickDate) {
System.out.println("anonymous class:");
System.out.println(tickDate.toString());
}
}
); // Adds itself as a listener for the event
2) Lambda expression:
source.addMetronomeEventListener(d -> System.out.println("lambda:\n"+d.toString()));
3) Method reference, which is the closest to what I am accustomed to. A method is defined in the main class:
public static void processTick(Date tickDate){
System.out.println("method reference:");
System.out.println(tickDate.toString());
}
...and then in the body of main() it is added as an event handler like this:
source.addMetronomeEventListener(MainApp::processTick);

Java new Thread using this - Any reason if it is good / bad?

Just a quick question look at the code below, is there any reason why wouldn't do this or is it fine?
public class MyClass implements Runnable, MyClassInterface {
Thread threader;
void start() {
threader = new Thread(this);
threader.start();
}
#Override
public void run() {
Thread current = Thread.getCurrentThread();
while (threader = current) {
..
}
}
}
The original logic was not to expose that fact it runs in a separate thread to the caller
who creates a "MyClass" but then there are doubts if that is a good thing or bad.
Can anyone see any good reason not to do it or is it acceptable. It can be expected that MyClass.start() maybe called a few times.
EDIT: Updated the code to show it is implementing Runnable and one other interface, the interface is used by client code, the actual implementation may run in a separate thread, same thread or any other way. The idea was to abstract that away from the client, as the client is simply an object that "MyClass" will notify and is not aware (currently) of the Runnable interface it implements.
Perhaps that abstraction is not needed and client should have more control?
EDIT: The start() was simply to tell the object it is ready to start receiving notifications rather than start a thread.
Have a look at this: http://docs.oracle.com/javase/8/docs/technotes/guides/concurrency/threadPrimitiveDeprecation.html
In my opinion, it is a bad design, because you are breaking encapsulation by implementing an interface (Runnable) and by providing a public method (run) that are of no use of the consumer of the class.
You can start a thread from the start method without inhering from Runnable:
public class MyClass {
private Thread thread;
public void start() {
thread = new Thread(this::doWork); // Java 8 method reference
thread.start();
}
private void doWork() {
// ...
}
}
If you can't use method references from Java 8, replace this::doWork with:
new Runnable() { public void run() { doWork(); } }

ThreadFactory and newThread(Runnable r) how to access to the attributes of r if it is a Thread?

For my thesis I'm working on a Discrete Event System Simulator. The simulation consists in a set of SimulatorThread extends Thread whose action consist in scheduling Events to the Simulator. Each SimulatorThread interracts with the Simulator through the SimulatorInterface.
public abstract class SimulatorThread extends Thread {
private SimulatorInterface si;
public SimulatorThread(SimulatorInterface si) {
this.si = si;
}
...
}
public final class Simulator {
private ExecutorService exec;
...
public void assignThread(SimulatorThread... stList) {
...
}
}
Before the simulation begins, each SimulatorThread is assigned to the Simulator, then the Simulator will execute each thread through exec.execute(simulatorThread). My problem is that in some part of the code i need to get a reference to the current running SimulatorThread, but the instruction (SimulatorThread) Thread.currentThread() gives a cast execption. Infact the output of System.out.print(Thread.currentThread().getClass()) is class java.lang.Thread, but I would like that the output is class SimulatorThread which can be obtained by running the thread using the instruction simulatorThread.start() instead of using the executor. So I thought that the problem is in writing an ad-hoc ThreadFactory that return an instance of SimulatorThread.
Infact I tried to use the trivial SimulatorThreadFactory extends ThreadFactory:
public class SimulatorThreadFactory implements ThreadFactory {
#Override
public Thread newThread(Runnable r) {
return new SimulatorThread(new SimulatorInterface());
}
}
and with this I obtained the previously cited output 'class SimulatorThread'. The problem is that when I call 'exec.execute(simulatorThread)', the parameter has an attribute 'SimulatorInterface' to which I need to get access, but I can't becaues the parameter of the method 'newThread' is a 'Runnable'. I expose here a wrong code that I hope expresses what I mean better than how I explain in words:
public class SimulatorThreadFactory implements ThreadFactory {
#Override
public Thread newThread(Runnable r) {
SimulatorInterface si = r.getSimulatorInterface(); // this is what
// I would like
// the thread factory
// to do
return new SimulatorThread(si);
}
}
So, how can I access to attribute 'SimulatorInterface' of the 'SimulatorThread' inside the method newThread in order to create a SimulatorThread if its paramater is a Runnable?
If I understand your needs, the right way to do this is to not extend Thread but to implement Runnable. Then all of the benefits of your own class hierarchy can be enjoyed:
public abstract class SimulatorRunnable extends Runnable {
protected SimulatorInterface si;
public SimulatorRunnable(SimulatorInterface si) {
this.si = si;
}
}
public final class Simulator extends SimulatorRunnable {
public Simulator(SimulatorInterface si) {
super(si);
}
public void run() {
// here you can use the si
si.simulate(...);
}
}
Then you submit your simulator to your thread-pool:
Simulator simulator = new Simulator(si);
...
exec.submit(simulator);
My problem is that in some part of the code i need to get a reference to the current running SimulatorThread, but the instruction (SimulatorThread) Thread.currentThread() gives a cast execption
You should not be passing a Thread into an ExecutorService. It is just using it as a Runnable (since Thread implements Runnable) and the thread-pool starts its' own threads and will never call start() on your SimulatorThread. If you are extending Thread then you need to call thread.start() directly and not submit it to an ExecutorService. The above pattern of implements Runnable with an ExecutorService is better.
#Gray's answer is correct, pointing out that the ExecutorService is designed to use its own threads to execute your Runnables, and sometimes created threads will even be reused to run different Runnables.
Trying to get information from (SimulatorThread) Thread.currentThread() smells like a 'global variable' anti-pattern. Better to pass the 'si' variable along in method calls.
If you really want global variables that are thread-safe, use ThreadLocals:
public final class Simulator extends SimulatorRunnable {
public static final ThreadLocal<SimulatorInterface> currentSim = new ThreadLocal<>();
public Simulator(SimulatorInterface si) {
super(si);
}
public void run() {
currentSim.set(si)
try{
doStuff();
}
finally{
currentSim.unset();
}
}
private void doStuff()
{
SimulatorInterface si = Simulator.currentSim.get();
//....
}
}

Categories