fastjengine / fastj Goto Github PK
View Code? Open in Web Editor NEWAn open-source, Java-based 2D game engine.
Home Page: https://fastj.tech
License: MIT License
An open-source, Java-based 2D game engine.
Home Page: https://fastj.tech
License: MIT License
The tech.fastj.engine.FastJEngine.exit()
method does not clear the AfterUpdateList
or AfterRenderList
, when it should because at that point those methods should not be executed.
Tasks:
AfterUpdateList
in the FastJEngine.exit()
methodAfterRenderList
in the FastJEngine.exit()
methodThe github wiki redirects to an non existant page (should be https://fastj.tech/wiki/intro not https://fastj.tech/fastj/wiki/intro)
The lack of discord server link is quite bad, let's be honest.
Add the discord server badge (from shields.io) and a mention to the discord server in the main README.
The InputManager
was originally integrated into the Scene
class, but involved quite a bit of method clutter. To counter this, the InputManager
class was created to control the state, and was exposed publicly to allow direct usage.
Now I know we can do better.
This issue was created to re-integrate the InputManager
into the Scene class
, and work on restricting direct input firing to the engine itself. However, this will not be what is worked on for now -- it will likely integrate with issue #11 before reaching that point.
The following should be completed:
InputManager
's method count for later possible integration with the Scene
classProgress will be tracked in the merge-inputmanager
branch. Comments welcome!
The lack of tutorials for how to use FastJ greatly hinder a newcomer's ability to effectively use the game engine.
Add tutorials to FastJ depicting how just about anything in FastJ works -- from an empty window, to rendering game objects, to adding game object behaviors, to scene management, etc.
@lucasstarsz will be proofreading and content-checking tutorials as needed.
You may also request that I notify you if your tutorial needs to be updated for whatever reason -- you can opt out of this at any time.
.psdf
formatFastJEngine#log/warning/error
FastJEngine#configure
FastJEngine#setTargetFPS
FastJEngine#setTargetUPS
Scene
s in a SceneManager
Progress on this issue will be tracked in the examples
branch. Feel free to suggest tutorials not yet mentioned!
The link to the source code in Maven doesnt work. Its currently https://tech.fastj which bring me to
I believe its supposed to be https://fastj.tech.
java2d is perfectly capable of rendering both the outline and the fill of anything being rendered. As such, FastJ should support both of these options for Text2D and Polygon2D.
FastJ should support the following options:
Stroke
) and fill (Paint
) variablesProgress will be tracked in the drawable-improvement
branch.
FastJ's README feature list section works well for its purpose, but the descriptions are far from optimal.
2D Rendering - Rendering of 2D Polygons, Models, Lighting
This is a succinct description of what the 2D rendering situation in FastJ should amount to.
Audio Engine - Play sounds of several different formats at any given time.
This is a vague description of the general ideas on Fastj's audio engine.
FastJ Model Creator - Create & Export 2D Models quickly and easily.
This, is quite literally a marketing ploy.
With the way FastJ has been reaching people in the last few days, now would be a great time to improve the descriptions to clear up how FastJ should appear to people -- a no-nonsense, reasonably simple 2D java game engine.
Change the descriptions in the README to match one general style -- no-nonsense, simple explanations. It's an open-source game engine -- give it a reason to stand out as professional!
As part of the constant improvement of the FastJ engine, we shouldn't forget that maintainability is as important as new functionality. Currently, both GameObject
and Camera
classes contain transform logic, which is duplicated and hard to maintain. This logic should instead be transfered over to a new class Transform2D
, which will contain transform logic, and provide a friendly way to interface with AffineTransform
s.
A possible set of changes is as follows:
GameObject
and Camera
classesTransform2D
classThe Transform2D
class may find use as well in other classes which require transformation logic.
AffineTransform
Comments, questions, and suggestions about this feature request are welcomed. Please put them below!
Progress will be tracked in the drawable-improvement
and camera-transform
branches.
It's become clear to me we need a lot better explanation of how to use FastJ.
Could probably use all of these:
FastJ's current implementation of SimpleManager
does not use Behaviors whatsoever. There is no place in which behaviors are updated, or initialized, nor destroyed.
1. Add a behavior to any game object in a SimpleManager
2. Run the program
3. See error
1.5.0 (Latest Version)
Java 11, Java 16
No response
The repository at lucasstarsz/FastJ-Engine has been privated. Links to this engine will no longer work and should be removed.
Remove all links to lucasstarsz/FastJ-Engine in the readme.
The Point
and Pointf
classes are FastJ's choice of weaponry when it comes to vector math. As such, there are many things to consider adding.
Several methods revolving around vectors should be implemented, such as:
The following are of less importance, but it is also desirable to create abstractions to allow working with certain AWT types:
java.awt.Dimension
And last but not least, I would like to achieve some more major improvements to the system as a whole:
- Abstract Point
/Pointf
to an interface, allowing the following:
- [ ] Immutable versions of Pointf
and Point
classes
- [ ] Reusability and a better guarantee that they will mesh together reliably in the future.
The above will be considered in a later issue. For now, it's out of the scope for completing smaller projects within the engine.
If you find more methods to be necessary, please leave a comment.
Progress of these features will be tracked in the math-improvement
branch.
Since #35, Polygon2D
's constructors have been replaced with a builder instance. This is useful, but still inconsistent with the current state of the other Drawable
derivative classes.
In both Text2D
and Model2D
classes...
Progress will be tracked in the drawable-improvement
branch.
FastJ 1.5.0 is near, and an audio engine would be a great addition to the arsenal of tools.
The Audio engine should, for 1.5.0, support the following features:
As an aside, the branch should also contain:
AudioManager#playSound
as well as file pathsProgress will be tracked in the audio
branch.
Since this is the FastJ org, the templates like https://github.com/lucasstarsz/fastj-java-template should be moved into the fastjengine
repo.
We should use version 6.8 of gradle instead of 6.7.1 (current one)
FastJ contains certain classes that need to be simplified -- their overall length is a pain to maintain in its current setup.
Each problematic file and its solution will be displayed here, as well as the progress made on simplifying it. As updates are made, this issue will be updated.
Commits dealing with this are tracked in the class-diverging
branch.
Display.java
GraphicsEnvironment
-related content into a separate file.FastJEngine.java
SettingsConfig
FastJEngine
class will be updated in a separate issue and branch.MemoryAudio
and StreamedAudio
currently serve different purposes in audio.
MemoryAudio
has explicit looping and playback controls but a lack of panning, volume, muting, and other controls. It also uses much more memory as the entire file gets loaded into the system at once.StreamedAudio
, on the other hand, loads the file in chunks which uses much less memory. It has the panning, volume, muting, etc. controls but still lacks explicit looping and playback controls.In this situation, StreamedAudio
has more pros than MemoryAudio
and should be the chosen audio type to use.
I would like to replace MemoryAudio
entirely, in favor of StreamedAudio
. Being more memory-efficient, it is the most natural option to continue using.
This also means that StreamedAudio
needs to support the following features:
Other than that, these tasks should also be completed:
No response
Neither the Scene
class nor the SimpleManager
class destroy behaviors when it is reset. This can be checked through placing a logging statement inside the destroy
method of any Behavior, then attaching it to a game object within any one of these managers.
1. Add a logging statement to any Behavior's destroy() method.
2. Attach said Behavior to any GameObject within a Scene or SimpleManager.
3. Run the program.
4. See error
1.5.0 (Latest Version)
Java 11, Java 16
N/A (The log does not print out.)
Place an x
in the box(es) [x]
that the issue occurs on (or that you've found the issue on)
A clear and concise description of what the bug is.
I tried running FastJ in 800x600 resolution, Then I found out that the Text is stretched and smaller than it should compare to running at 1280x720 resolution.
A clear and concise description of what you expected to happen.
I expect the Text to display properly, With the same size when displayed on 1280x720 resolution.
Steps to reproduce the behavior:
FastJEngine.init(gameName, this);
FastJEngine.configureViewerResolution(new Point(800, 600));
FastJEngine.run();
If applicable, add screenshots/GIFs/videos to help explain your problem.
Additional context not provided above.
I use a Custom class to create the Text.
The code for the class:
package ga.susite.StablerCharacter;
import java.awt.Color;
import java.awt.Font;
import tech.fastj.graphics.game.Text2D;
public class TextInfo {
Color color;
Font font;
TextInfo(Color nColor, Font nFont) {
color = nColor;
font = nFont;
}
public Text2D build(String message) {
return Text2D.create(message).withFont(font).withFill(color).build();
}
}
FastJ's packages each lack descriptors for what they relate to. With the engine on the rise, it would make sense to provide a general run-down of what each of the packages contain.
The following packages need to be covered:
tech.fastj.engine
tech.fastj.engine.internals
tech.fastj.graphics
tech.fastj.graphics.display
tech.fastj.graphics.game
tech.fastj.graphics.gradients
tech.fastj.graphics.io
tech.fastj.graphics.ui
tech.fastj.graphics.util
tech.fastj.input
tech.fastj.input.keyboard
tech.fastj.input.mouse
tech.fastj.math
tech.fastj.systems
tech.fastj.systems.audio
tech.fastj.systems.behaviors
tech.fastj.systems.control
tech.fastj.systems.fio
tech.fastj.systems.tags
Suggest changes or fixes below.
Place an x
in the box(es) [x]
that the issue occurs on (or that you've found the issue on)
A clear and concise description of what the bug is.
I'm making a Swing UI for adjusting window resolution and Other settings.
But when I run the Code, I pressed play, The game window appears properly. But I can't exit out of the Game using the x
button on the Window border.
And it messed up the Window resizing as well.
A clear and concise description of what you expected to happen.
Exit the Java program peacefully. And can resize like normal.
Steps to reproduce the behavior:
x
on the Window border.If applicable, add screenshots/GIFs/videos to help explain your problem.
(Video provided by: lucasstarsz)
Additional context not provided above.
As part of the massive performance, feature, and structural overhaul needed to propel FastJ into 2.0, we need an incredibly strong and flexible foundation. As such, this issue is opened to describe the many things needed in order to consider the engine ready for a more useful UI system, among other things.
This is the list of features currently expected as a bare minimum in order to proceed:
General Model Loading
svg
formatobj
formatText2D
Polygon2D
Drawable
If you have any suggestions for other features, please leave a comment down below explaining. Progress of this will be tracked in the drawable
branch.
System.out
was good and all for the time, but this project is finally going somewhere -- might be time to give it some debugging wiiiiiiiiiiiiiiiiiiiiings.
Here are the tasks to complete for the logging system:
Progress will be was tracked on the slf4j
branch.
Currently in FastJ's audio engine, all audio files are gotten from a Path
file. This is fine for general purposes, but it is insufficient for cases where an audio file needs to be read from within a jarfile.
To attempt to load an audio file in FastJ from inside a jarfile the code may look like this:
Path pathToAudio = new File(
Objects.requireNonNull(
classLoader.getResource("path/to/audio.wav")
).getFile().substring(5) // substring(5) removes the "file:" from the beginning of the output of getFile()
).toPath();
AudioManager.loadMemoryAudio(pathToAudio);
Despite this seeming to work, it does not. The file system (which is resolving the File
created from the Path
provided) is not able to find the file, because it is inside the jarfile. The error may look like this:
java.io.FileNotFoundException: F:\project\build\libs\project-0.0.1.jar!\path\to\audio.wav (The system cannot find the path specified)
However, this code:
AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(
Objects.requireNonNull(
TheClass.class.getClassLoader().getResource("path/to/audio.wav")
)
);
runs perfectly fine.
I'm inclined to believe that the File
system does not evaluate files within jars as a result.
To combat these issues, I propose the following changes:
AudioManager#newAudioStream
to allow generation of an AudioInputStream
using a URL
object.Path
objects, including:
MemoryAudio
constructorStreamedAudio
constructorAudioManager#loadMemoryAudio
methodsAudioManager#loadStreamedAudio
methodsThis should be sufficient to allow for audio objects to be loaded with URL
files.
No response
Considering just how much there is to this game engine, and the amount of times bugs go untested, a bit of testing for the various functions in the game engine would be much appreciated.
This is our coverage of tests so far:
engine
engine.config
graphics
graphics.dialog
graphics.display
graphics.game
graphics.ui.elements
graphics.util
graphics.gradients
input
input.keyboard
input.mouse
logging
math
resources
resources.files
resources.images
resources.models
systems.audio
systems.audio.state
systems.behaviors
systems.collections
systems.control
systems.tags
As the engine develops, more tests will be written.
From the SonarCloud quality tests, it seems there are some unnecessary casts to float.
case Paused: { audioEventListener.audioResumeAction.accept(audioEvent); }
I was wondering if you might want to add a
break
statement here?
Actually, I've been meaning to include a comment explaining the lack of a break! Good catch.
The audio event system includes audio events for when audio is paused, and when the audio's playing stream is stopped (either temporarily or permanently). As of right now, I've intentionally had both trigger because it made sense at the time -- when an audio stream stops, ot could be either paused or completely stopped. If it is paused, then an extra event should be created for that. Feel free to dispute this though -- I've been considering adding those break statements for a while.
Originally posted by @lucasstarsz in #71 (comment)
At some point I need to add a comment explaining the usage that I talk about here.
The current keyboard input solution for FastJ is fairly useful in terms of checking against keyboard state. However, there is a need for an improvement in terms of keycodes.
The following features should be implemented:
Keys
contain its keycode and key location such that users don't have to determine where on the keyboard a key is. (Change Keys
to an enum)java.awt.KeyEvent
to provide extra methods that mesh with the Keys
enumProgress will be tracked in the keyboard
branch.
Within tech.fastj.graphics.game.Text2D
, the setMetrics
method adds the object's current translation to the collision. However, the outward-facing collision path already gets transformed -- this means the translation gets doubled, which leads to issues rendering.
Fix through completion of the following tasks;
Text2D.setMetrics
1. Create a Text2D object with a translation of some sort. In the logs below, a translation of (400, 300) was used.
2. Log the Text2D's current collision path (using text2D.getCollisionPath().getBounds2D())
3. Change the Text2D's text or font, or otherwise trigger the "setMetrics" method to run.
4. Log the Text2D's current collision path (using text2D.getCollisionPath().getBounds2D())
5. See error -- the translation has changed between the two, despite the translation not having been updated.
1.5.1 (Latest Version), 1.5.0 (Latest General Version)
Java 11, Java 12-15, Java 16
[main] INFO tech.fastj.engine.FastJEngine - BEFORE
[main] INFO tech.fastj.engine.FastJEngine - java.awt.geom.Rectangle2D$Float[x=400.0,y=300.0,w=157.0,h=22.0]
[main] INFO tech.fastj.engine.FastJEngine - AFTER
[main] INFO tech.fastj.engine.FastJEngine - java.awt.geom.Rectangle2D$Float[x=800.0,y=600.0,w=81.0,h=22.0]
In tech.fastj.systems.audio.AudioEventListener
, inside the AudioEventProcessor
Map, the mappings for audio start/stop check the PlaybackState
in order to process actions. However, the current switch statements do not cover all cases.
I suggest adding default cases to each of the switch statements that throw illegal state exceptions -- these errors should state that the audio state was unexpected and invalid.
As FastJ quickly shoots through multiple versions, a versioning system needs to be set up. This will help to better mark out compatibility issues between different versions of FastJ in different sectors such as .psdf files.
The following tasks should be completed:
No response
As of #65, FastJ now supports x11 hardware acceleration. But, in the examples/engineconfig
example, it says only Direct3D and OpenGL are supported.
Update the engineconfig example to include x11 in the supported graphics API's.
In FastJ's current Display
, render options are set through using java.awt.RenderingHints
. This interface is fine, but there should be an interface included that words content for better readability.
The following should be added:
Progress will be tracked in the display-options
branch.
As FastJ's drawable system grows, curves need to be supported by all polygons. The following tasks should be completed:
Currently in FastJ, the only way to set up lighting is to use gradients... while this may solve basic needs. It can be tedious sometimes to set up proper lighting, not to mention shadows won't be supported
Drawing of basic lighting (could be pixel based or gradients) that forms shadows dynamically when light is moved closer to another solid object.
There aren't really any alternatives to this, but like i said above, the only way as of right now is to use gradients, and again, as i said above... it gets tedious sometimes and there's no shadow rendering as well..
Maven Central has served us well, but with all the production mistakes being made it might be a good time to switch to an easier-to-use platform.
The following should be completed:
HWAccel
currently does not contain an option for Linux's x11 rendering.
X11
option with the x11-based java2d properties to HWAccel.java
.FastJEngine#configureHardwareAcceleration
. This process is already done for Direct3D
.I'm wondering how you would go about moving ./.github/media/*
to the root of the project. As in ./assets/branding
or such. The reason I'm suggesting this is that I haven't really seen any repository have resources/branding/assets/whatever in .github/*
.
How would this help though?
Well, nothing. As far as I've seen/know, it's traditional to have that. I've noticed godot has that directly in its root, in my opinion, that makes it less organized. Oh well, I hope this issue is clear enough.
Broken link to an example in FastJ news (in FastJ 1.5.0 Release
news) in the Audio Engine section, There's this message:
For the best information, check out the audio usage example.
I clicked the link, And it redirects to https://example.fastj.dev/audio/Main.java page. that redirects to https://github.com/fastjengine/FastJ/tree/main/src/example/java/tech/fastj/example/audio/Main.java which does not exist.
Fix the link into the correct one.
Place an x
in the box(es) [x]
that the issue occurs on (or that you've found the issue on)
A clear and concise description of what the bug is.
The button position is set, But the button is still placed at the top left corner.
A clear and concise description of what you expected to happen.
The button supposed to Position properly.
Steps to reproduce the behavior:
If applicable, add screenshots/GIFs/videos to help explain your problem.
Additional context not provided above.
The FastJ version I was using was FastJ 1.5.0 (Snapshot)
You have to use the Scenes workflow to reproduce it. (Because Buttons only supports scenes at the moment)
As part of the next version(s) of FastJ, improving the LogicManager and Scene-related classes is a must.
These are the following features I'd like to see:
SceneManager
(has scenes), and SimpleManager
(no scenes here!)
LogicManager
into an interface, to allow for LogicManager
s without Scene
implementationsSceneManager
setCurrentScene
should attempt to safely add the scene to the manager before setting as current- [ ] Add support for scene dividing (layering)
- [ ] Allow parallelization of updating/rendering, due to each layer running independently (one layer cannot affect the state of another)
Progress of these features will be tracked in the logicmanager-and-scene-improvement
branch.
In #87, the audio system received a buff in that audio files could now be played from a URL. This feature should also be applied to AudioManager.playSound
. Furthermore, unit tests should be added to ensure these methods work as intended.
The following tasks should be completed:
AudioManager.playSound
using a URL
objectAudioManager.playSound
After #35 and #37 were merged, the examples for FastJ became severely outdated in content and would break upon usage due to outdated code.
Update examples so that they account for recent merges to the game engine.
Progress will be tracked in the examples
branch.
As FastJ's Drawable system grows, textures for polygons need to be supported. The following tasks should be completed:
FastJ 1.5.0 already released. We should bump the snapshot version to 1.6.0.
As FastJ heads into version 1.6.0, a system for handling images, sprites, and sprite animation will be needed to accompany FastJ's growing model system.
The following tasks should be completed:
Sprite2D
classSprite2D
, with the following features:
No response
The tech.fastj.graphics.io.SupportedFileFormats
class' purpose is to provide a list of supported formats for model reading and writing. It serves its purpose well, but the name can be misleading, and for future purposes is a bit too general. Later on in the future there will be other classes similar to it for other types of files being read, such as audio files.
My recommended solution is to change the class name to SupportedModelFormats
, since it is much more representative of what the class is for.
While running FastJ unit tests, I received a ConcurrentModificationException
from FastJ's scene system. It seems despite many efforts FastJ still has occasional threading issues.
1. Run any FastJ program that uses the scene system.
2. (Very) occasionally, the error will appear.
1.5.0 (Latest Version)
Java 11
Unexpected exception type thrown ==> expected: <java.lang.IllegalStateException> but was: <java.util.ConcurrentModificationException>
Expected :java.lang.IllegalStateException
Actual :java.util.ConcurrentModificationException
<Click to see difference>
org.opentest4j.AssertionFailedError: Unexpected exception type thrown ==> expected: <java.lang.IllegalStateException> but was: <java.util.ConcurrentModificationException>
at [email protected]/org.junit.jupiter.api.AssertThrows.assertThrows(AssertThrows.java:65)
at [email protected]/org.junit.jupiter.api.AssertThrows.assertThrows(AssertThrows.java:37)
at [email protected]/org.junit.jupiter.api.Assertions.assertThrows(Assertions.java:3007)
at fastj.library.test/unittest.testcases.systems.control.SceneManagerTests.trySceneManagerSetCurrentScene_bySceneName_withSceneNameThatDoesNotExist(SceneManagerTests.java:146)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at [email protected]/org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:688)
at [email protected]/org.junit.jupiter.engine.execution.MethodInvocation.proceed(MethodInvocation.java:60)
at [email protected]/org.junit.jupiter.engine.execution.InvocationInterceptorChain$ValidatingInvocation.proceed(InvocationInterceptorChain.java:131)
at [email protected]/org.junit.jupiter.engine.extension.TimeoutExtension.intercept(TimeoutExtension.java:149)
at [email protected]/org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestableMethod(TimeoutExtension.java:140)
at [email protected]/org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestMethod(TimeoutExtension.java:84)
at [email protected]/org.junit.jupiter.engine.execution.ExecutableInvoker$ReflectiveInterceptorCall.lambda$ofVoidMethod$0(ExecutableInvoker.java:115)
at [email protected]/org.junit.jupiter.engine.execution.ExecutableInvoker.lambda$invoke$0(ExecutableInvoker.java:105)
at [email protected]/org.junit.jupiter.engine.execution.InvocationInterceptorChain$InterceptedInvocation.proceed(InvocationInterceptorChain.java:106)
at [email protected]/org.junit.jupiter.engine.execution.InvocationInterceptorChain.proceed(InvocationInterceptorChain.java:64)
at [email protected]/org.junit.jupiter.engine.execution.InvocationInterceptorChain.chainAndInvoke(InvocationInterceptorChain.java:45)
at [email protected]/org.junit.jupiter.engine.execution.InvocationInterceptorChain.invoke(InvocationInterceptorChain.java:37)
at [email protected]/org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:104)
at [email protected]/org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:98)
at [email protected]/org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeTestMethod$6(TestMethodTestDescriptor.java:210)
at [email protected]/org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at [email protected]/org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeTestMethod(TestMethodTestDescriptor.java:206)
at [email protected]/org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:131)
at [email protected]/org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:65)
at [email protected]/org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:139)
at [email protected]/org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at [email protected]/org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:129)
at [email protected]/org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
at [email protected]/org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:127)
at [email protected]/org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at [email protected]/org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:126)
at [email protected]/org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:84)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1541)
at [email protected]/org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38)
at [email protected]/org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:143)
at [email protected]/org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at [email protected]/org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:129)
at [email protected]/org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
at [email protected]/org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:127)
at [email protected]/org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at [email protected]/org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:126)
at [email protected]/org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:84)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1541)
at [email protected]/org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38)
at [email protected]/org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:143)
at [email protected]/org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at [email protected]/org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:129)
at [email protected]/org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
at [email protected]/org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:127)
at [email protected]/org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at [email protected]/org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:126)
at [email protected]/org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:84)
at [email protected]/org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:32)
at [email protected]/org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57)
at [email protected]/org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:51)
at [email protected]/org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:108)
at [email protected]/org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:88)
at [email protected]/org.junit.platform.launcher.core.EngineExecutionOrchestrator.lambda$execute$0(EngineExecutionOrchestrator.java:54)
at [email protected]/org.junit.platform.launcher.core.EngineExecutionOrchestrator.withInterceptedStreams(EngineExecutionOrchestrator.java:67)
at [email protected]/org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:52)
at [email protected]/org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:96)
at [email protected]/org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:75)
at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor$CollectAllTestClassesExecutor.processAllTestClasses(JUnitPlatformTestClassProcessor.java:99)
at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor$CollectAllTestClassesExecutor.access$000(JUnitPlatformTestClassProcessor.java:79)
at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor.stop(JUnitPlatformTestClassProcessor.java:75)
at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.stop(SuiteTestClassProcessor.java:61)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:36)
at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
at org.gradle.internal.dispatch.ContextClassLoaderDispatch.dispatch(ContextClassLoaderDispatch.java:33)
at org.gradle.internal.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:94)
at com.sun.proxy.$Proxy5.stop(Unknown Source)
at org.gradle.api.internal.tasks.testing.worker.TestWorker.stop(TestWorker.java:135)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:36)
at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
at org.gradle.internal.remote.internal.hub.MessageHubBackedObjectConnection$DispatchWrapper.dispatch(MessageHubBackedObjectConnection.java:182)
at org.gradle.internal.remote.internal.hub.MessageHubBackedObjectConnection$DispatchWrapper.dispatch(MessageHubBackedObjectConnection.java:164)
at org.gradle.internal.remote.internal.hub.MessageHub$Handler.run(MessageHub.java:414)
at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:64)
at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:48)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
at org.gradle.internal.concurrent.ThreadFactoryImpl$ManagedThreadRunnable.run(ThreadFactoryImpl.java:56)
at java.base/java.lang.Thread.run(Thread.java:834)
Caused by: java.util.ConcurrentModificationException
at java.base/java.util.HashMap$HashIterator.nextNode(HashMap.java:1493)
at java.base/java.util.HashMap$ValueIterator.next(HashMap.java:1521)
at fastj.library/tech.fastj.systems.behaviors.BehaviorManager.reset(BehaviorManager.java:111)
at fastj.library/tech.fastj.engine.FastJEngine.exit(FastJEngine.java:557)
at fastj.library/tech.fastj.engine.FastJEngine.forceCloseGame(FastJEngine.java:401)
at fastj.library/tech.fastj.engine.FastJEngine.error(FastJEngine.java:432)
at fastj.library/tech.fastj.systems.control.SceneManager.sceneExistenceCheck(SceneManager.java:360)
at fastj.library/tech.fastj.systems.control.SceneManager.setCurrentScene(SceneManager.java:100)
at fastj.library.test/unittest.testcases.systems.control.SceneManagerTests.lambda$trySceneManagerSetCurrentScene_bySceneName_withSceneNameThatDoesNotExist$3(SceneManagerTests.java:146)
at [email protected]/org.junit.jupiter.api.AssertThrows.assertThrows(AssertThrows.java:55)
... 93 more
Gradle Test Executor 1 finished executing tests.
> Task :test
SceneManagerTests > trySceneManagerSetCurrentScene_bySceneName_withSceneNameThatDoesNotExist() FAILED
org.opentest4j.AssertionFailedError: Unexpected exception type thrown ==> expected: <java.lang.IllegalStateException> but was: <java.util.ConcurrentModificationException>
at [email protected]/org.junit.jupiter.api.AssertThrows.assertThrows(AssertThrows.java:65)
at [email protected]/org.junit.jupiter.api.AssertThrows.assertThrows(AssertThrows.java:37)
at [email protected]/org.junit.jupiter.api.Assertions.assertThrows(Assertions.java:3007)
at fastj.library.test/unittest.testcases.systems.control.SceneManagerTests.trySceneManagerSetCurrentScene_bySceneName_withSceneNameThatDoesNotExist(SceneManagerTests.java:146)
Caused by:
java.util.ConcurrentModificationException
at java.base/java.util.HashMap$HashIterator.nextNode(HashMap.java:1493)
at java.base/java.util.HashMap$ValueIterator.next(HashMap.java:1521)
at fastj.library/tech.fastj.systems.behaviors.BehaviorManager.reset(BehaviorManager.java:111)
at fastj.library/tech.fastj.engine.FastJEngine.exit(FastJEngine.java:557)
at fastj.library/tech.fastj.engine.FastJEngine.forceCloseGame(FastJEngine.java:401)
at fastj.library/tech.fastj.engine.FastJEngine.error(FastJEngine.java:432)
at fastj.library/tech.fastj.systems.control.SceneManager.sceneExistenceCheck(SceneManager.java:360)
at fastj.library/tech.fastj.systems.control.SceneManager.setCurrentScene(SceneManager.java:100)
at fastj.library.test/unittest.testcases.systems.control.SceneManagerTests.lambda$trySceneManagerSetCurrentScene_bySceneName_withSceneNameThatDoesNotExist$3(SceneManagerTests.java:146)
at [email protected]/org.junit.jupiter.api.AssertThrows.assertThrows(AssertThrows.java:55)
... 3 more
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.