I am trying to eliminate all the memory allocation during gameplay on my game and I have stuck to something strange that I never saw in the past, for some reason the use of instanceof is doing memory allocation on android, why is that?
This is the full code of OrangeFollower.java:
package enemies;
import game.ConcreteBodySystem;
import game.Tags;
import main.MainGame;
import player.Player;
import tools.Director;
import tools.FastMath;
import tools.Vector;
import tools.gColor;
import worldsystem.BlockCollitionSystem;
import worldsystem.Entity;
import worldsystem.IntervalSystem;
import worldsystem.SoundSystem;
import worldsystem.SpriteSystem;
import worldsystem.gWorld;
import com.badlogic.gdx.Gdx;
public class OrangeFollower extends Enemy {
public static int TAG=gWorld.getNextTag();
public OrangeFollower(final gWorld world) {
super(world);
this.tag =TAG;
initScale(0.8f,0.8f);
initColor(1,0.6f,0, 1);
initColScale(0.4f, 0.4f);
initSpeed(0.018f);
setGroups(Tags.GROUP_CONCRETE_ENEMIES,Tags.GROUP_DESTRACTABLE,Tags.GROUP_ENEMIE,Tags.GROUP_GREEN_ENEMIES,Tags.GROUP_MOVING);
SpriteSystem sm=(SpriteSystem) addSystem(new SpriteSystem(this, "sprites/sprites2.png",896,256,1,128,128,pos,scale,rotation,new gColor(1,1,1,1)));
addSystem(new ConcreteBodySystem(this));
addSystem(new EnemieSystem(this,2,20,false,true,false,false,Tags.GROUP_GREEN_ENEMIES){{multis=2;}});
addSystem(new BlockCollitionSystem(this,256,true){
#Override
public void colliding(Entity e) {
super.colliding(e);
if(e instanceof Generator)return;
Vector.vector.set(e.pos.x-pos.x, e.pos.y-pos.y);
float length = FastMath.sqrtBlazingFast(Vector.vector.x*Vector.vector.x + Vector.vector.y*Vector.vector.y);
if (length != 0) {
Vector.vector.x = Vector.vector.x / length;
Vector.vector.y = Vector.vector.y / length;
vel.x-=Vector.vector.x;
vel.y-=Vector.vector.y;
}
}
});
}
#Override
public void init() {
super.init();
speed=realSpeed;
}
#Override
public void update() {
super.update();
pos.x += (vel.x * speed) * Director.delta;
pos.y += (vel.y * speed) * Director.delta;
}
}
The class is initialized for the first time.
An inner class is not necessarily initialized when the outer class is. Again the java reference says: first use.
Memory allocation not only happens with new at the object instantiations, but also at the ClassLoaders.
What happens on Android is yet another affair, but fortunately Google still keeps close to processing model of the official JVMs.
As extracted from comments by #VinceEmigh, #SteveL, #fge.
Related
So I'm trying to make SEA_LANTERN drop multiple sand underneath of itself when it's placed so I can keep my cannon filled with sand as it's firing here is my code
Main
package me.zavage.sandbot;
import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.java.JavaPlugin;
import me.zavage.sandbot.commands.SandBotCommand;
import me.zavage.sandbot.listeners.SandBotListener;
public class Main extends JavaPlugin {
#Override
public void onEnable() {
new SandBotListener(this);
new SandBotCommand(this);
}
public static Plugin getInstance() {
return null;
}
}
package me.zavage.sandbot.listeners;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.entity.FallingBlock;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.block.BlockPlaceEvent;
import org.bukkit.scheduler.BukkitTask;
import org.bukkit.util.Vector;
import me.zavage.sandbot.Main;
public class SandBotListener implements Listener {
private BukkitTask task;
private int keepToSpawn = 0;
public SandBotListener(Main main) {
}
#EventHandler
public void onPlaceSandbot(BlockPlaceEvent e) {
Material spawnType = e.getBlockPlaced().getType(); // get placed block
if(!spawnType.equals(Material.SEA_LANTERN)) // in your case, be sure it's sea lantern
return;
keepToSpawn = 5; // amount of spawned item
Location loc = e.getBlock().getLocation(); // location where entity will spawn
task = Bukkit.getScheduler().runTaskTimer(Main.getInstance(), () -> {
// each 0.5s, we made spawn a falling block of given type
run(loc, spawnType);
if(keepToSpawn == 0)
task.cancel();
keepToSpawn--;
}, 10, 10); // 10 ticks = 0.5 seconds
}
#SuppressWarnings("deprecation")
private void run(Location loc, Material type) {
FallingBlock falling = loc.getWorld().spawnFallingBlock(loc, Material.SAND, (byte) 0);
falling.setDropItem(true);
falling.setVelocity(new Vector(0, -0.5, 0)); // set the velicoty of the block
}
}
Edit: I updated the code including the main class as well
Theres gotta be something I'm missing, but ive tried so many different things at this point
This is an example code that will make spawn 5 times a falling block to below :
private BukkitTask task;
private int keepToSpawn = 0;
#EventHandler
public void onPlaceSandbot(BlockPlaceEvent e) {
Material spawnType = e.getBlockPlaced().getType(); // get placed block
if(!spawnType.equals(Material.SEA_LANTERN)) // in your case, be sure it's sea lantern
return;
keepToSpawn = 5; // amount of spawned item
Location loc = e.getBlock().getLocation(); // location where entity will spawn
task = Bukkit.getScheduler().runTaskTimer(Main.getInstance(), () -> {
// each 0.5s, we made spawn a falling block of given type
run(loc, spawnType);
if(keepToSpawn == 0)
task.cancel();
keepToSpawn--;
}, 10, 10); // 10 ticks = 0.5 seconds
}
#SuppressWarnings("deprecation")
private void run(Location loc, Material type) {
FallingBlock falling = loc.getWorld().spawnFallingBlock(loc, type, (byte) 0);
falling.setDropItem(true);
falling.setVelocity(new Vector(0, -0.5, 0)); // set the velicoty of the block
}
Don't use Bukkit.getWorld(e.getBlockPlaced().getLocation().getWorld().getUID()), you already have the world instance with e.getBlockPlaced().getWorld().
For the Vector used as velocity, you should set the direction of the block. I set negative Y to make it fall (and not x/z to make it keep at his block).
PS: Don't forget to register the listener with this code in your onEnable:
getServer().getPluginManager().registerEvents(new SandBotListener(this), this);
For the instance of your plugin, you have to have an instance of the object "Main" which is represented by "this".
To use it, in your Main.java :
private static Main instance; // create variable that is "static".
// It means it not depend to an object to get it
public static Main getInstance() { // get the object instance, so the plugin instance
return instance;
}
#Override
public void onEnable() {
instance = this; // here set the instance of this, so as the current object
// it will make this object available for everyone
getServer().getPluginManager().registerEvents(new SandBotListener(), this);
}
Then, you can remove the constructor of the SandBotListener.java.
Now, you able to use Main.getInstance().
I am trying to develop a blacklist system for blocks for my server and this is how it should work: In the config.yml there are names of the materials of the blocks that are not allowed to be placed. Then a check is made for each placed block whether the material is contained in config.yml.
Here is my code:
package de.blocklog.blocklog;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.block.Block;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.block.BlockPlaceEvent;
import org.bukkit.plugin.java.JavaPlugin;
import java.util.List;
public final class Main extends JavaPlugin implements Listener {
#Override
public void onEnable() {
// Plugin startup logic
}
#Override
public void onDisable() {
// Plugin shutdown logic
}
#EventHandler
public void onBlockPlace(BlockPlaceEvent event){
Block block = event.getBlock();
Material material = block.getType();
Player placer = event.getPlayer();
double x = block.getLocation().getX();
double y = block.getLocation().getY();
double z = block.getLocation().getZ();
List<String> bannedmats = this.getConfig().getStringList("banned-blocks");
for(World w : Bukkit.getWorlds()){
for(Player p : w.getPlayers()){
if(p.hasPermission("blocklogsystem.see") || p.hasPermission("blocklogsystem.*"))
p.sendMessage("[BLOCKLOG] Player " + placer.getDisplayName() + " placed " + material + " at X:" + x + " Y: " + y +" Z: "+ z);
if(material.name().equals(bannedmats))
p.sendMessage("[BLOCKLOG] Player " + placer.getDisplayName() + " placed an illegal " + material + " at X:" + x + " Y: " + y +" Z: "+ z);
}
}
}
}
But somehow it doesn't work :/
Yout need to register your Event in the onEnable Method like:
#Override
public void onEnable() {
// Plugin startup logic
Bukkit.getPluginManager().registerEvents(this, this);
}
To be fair, your provided information is a bit vague but I've recently implemented exactly this feature except with the banned blocks stored in memory as an ArrayList of Material objects.
Effectively what I do is make use of the .contains() method of an ArrayList object to check for presence of a given block in a list of blocks.
All this considered here is the basic run down, assuming you've already developed parsing your config.yml data into specifically an ArrayList of Material objects that looks something like this:
public static ArrayList<Material> PlacementBanned = new ArrayList<>();
{
PlacementBanned.addAll(Arrays.asList(Material.BARRIER, Material.COMMAND_BLOCK,
Material.CHAIN_COMMAND_BLOCK, Material.REPEATING_COMMAND_BLOCK, Material.COMMAND_BLOCK_MINECART,
Material.WATER, Material.LAVA, Material.STRUCTURE_BLOCK, Material.STRUCTURE_VOID));
}
Firstly, I highly recommend you use a separate class for the listener. like this:
Main
package myPlugin;
import myPlugin.myPackage.myListenerClass;
import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.PluginManager;
import org.bukkit.plugin.java.JavaPlugin;
public class Main extends JavaPlugin {
public static Plugin instance;
#Override
public void onEnable() {
instance = this;
PluginManager pm = getServer().getPluginManager();
pm.registerEvents(new myListenerClass(), this);
}
}
myPackage.myListenerClass
package myPlugin.myPackage;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.event.Listener;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.block.BlockPlaceEvent;
public class myListenerClass implements Listener {
#EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = false)
public void onPlace(BlockPlaceEvent event) {
Block block = event.getBlockPlaced();
Material blockType = block.getType();
if (PlacementBanned.contains(blockType)) {
event.setCancelled(true);
return;
}
}
}
Note, LOWEST priority means it will be queued up in the first of 5 batches of all methods triggered by the listener in your code.
I have a custom object FermentableInRecipe, which populates a TableView. In order to respond to changes to items in the list, as well as the list itself, I have decided to employ an extractor. Here is my declaration and instantiation of my ObservableList:
private ObservableList<FermentableInRecipe> fermentablesInRecipe =
FXCollections.observableArrayList(item -> new Observable[]{item.WeightProperty()});
Here are the relevant segments of my custom class:
public class FermentableInRecipe {
private DoubleProperty weight;
...
public Double getWeight() {
return this.weight.getValue();
}
public void setWeight(Double value) {
this.weight.setValue(value);
}
public DoubleProperty WeightProperty() {
if (weight == null) {
weight = new SimpleDoubleProperty(0.0);
}
return weight;
}
...
}
In the links I've provided below, this approach worked. But Netbeans is telling me "DoubleProperty cannot be converted to Observable". I can see why this is the case, but I cannot understand why it worked in the links below and not for me, and how I should create extractor and link it to the weightProperty() function if this approach doesn't work.
Links:
JavaFX 2.0 Choice Box Issue. How to update a choiceBox, which represents a list of objects, when an object is updated?
JavaFX, ObservableList: How to fire an InvalidationListener whenever an object of the list gets modified?
Thanks in advance. Let me know if I've missed any crucial information.
There's nothing wrong with your code as written, this compiles just fine for me:
import javafx.application.Application;
import javafx.beans.Observable;
import javafx.beans.property.DoubleProperty;
import javafx.beans.property.SimpleDoubleProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.stage.Stage;
public class JavaFXApplication1 extends Application {
class FermentableInRecipe {
private DoubleProperty weight;
public Double getWeight() {
return this.weight.getValue();
}
public void setWeight(Double value) {
this.weight.setValue(value);
}
public DoubleProperty WeightProperty() {
if (weight == null) {
weight = new SimpleDoubleProperty(0.0);
}
return weight;
}
}
private ObservableList<FermentableInRecipe> fermentablesInRecipe = FXCollections.observableArrayList(item -> new Observable[]{item.WeightProperty()});
#Override
public void start(Stage primaryStage) throws Exception {
}
}
I'd suggest double checking imports, and make sure you haven't imported java.util.Observable or similar by mistake.
In my hard drive I have follow source:
package DAO;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.Reader;
import java.io.StringReader;
import java.io.StringWriter;
import java.io.Writer;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.*;
import java.util.concurrent.CountDownLatch;
public abstract class A {
public class A4{
public String teste4(int i){
return (new String("teste"));
}
}
public class A3{
public String teste3(int i){
return (new String("teste"));
}
public A4 teste33(int i){
return (new A4());
}
}
public class A2{
public A3 teste2(int i){
return (new A3());
}
}
public class A1{
public A2 teste1(int i){
return (new A2());
}
}
public int[] toIntArray(List<Integer> list) {
A1 q=new A1();
Integer t=q.teste1(
(new A1()).
teste1(0).
teste2(0).
teste33(0).
teste4(0).
length() ).
teste2(0).
teste3(0).
length();
}
}
Note that in this file (A.java) we have many blank lines and one command not necessarily was written in the same line, in others words, it's maybe spread in many lines (See last line of method "toIntArray").
When I parse this source code with AST, the "toString" of "CompilationUnit"show the follow struct (AST Struct):
package DAO;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.Reader;
import java.io.StringReader;
import java.io.StringWriter;
import java.io.Writer;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.*;
import java.util.concurrent.CountDownLatch;
public abstract class A {
public class A4 {
public String teste4( int i){
return (new String("teste"));
}
}
public class A3 {
public String teste3( int i){
return (new String("teste"));
}
public A4 teste33( int i){
return (new A4());
}
}
public class A2 {
public A3 teste2( int i){
return (new A3());
}
}
public class A1 {
public A2 teste1( int i){
return (new A2());
}
}
public int[] toIntArray( List<Integer> list){
A1 q=new A1();
Integer t=q.teste1((new A1()).teste1(0).teste2(0).teste33(0).teste4(0).length()).teste2(0).teste3(0).length();
}
}
Note that in this case, all blank lines was removed and the command "Integer t=q.teste1...." was write in the same line. It's fine to me. Thus, in visit "MethodInvocation", I want to get line number of these invocations. To do this, I make follow source in my astVisitors:
public boolean visit(final CompilationUnit node) {
this.CompilationUnit=node;
}
public boolean visit(final MethodInvocation node) {
Integer LineInFile=this.CompilationUnit.getLineNumber(node.getStartPosition());
}
But the command "getLineNumber" return Line Number in source file in my hard drive, not in AST Struct. In this case, to the line "q.teste1((new.....", the command "getLineNumber" return the lines 44 and 45, but want that this return only the line 44.
So, How get de line number in "AST Struct"?
The CompilationUnit.toString method is just doing a rough format of the internal AST using the NaiveASTFlattener class.
The actual internal structure of the AST is just a large number of class instances of things like Block, Comment, Statement, ... As such the AST itself does not have line numbers. The only line numbers the AST knows about are the lines in the original source code.
We may start by expanding AST to "abstract syntax tree", which emphasizes that we have no (direct) connection to the source level (=concrete) syntax. You may call it a "model", which captures the semantically relevant aspects, while omitting accidental details like white space. A language could even rename its keywords without any changes to the abstract syntax etc.
It's a convenience for users, that a CompilationUnit additionally stores the positions of line ends, so it can map an AST node back to its original location in the source code.
I am trying to add sentiment analysis program to Spark pipeline. When doing it, I have class which extends org.apache.spark.ml.PredictionModel. When extending this PredictionModel class, I have to override predict() method which predicts the label for given feature. But, I get either 0 or 1 all the time when I execute this code.For example, if there are 10 movie reviews, five are negative reviews and other five are negative, it classifies all reviews as negative. I have attached the code below.
import org.apache.spark.ml.PredictionModel;
import org.apache.spark.ml.param.ParamMap;
import org.apache.spark.mllib.linalg.DenseVector;
import org.apache.spark.mllib.linalg.Vector;
import org.deeplearning4j.nn.multilayer.MultiLayerNetwork;
import org.nd4j.linalg.api.buffer.DataBuffer;
import org.nd4j.linalg.api.ndarray.INDArray;
import org.nd4j.linalg.factory.Nd4j;
import java.io.*;
//Model produced by a ProbabilisticClassifier
public class MovieReviewClassifierModel extends PredictionModel<Object, MovieReviewClassifierModel> implements Serializable{
private static final long serialVersionUID = 1L;
private MultiLayerNetwork net;
MovieReviewClassifierModel (MultiLayerNetwork net) throws Exception {
this.net=net;
}
#Override
public MovieReviewClassifierModel copy(ParamMap args0) {
return null;
}
#Override
public String uid() {
return "MovieReviewClassifierModel";
}
public double raw2prediction(Vector rawPrediction) {//Given a vector of raw predictions, select the predicted label
return rawPrediction.toArray()[0];
}
#Override
public double predict(Object o) {
int prediction=0;
DenseVector v=(DenseVector)o;
double[] a=v.toArray();
INDArray arr=Nd4j.create(a);
INDArray array= net.output(arr,false);
DataBuffer ob = array.data();
double[] d=ob.asDouble();
double zeroProbability=d[0];
double oneProbability=d[1];
if (zeroProbability > oneProbability) {
prediction=0;
}
else{
prediction=1;
}
return prediction;
}
}
Can you give me reasons for the wrong predictions?
In public double predict(Object o) you have a following if statement:
if (zeroProbability > oneProbability) {
prediction=0;
}
else{
prediction=1;
}
which causes the return of 0 or 1. Change this method in order to have some other prediction values.