How to fix boolean-methods "unexpected token: boolean/void" in Processing - java

I try to create a Class in Processing,
it includes 3 bool´s, and I want to make a getter, setter, resp. a method which changes the boolean to the other value.
That´s it.
My Code is following:
public class Color_high_low {
private boolean r_higher = true;
private boolean g_higher = true;
private boolean b_higher = true;
Color_high_low() {
r_higher = true;
g_higher = true;
b_higher = true;
}
//Getter
{
boolean get_r_h() {
return r_higher;
}
boolean get_g_h() {
return this.r_higher;
}
boolean get_b_h() {
return this.r_higher;
}
}
//Changer
{
void change_r_h() {
if (r_higher == true) {
r_higher = false;
} else {
r_higher = true;
}
return;
}
void change_g_h() {
if (g_higher == true) {
g_higher = false;
} else {
g_higher = true;
}
return;
}
void change_b_h() {
if (b_higher == true) {
b_higher = false;
} else {
b_higher = true;
}
return;
}
}
//Setter
{
void set_r_h(boolean be_or_not_to_be) {
r_higher = be_or_not_to_be;
return;
}
void set_g_h(boolean be_or_not_to_be) {
g_higher = be_or_not_to_be;
return;
}
void set_b_h(boolean be_or_not_to_be) {
b_higher = be_or_not_to_be;
return;
}
}
}
At the moment I get compile errors by the Return-Types of my methods, but I don´t know why. Do you have ideas?
Answers would be a pleasure!
Compile errors at the moment:
unexpected token: boolean
unexpected token: void

Don´t put methods in extra backets {} for grouping!

Related

How to check if string-number with decimals is double or integer?

I'm reading values from a .csv file and there are numbers in which are stored in the format #.##, i.e. the number 4 is stored as 4.00.
Now I need to check if the nuber is an integer or a double value. Depending on the type I need to format the string in the right way.
I made two checks to validate the value but it never passes the integer-check.
public static boolean isInteger(String s) {
try {
Integer.parseInt(s);
} catch (NumberFormatException | NullPointerException e) {
return false;
}
// only got here if we didn't return false
return true;
}
public static boolean isDecimal(String s) {
try {
Double.parseDouble(s);
} catch (NumberFormatException | NullPointerException e) {
return false;
}
// only got here if we didn't return false
return true;
}
Is there a easy way how I can check this?
I would do something like this:
public boolean isInteger(String s) {
boolean result;
try {
double d = Double.parseDouble(s);
if ((d == Math.floor(d)) && !Double.isInfinite(d)) {
result = true;
}
} catch (NumberFormatException e) {
result = false;
}
return result;
}
public boolean isDecimal(String s) {
boolean result;
try {
double d = Double.parseDouble(s);
if (d != Math.floor(d)) {
result = true;
}
} catch (NumberFormatException e) {
result = false;
}
return result;
}
Try this:
private static boolean isInteger(String s) {
return Double.parseDouble(s) % 1 == 0;
}

Java - Error Cannot cast from HashBasedTable<Object,Object,Object> to Table<UUID,PotionEffectType,PotionEffect>

I'm having this errors:
1) Cannot cast from HashBasedTable to Table .
This is the code in error: In the line:
this.restores = **(Table<UUID, PotionEffectType, PotionEffect>)HashBasedTable.create()**;
2) The method put(UUID, PotionEffectType, PotionEffect) in the type Table is not applicable for the arguments (Object, Object, Object)
This is the code in error: In the line:
this.restores.**put**((Object)player.getUniqueId(), (Object)active.getType(), (Object)active);
public class MageRestorer implements Listener
{
private final Table<UUID, PotionEffectType, PotionEffect> restores;
public MageRestorer(final HCF plugin) {
this.restores = (Table<UUID, PotionEffectType, PotionEffect>)HashBasedTable.create();
plugin.getServer().getPluginManager().registerEvents((Listener)this, (Plugin)plugin);
}
#EventHandler(ignoreCancelled = true, priority = EventPriority.MONITOR)
public void onPvpClassUnequip(final PvpClassUnequipEvent event) {
this.restores.rowKeySet().remove(event.getPlayer().getUniqueId());
}
public void setRestoreEffect(final Player player, final PotionEffect effect) {
boolean shouldCancel = true;
final Collection<PotionEffect> activeList = (Collection<PotionEffect>)player.getActivePotionEffects();
for (final PotionEffect active : activeList) {
if (active.getType().equals((Object)effect.getType())) {
if (effect.getAmplifier() < active.getAmplifier()) {
return;
}
if (effect.getAmplifier() == active.getAmplifier() && effect.getDuration() < active.getDuration()) {
return;
}
this.restores.put((Object)player.getUniqueId(), (Object)active.getType(), (Object)active);
shouldCancel = false;
}
}
player.addPotionEffect(effect, true);
if (shouldCancel && effect.getDuration() > 100 && effect.getDuration() < MageClass.DEFAULT_MAX_DURATION) {
this.restores.remove((Object)player.getUniqueId(), (Object)effect.getType());
}
}
#EventHandler(ignoreCancelled = true, priority = EventPriority.MONITOR)
public void onPotionEffectExpire(final PotionEffectExpiresEvent event) {
final LivingEntity livingEntity = event.getEntity();
if (livingEntity instanceof Player) {
final Player player = (Player)livingEntity;
final PotionEffect previous = (PotionEffect)this.restores.remove((Object)player.getUniqueId(), (Object)event.getEffect().getType());
if (previous != null) {
new BukkitRunnable() {
public void run() {
player.addPotionEffect(previous, true);
}
}.runTask((Plugin)HCF.getPlugin());
}
}
}
}
I dont know fix this. This is a clase of bukkit
For the first error, can we see the stack trace? Also, why do you need to cast it? You can store it as a Table; a cast is unnecessary.
For the second error, remove the casts to Object. Simply leave them as their actual types. this.restores.put(player.getUniqueId(), active.getType(), active);
This should help you get through the issue.

Linkedlist remove method erroe [duplicate]

This question already has answers here:
Iterating through a Collection, avoiding ConcurrentModificationException when removing objects in a loop
(31 answers)
Closed 4 years ago.
when i try to remove element there is an error, i have uploaded the error in the image section. any help to fix? of any other way to get the code fixed and working smoothly and it it works while deleting the middle element not the first or second
duplication issue ,fixed using iterator. hatsooff to stack overflow .
all good
import java.util.*;
public class EarthquakeList {
private ArrayList<EarthquakeNode> records;
public EarthquakeList() {
records = new ArrayList<EarthquakeNode>();
}
public boolean isempty() {
return true;
}
public void add(String EarthquakeLo,String EarthquakeDt, double EarthquakeSgth, int EarthquakeDu) {
EarthquakeNode en = new EarthquakeNode(EarthquakeLo, EarthquakeDt, EarthquakeSgth, EarthquakeDu);
records.add(en);
}
public boolean remove(String EarthquakeLo,String EarthquakeDt) {
boolean flag= false;
for(EarthquakeNode earthquake: records)
{
if(earthquake.getLocation().equalsIgnoreCase(EarthquakeLo))
{
if(earthquake.getDate().equals(EarthquakeDt))
{
records.remove(earthquake);
flag=true;
}
}
}
return flag;
}
public EarthquakeNode search(String EarthquakeLo,String EarthquakeDt) {
EarthquakeNode node= null;
for(EarthquakeNode earthquake: records)
{
if(earthquake.getLocation().equalsIgnoreCase(EarthquakeLo))
{
if(earthquake.getDate().equals(EarthquakeDt))
{
node=earthquake;
}
}
}
return node;
}
public boolean clear() {
int count=records.size();
for(EarthquakeNode earthquake: records)
{
count=count-1;
records.remove(earthquake);
}
if(count==0)
{
System.out.println("already empty");
return false;}
else
System.out.println("every thing is removed");
return true;
}
public boolean isempty(String EarthquakeLo,String EarthquakeDt) {
boolean flag= false;
for(EarthquakeNode earthquake: records)
{
if(earthquake.getLocation().equalsIgnoreCase(EarthquakeLo))
{
if(earthquake.getDate().equals(EarthquakeDt))
{
flag=true;
}
}
}
return flag;
}
public void print() {
for(EarthquakeNode earthquake: records)
{
System.out.println( earthquake.getLocation() +" - "
+ earthquake.getDate()+ " - "
+ earthquake.getStrength() + " on rector scale"+
"-" + earthquake.getDuration() + "mins");
}
}
}
You need to use an Iterator to safely remove from a collection while iterating over it.
public boolean remove(String earthquakeLo, String earthquakeDt) {
boolean flag= false;
Iterator<EarthquakeNode> iterator = records.iterator();
while(iterator.hasNext()) {
EarthquakeNode earthquake = iterator.next();
if(earthquake.getLocation().equalsIgnoreCase(earthquakeLo)) {
if(earthquake.getDate().equals(earthquakeDt)) {
iterator.remove();
flag=true;
}
}
}
return flag;
}

Junit not passing even though it should

Updated the isVanityURL method. See below for original question and code based on Shahid's recommendation. Also looking at the Path class as suggested by assylias.
public static boolean isVanityPath(String resourcePath) {
String resPath = resourcePath;
if (resPath == null) {
return false;
} else {
resPath = resPath.trim();
if (!resPath.equalsIgnoreCase(StringPool.BLANK)) {
int len = resPath.length();
String startChar = resPath.substring(0, 1);
if (startChar.equals(StringPool.FORWARD_SLASH) && len > 1) {
resPath = resPath.substring(1, len--);
}else{
return false;
}
int lastIndexOfSlash = resPath.lastIndexOf(StringPool.FORWARD_SLASH);
int slashIndex = resPath.indexOf(StringPool.FORWARD_SLASH);
if (slashIndex != -1)
return slashIndex == lastIndexOfSlash && lastIndexOfSlash == len - 1;
else
return true;
} else {
return false;
}
}
This is the updated JUnit Test
#Before
public void setUp() {
vu = Mockito.mock(ResourcePathUtil.class);
}
#Test
public void testVanityURLWhenRoot() {
Assert.assertFalse(ResourcePathUtil.isVanityPath("/"));
}
#Test
public void testVanityURLWhenNull() {
Assert.assertFalse(ResourcePathUtil.isVanityPath(null));
}
#Test
public void testVanityURLWhenValidVanity() {
Assert.assertTrue(ResourcePathUtil.isVanityPath("/vanitycode"));
}
#Test
public void testVanityURLWhenValidVanityWithTrailingSlash() {
boolean retValue = ResourcePathUtil.isVanityPath("/vanitycode/");
Assert.assertFalse("Returned True", retValue);
}
#Test
public void testVanityURLWhenInvalidVanityWithTrailingSlash() {
Assert.assertFalse(ResourcePathUtil.isVanityPath("/vanitycode/invalidwithslash/"));
}
#Test
public void testVanityURLWhenInvalidVanity() {
Assert.assertFalse(ResourcePathUtil.isVanityPath("/vanitycode/justinvalid"));
}
#Test
public void testVanityURLWhenBlank() {
Assert.assertFalse(ResourcePathUtil.isVanityPath(""));
}
I have the following class (ResourcePathUtil) with a static method. I'd like to test it with a JUnit (URLTest). However some of the tests (testVanityURLWhenRoot, testVanityURLWhenValidVanity) don't seem to pass, although it should. Any pointers on what I am doing wrong?
public class ResourcePathUtil {
/**
*
* #param url
* #param data
* #return result
*/
public static boolean isVanityPath(String resourcePath) {
String resPath = resourcePath;
if (resPath == null) {
return false;
} else {
resPath = resPath.trim();
if (!resPath.equalsIgnoreCase(StringPool.BLANK)) {
int len = resPath.length();
String startChar = resPath.substring(0, 1);
if (startChar.equals(StringPool.FORWARD_SLASH)) {
resPath = resPath.substring(1, len--);
}
int lastIndexOfSlash = resPath.lastIndexOf(StringPool.FORWARD_SLASH);
int slashIndex = resPath.indexOf(StringPool.FORWARD_SLASH);
if (slashIndex != -1)
return slashIndex == lastIndexOfSlash && lastIndexOfSlash == len - 1;
else
return true;
} else {
return false;
}
}
}
}
The JUnit Class is below
import junit.framework.Assert;
import org.mockito.Mockito;
import org.junit.Before;
import org.junit.Test;
public class URLTest {
#Before
public void setUp() {
vu = Mockito.mock(ResourcePathUtil.class);
}
#Test
public void testVanityURLWhenRoot() {
Assert.assertFalse(ResourcePathUtil.isVanityPath("/"));
}
#Test
public void testVanityURLWhenNull() {
Assert.assertFalse(ResourcePathUtil.isVanityPath(null));
}
#Test
public void testVanityURLWhenValidVanity() {
Assert.assertTrue(!ResourcePathUtil.isVanityPath("/vanitycode"));
}
#Test
public void testVanityURLWhenValidVanityWithTrailingSlash() {
boolean retValue = ResourcePathUtil.isVanityPath("/vanitycode/");
Assert.assertTrue("Returned False", !retValue);
}
#Test
public void testVanityURLWhenInvalidVanityWithTrailingSlash() {
Assert.assertFalse(ResourcePathUtil.isVanityPath("/vanitycode/invalidwithslash/"));
}
#Test
public void testVanityURLWhenInvalidVanity() {
Assert.assertFalse(ResourcePathUtil.isVanityPath("/vanitycode/justinvalid"));
}
#Test
public void testVanityURLWhenBlank() {
Assert.assertFalse(ResourcePathUtil.isVanityPath(""));
}
}
String Pool Class is below
public class StringPool {
public static final String BLANK = "";
public static final String FORWARD_SLASH = "/";
}
#Test
public void testVanityURLWhenRoot() {
// expecting isVanityPath() to return false
Assert.assertFalse(ResourcePathUtil.isVanityPath("/"));
}
#Test
public void testVanityURLWhenValidVanity() {
// expecting isVanityPath() to return false
Assert.assertTrue(!ResourcePathUtil.isVanityPath("/vanitycode"));
}
In both testVanityURLWhenRoot and testVanityURLWhenValidVanity, you are expecting false. But you are getting true. The reason lies in the method isVanityPath().
In both cases, the value of slashIndex is -1. And you are returning true when slashIndex is equal to -1. That's why in both cases you are getting true result, though you are expecting false.
if (slashIndex != -1) {
return slashIndex == lastIndexOfSlash && lastIndexOfSlash == len - 1;
} else { // it executes when slashIndex == -1
return true;
}
Suggestion:
Instead of:
Assert.assertTrue(!ResourcePathUtil.isVanityPath("/vanitycode"));
write:
Assert.assertFalse(ResourcePathUtil.isVanityPath("/vanitycode"));
The latter is more readable.

Coroutines in Java

I am reading this page about coroutines in Python and this Wikipedia page. I saw that there are a few libraries in Java implementing coroutines.
My question is: is there any known reason why the Java designers decided not to implement coroutines so far and is there any plan to include it in a future version of Java?
Thanks.
Actually the concept of a co-routine was the first design of the Java threading system. The wait/notify mechanism is a simplistic form of co-routine where notify is equivalent to yield etc.
Since then much has been done, particularly to make structures thread-safe rather than algorithms. This derives from the realization that it is not the code that must synchronize/yield but the data structure used to communicate between the threads that must be thread-safe.
Project Loom
Continuations and Coroutines will come to Java in the nearer future and they’ll be called virtual threads (also referred to as fibers). There’s a project called Loom:
Project Loom is intended to explore, incubate and deliver Java VM features and APIs built on top of them for the purpose of supporting easy-to-use, high-throughput lightweight concurrency and new programming models on the Java platform. This is accomplished by the addition of the following constructs:
Virtual threads
Delimited continuations
Tail-call elimination
Further reading: https://cr.openjdk.java.net/~rpressler/loom/Loom-Proposal.html
To quote that document:
It is the goal of this project to add a public delimited continuation (or coroutine) construct to the Java platform. However, this goal is secondary to fibers …
Preliminary builds of Project Loom are available now, based on early-access Java 16.
On the "are there any plans ..." part of the question, the answer is:
Not at this stage
The JEP list (http://openjdk.java.net/jeps/0) does not make any mention of coroutines. The list covers features added in Java 8, added or targeted for Java 9, or proposed for future releases.
Interestingly, there was an RFE submitted in March 2013 (https://bugs.openjdk.java.net/browse/JDK-8029988). The RFE only got one vote, and it was closed 9 months with the suggestion to submit a JEP. Nobody has bothered to take the idea any further, which to me is telling.
It's synced with Java 15 build 7.
Link
There's an another choice is here for Java6+
A pythonic coroutine implementation:
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;
class CorRunRAII {
private final List<WeakReference<? extends CorRun>> resources = new ArrayList<>();
public CorRunRAII add(CorRun resource) {
if (resource == null) {
return this;
}
resources.add(new WeakReference<>(resource));
return this;
}
public CorRunRAII addAll(List<? extends CorRun> arrayList) {
if (arrayList == null) {
return this;
}
for (CorRun corRun : arrayList) {
add(corRun);
}
return this;
}
#Override
protected void finalize() throws Throwable {
super.finalize();
for (WeakReference<? extends CorRun> corRunWeakReference : resources) {
CorRun corRun = corRunWeakReference.get();
if (corRun != null) {
corRun.stop();
}
}
}
}
class CorRunYieldReturn<ReceiveType, YieldReturnType> {
public final AtomicReference<ReceiveType> receiveValue;
public final LinkedBlockingDeque<AtomicReference<YieldReturnType>> yieldReturnValue;
CorRunYieldReturn(AtomicReference<ReceiveType> receiveValue, LinkedBlockingDeque<AtomicReference<YieldReturnType>> yieldReturnValue) {
this.receiveValue = receiveValue;
this.yieldReturnValue = yieldReturnValue;
}
}
interface CorRun<ReceiveType, YieldReturnType> extends Runnable, Callable<YieldReturnType> {
boolean start();
void stop();
void stop(final Throwable throwable);
boolean isStarted();
boolean isEnded();
Throwable getError();
ReceiveType getReceiveValue();
void setResultForOuter(YieldReturnType resultForOuter);
YieldReturnType getResultForOuter();
YieldReturnType receive(ReceiveType value);
ReceiveType yield();
ReceiveType yield(YieldReturnType value);
<TargetReceiveType, TargetYieldReturnType> TargetYieldReturnType yieldFrom(final CorRun<TargetReceiveType, TargetYieldReturnType> another);
<TargetReceiveType, TargetYieldReturnType> TargetYieldReturnType yieldFrom(final CorRun<TargetReceiveType, TargetYieldReturnType> another, final TargetReceiveType value);
}
abstract class CorRunSync<ReceiveType, YieldReturnType> implements CorRun<ReceiveType, YieldReturnType> {
private ReceiveType receiveValue;
public final List<WeakReference<CorRun>> potentialChildrenCoroutineList = new ArrayList<>();
// Outside
private AtomicBoolean isStarted = new AtomicBoolean(false);
private AtomicBoolean isEnded = new AtomicBoolean(false);
private Throwable error;
private YieldReturnType resultForOuter;
#Override
public boolean start() {
boolean isStarted = this.isStarted.getAndSet(true);
if ((! isStarted)
&& (! isEnded())) {
receive(null);
}
return isStarted;
}
#Override
public void stop() {
stop(null);
}
#Override
public void stop(Throwable throwable) {
isEnded.set(true);
if (throwable != null) {
error = throwable;
}
for (WeakReference<CorRun> weakReference : potentialChildrenCoroutineList) {
CorRun child = weakReference.get();
if (child != null) {
child.stop();
}
}
}
#Override
public boolean isStarted() {
return isStarted.get();
}
#Override
public boolean isEnded() {
return isEnded.get();
}
#Override
public Throwable getError() {
return error;
}
#Override
public ReceiveType getReceiveValue() {
return receiveValue;
}
#Override
public void setResultForOuter(YieldReturnType resultForOuter) {
this.resultForOuter = resultForOuter;
}
#Override
public YieldReturnType getResultForOuter() {
return resultForOuter;
}
#Override
public synchronized YieldReturnType receive(ReceiveType value) {
receiveValue = value;
run();
return getResultForOuter();
}
#Override
public ReceiveType yield() {
return yield(null);
}
#Override
public ReceiveType yield(YieldReturnType value) {
resultForOuter = value;
return receiveValue;
}
#Override
public <TargetReceiveType, TargetYieldReturnType> TargetYieldReturnType yieldFrom(CorRun<TargetReceiveType, TargetYieldReturnType> another) {
return yieldFrom(another, null);
}
#Override
public <TargetReceiveType, TargetYieldReturnType> TargetYieldReturnType yieldFrom(CorRun<TargetReceiveType, TargetYieldReturnType> another, TargetReceiveType value) {
if (another == null || another.isEnded()) {
throw new RuntimeException("Call null or isEnded coroutine");
}
potentialChildrenCoroutineList.add(new WeakReference<CorRun>(another));
synchronized (another) {
boolean isStarted = another.start();
boolean isJustStarting = ! isStarted;
if (isJustStarting && another instanceof CorRunSync) {
return another.getResultForOuter();
}
return another.receive(value);
}
}
#Override
public void run() {
try {
this.call();
}
catch (Exception e) {
e.printStackTrace();
stop(e);
return;
}
}
}
abstract class CorRunThread<ReceiveType, YieldReturnType> implements CorRun<ReceiveType, YieldReturnType> {
private final ExecutorService childExecutorService = newExecutorService();
private ExecutorService executingOnExecutorService;
private static final CorRunYieldReturn DUMMY_COR_RUN_YIELD_RETURN = new CorRunYieldReturn(new AtomicReference<>(null), new LinkedBlockingDeque<AtomicReference>());
private final CorRun<ReceiveType, YieldReturnType> self;
public final List<WeakReference<CorRun>> potentialChildrenCoroutineList;
private CorRunYieldReturn<ReceiveType, YieldReturnType> lastCorRunYieldReturn;
private final LinkedBlockingDeque<CorRunYieldReturn<ReceiveType, YieldReturnType>> receiveQueue;
// Outside
private AtomicBoolean isStarted = new AtomicBoolean(false);
private AtomicBoolean isEnded = new AtomicBoolean(false);
private Future<YieldReturnType> future;
private Throwable error;
private final AtomicReference<YieldReturnType> resultForOuter = new AtomicReference<>();
CorRunThread() {
executingOnExecutorService = childExecutorService;
receiveQueue = new LinkedBlockingDeque<>();
potentialChildrenCoroutineList = new ArrayList<>();
self = this;
}
#Override
public void run() {
try {
self.call();
}
catch (Exception e) {
stop(e);
return;
}
stop();
}
#Override
public abstract YieldReturnType call();
#Override
public boolean start() {
return start(childExecutorService);
}
protected boolean start(ExecutorService executorService) {
boolean isStarted = this.isStarted.getAndSet(true);
if (!isStarted) {
executingOnExecutorService = executorService;
future = (Future<YieldReturnType>) executingOnExecutorService.submit((Runnable) self);
}
return isStarted;
}
#Override
public void stop() {
stop(null);
}
#Override
public void stop(final Throwable throwable) {
if (throwable != null) {
error = throwable;
}
isEnded.set(true);
returnYieldValue(null);
// Do this for making sure the coroutine has checked isEnd() after getting a dummy value
receiveQueue.offer(DUMMY_COR_RUN_YIELD_RETURN);
for (WeakReference<CorRun> weakReference : potentialChildrenCoroutineList) {
CorRun child = weakReference.get();
if (child != null) {
if (child instanceof CorRunThread) {
((CorRunThread)child).tryStop(childExecutorService);
}
}
}
childExecutorService.shutdownNow();
}
protected void tryStop(ExecutorService executorService) {
if (this.executingOnExecutorService == executorService) {
stop();
}
}
#Override
public boolean isEnded() {
return isEnded.get() || (
future != null && (future.isCancelled() || future.isDone())
);
}
#Override
public boolean isStarted() {
return isStarted.get();
}
public Future<YieldReturnType> getFuture() {
return future;
}
#Override
public Throwable getError() {
return error;
}
#Override
public void setResultForOuter(YieldReturnType resultForOuter) {
this.resultForOuter.set(resultForOuter);
}
#Override
public YieldReturnType getResultForOuter() {
return this.resultForOuter.get();
}
#Override
public YieldReturnType receive(ReceiveType value) {
LinkedBlockingDeque<AtomicReference<YieldReturnType>> yieldReturnValue = new LinkedBlockingDeque<>();
offerReceiveValue(value, yieldReturnValue);
try {
AtomicReference<YieldReturnType> takeValue = yieldReturnValue.take();
return takeValue == null ? null : takeValue.get();
} catch (InterruptedException e) {
e.printStackTrace();
}
return null;
}
#Override
public ReceiveType yield() {
return yield(null);
}
#Override
public ReceiveType yield(final YieldReturnType value) {
returnYieldValue(value);
return getReceiveValue();
}
#Override
public <TargetReceiveType, TargetYieldReturnType> TargetYieldReturnType yieldFrom(final CorRun<TargetReceiveType, TargetYieldReturnType> another) {
return yieldFrom(another, null);
}
#Override
public <TargetReceiveType, TargetYieldReturnType> TargetYieldReturnType yieldFrom(final CorRun<TargetReceiveType, TargetYieldReturnType> another, final TargetReceiveType value) {
if (another == null || another.isEnded()) {
throw new RuntimeException("Call null or isEnded coroutine");
}
boolean isStarted = false;
potentialChildrenCoroutineList.add(new WeakReference<CorRun>(another));
synchronized (another) {
if (another instanceof CorRunThread) {
isStarted = ((CorRunThread)another).start(childExecutorService);
}
else {
isStarted = another.start();
}
boolean isJustStarting = ! isStarted;
if (isJustStarting && another instanceof CorRunSync) {
return another.getResultForOuter();
}
TargetYieldReturnType send = another.receive(value);
return send;
}
}
#Override
public ReceiveType getReceiveValue() {
setLastCorRunYieldReturn(takeLastCorRunYieldReturn());
return lastCorRunYieldReturn.receiveValue.get();
}
protected void returnYieldValue(final YieldReturnType value) {
CorRunYieldReturn<ReceiveType, YieldReturnType> corRunYieldReturn = lastCorRunYieldReturn;
if (corRunYieldReturn != null) {
corRunYieldReturn.yieldReturnValue.offer(new AtomicReference<>(value));
}
}
protected void offerReceiveValue(final ReceiveType value, LinkedBlockingDeque<AtomicReference<YieldReturnType>> yieldReturnValue) {
receiveQueue.offer(new CorRunYieldReturn(new AtomicReference<>(value), yieldReturnValue));
}
protected CorRunYieldReturn<ReceiveType, YieldReturnType> takeLastCorRunYieldReturn() {
try {
return receiveQueue.take();
} catch (InterruptedException e) {
e.printStackTrace();
}
return null;
}
protected void setLastCorRunYieldReturn(CorRunYieldReturn<ReceiveType,YieldReturnType> lastCorRunYieldReturn) {
this.lastCorRunYieldReturn = lastCorRunYieldReturn;
}
protected ExecutorService newExecutorService() {
return Executors.newCachedThreadPool(getThreadFactory());
}
protected ThreadFactory getThreadFactory() {
return new ThreadFactory() {
#Override
public Thread newThread(final Runnable runnable) {
Thread thread = new Thread(runnable);
thread.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
#Override
public void uncaughtException(Thread thread, Throwable throwable) {
throwable.printStackTrace();
if (runnable instanceof CorRun) {
CorRun self = (CorRun) runnable;
self.stop(throwable);
thread.interrupt();
}
}
});
return thread;
}
};
}
}
Now you can use pythonic coroutines in this way
(e.g. fibonacci numbers)
Thread Version:
class Fib extends CorRunThread<Integer, Integer> {
#Override
public Integer call() {
Integer times = getReceiveValue();
do {
int a = 1, b = 1;
for (int i = 0; times != null && i < times; i++) {
int temp = a + b;
a = b;
b = temp;
}
// A pythonic "yield", i.e., it returns `a` to the caller and waits `times` value from the next caller
times = yield(a);
} while (! isEnded());
setResultForOuter(Integer.MAX_VALUE);
return getResultForOuter();
}
}
class MainRun extends CorRunThread<String, String> {
#Override
public String call() {
// The fib coroutine would be recycled by its parent
// (no requirement to call its start() and stop() manually)
// Otherwise, if you want to share its instance and start/stop it manually,
// please start it before being called by yieldFrom() and stop it in the end.
Fib fib = new Fib();
String result = "";
Integer current;
int times = 10;
for (int i = 0; i < times; i++) {
// A pythonic "yield from", i.e., it calls fib with `i` parameter and waits for returned value as `current`
current = yieldFrom(fib, i);
if (fib.getError() != null) {
throw new RuntimeException(fib.getError());
}
if (current == null) {
continue;
}
if (i > 0) {
result += ",";
}
result += current;
}
setResultForOuter(result);
return result;
}
}
Sync(non-thread) version:
class Fib extends CorRunSync<Integer, Integer> {
#Override
public Integer call() {
Integer times = getReceiveValue();
int a = 1, b = 1;
for (int i = 0; times != null && i < times; i++) {
int temp = a + b;
a = b;
b = temp;
}
yield(a);
return getResultForOuter();
}
}
class MainRun extends CorRunSync<String, String> {
#Override
public String call() {
CorRun<Integer, Integer> fib = null;
try {
fib = new Fib();
} catch (Exception e) {
e.printStackTrace();
}
String result = "";
Integer current;
int times = 10;
for (int i = 0; i < times; i++) {
current = yieldFrom(fib, i);
if (fib.getError() != null) {
throw new RuntimeException(fib.getError());
}
if (current == null) {
continue;
}
if (i > 0) {
result += ",";
}
result += current;
}
stop();
setResultForOuter(result);
if (Utils.isEmpty(result)) {
throw new RuntimeException("Error");
}
return result;
}
}
Execution(Both versions will work):
// Run the entry coroutine
MainRun mainRun = new MainRun();
mainRun.start();
// Wait for mainRun ending for 5 seconds
long startTimestamp = System.currentTimeMillis();
while(!mainRun.isEnded()) {
if (System.currentTimeMillis() - startTimestamp > TimeUnit.SECONDS.toMillis(5)) {
throw new RuntimeException("Wait too much time");
}
}
// The result should be "1,1,2,3,5,8,13,21,34,55"
System.out.println(mainRun.getResultForOuter());

Categories