I'm trying to use Nape with HaxeFlixel. Sadly, there's almost no documentation on how to use the addons.nape package and I just can't figure out why this code isn't moving the white rectangle (_test). (I left out imports for simplicity)
class PlayState extends FlxNapeState
{
var _test = new FlxNapeSprite(16, 16);
override public function create():Void
{
super.create();
_test.makeGraphic(16, 16);
_test.body.type = BodyType.KINEMATIC;
add(_test);
}
override public function update():Void
{
_test.body.velocity.x = 100;
super.update();
}
}
There are two issues with your code:
Directly initializing the _test variable leads to the FlxNapeSprite constructor call happening in the constructor of your PlayState. create() is called after the state constructor. This can cause crashes and otherwise weird behavior since Flixel does its internal cleanup between the constructor call of the new state and create() (graphics are disposed, for example, and in this case the Nape Space instance doesn't exist yet since it's created in the super.create() call).
The FlxNapeSprite constructor has a createRectangularBody argument which defaults to true and calls the function of that same name if true. Since you're not passing any asset to the constructor, it ends up creating a Shape with a width and height of 0. This leads to the following error:
Error: Cannot simulate with an invalid Polygon
Instead, you'll want to call createRectangularBody() manually after makeGraphic() to create a Shape that matches the graphic's dimensions.
The complete, working code looks like this:
package;
import flixel.addons.nape.FlxNapeSprite;
import flixel.addons.nape.FlxNapeState;
class PlayState extends FlxNapeState
{
override public function create():Void
{
super.create();
var _test = new FlxNapeSprite(16, 16);
_test.makeGraphic(16, 16);
_test.createRectangularBody();
_test.body.velocity.x = 100;
add(_test);
}
}
Regarding documentation, the FlxNape demo is a great resource to learn from.
Related
I have the following class:
public class MyDialogSelect extends RunBase
{
private DialogField nameField;
// Snipped for brevity
public Object dialog()
{
Dialog dialog = super();
nameField = dialog.addField(extendedTypeStr(CustName));
// Snipped for brevity
return dialog;
}
public void dialogSelectCtrl()
{
CustTable customerTable = CustTable::find(accountField.value());
nameField.value(customerTable.name());
// Snipped for brevity
}
}
This compiles and works as expected.
However, I prefer using the keyword this to indicate when variables belong to the instance, so I try changing it this to:
public class MyDialogSelect extends RunBase
{
private DialogField nameField;
// Snipped for brevity
public Object dialog()
{
Dialog dialog = super();
this.nameField = dialog.addField(extendedTypeStr(CustName));
// Snipped for brevity
return dialog;
}
public void dialogSelectCtrl()
{
CustTable customerTable = CustTable::find(accountField.value());
this.nameField.value(customerTable.name());
// Snipped for brevity
}
}
But, this won't compile, instead resulting in Invalid token '('..
However, if I remove this before nameField.value(customerTable.name());,
it works as expected again. (Note: I still indicate this in this.nameField = dialog.addField(extendedTypeStr(CustName));).
Why won't it compile when I include this before a property which invokes a method?
I've also observed this with this.nameField.enabled(false) also failing.
Is there a more general rule or principle I should understand here about when x++ allows, disallows, or requires this?
You cannot use this to reference instance variables in X++. Like in C++.
You can (and must) use this to refer to instance methods.
This refers to the context of the development, in your example, this refers to the class as a whole. Of you add another method, you would call that method using this.
With latest form pattern changes, I believe the MSFT recommendation is to use dialog form pattern instead of class to generate dialog.
I have 2 methods, tappedNext() and tappedPrevious(), i need to call this function by passing a string variable, e.g onTap: tapped + part + (), is it possible to make a string interpolation for this like tapped${part}() ?
I certainly do not recommend you to do that. Instead, use a simple if statement.
But since you asked if it is possible..
Short answer, no (with a function only). Unless you're talking about methods, in that case we could use some mirrors.
You'll need to import the mirror package, it doesn't work on dartpad, so test it locally:
import 'dart:mirrors';
class MyClass {
tappedNext() {
print('Next Function');
}
tappedPrevious() {
print('Previous Function');
}
}
Now you must create an object from the class, create a mirror of it, and then make use of a Symbol to call the method in a reflectly way.
void main() {
final clazz = MyClass();
final mirror = reflect(clazz);
final function = 'Next';
Symbol s = Symbol('tapped$function');
mirror.invoke(s, []).reflectee;
}
That's it, the console will print:
Next Function
The code snippet is from the book < Groovy in action 2nd >, with minor modifications.
1 this code works as expected
package test
class InspectMe {
int outer(){
return inner()
}
int inner(){
return 1
}
}
def tracer = new TracingInterceptor(writer: new StringWriter())
def proxyMetaClass = ProxyMetaClass.getInstance(InspectMe)
proxyMetaClass.interceptor = tracer
InspectMe inspectMe = new InspectMe()
inspectMe.metaClass = proxyMetaClass
inspectMe.outer()
println(tracer.writer.toString())
output:
before test.InspectMe.outer()
before test.InspectMe.inner()
after test.InspectMe.inner()
after test.InspectMe.outer()
2 but this code's output is different
package test
class InspectMe {
int outer(){
return inner()
}
int inner(){
return 1
}
}
def tracer = new TracingInterceptor(writer: new StringWriter())
def proxyMetaClass = ProxyMetaClass.getInstance(InspectMe)
proxyMetaClass.interceptor = tracer
InspectMe inspectMe = new InspectMe()
proxyMetaClass.use(inspectMe){
inspectMe.outer()
}
println(tracer.writer.toString())
output:
before test.InspectMe.outer()
after test.InspectMe.outer()
It seems TracingInterceptor dosen't intercept inner methods in the second code.
Maybe it's normal behavior, But it seems to me like a bug.
Can somebody please explain this?
I don't know if this is a bug or not, but I can explain why this different behavior happens. Let's start with analyzing what InspectMe.outer() method implementation looks like at the bytecode level (we decompile .class file):
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//
import groovy.lang.GroovyObject;
import groovy.lang.MetaClass;
import org.codehaus.groovy.runtime.BytecodeInterface8;
import org.codehaus.groovy.runtime.callsite.CallSite;
import org.codehaus.groovy.runtime.typehandling.DefaultTypeTransformation;
public class InspectMe implements GroovyObject {
public InspectMe() {
CallSite[] var1 = $getCallSiteArray();
MetaClass var2 = this.$getStaticMetaClass();
this.metaClass = var2;
}
public int outer() {
CallSite[] var1 = $getCallSiteArray();
return !__$stMC && !BytecodeInterface8.disabledStandardMetaClass() ? this.inner() : DefaultTypeTransformation.intUnbox(var1[0].callCurrent(this));
}
public int inner() {
CallSite[] var1 = $getCallSiteArray();
return 1;
}
}
As you can see, the outer() method tests the following predicate
!__$stMC && !BytecodeInterface8.disabledStandardMetaClass()
and if it evaluates to true, it invokes directly this.inner() method avoiding Groovy's MOP (meta-object protocol) layer (no metaclass involved in this case). Otherwise, it invokes var1[0].callCurrent(this) which means that inner() method gets invoked through Groovy's MOP with metaclass and interceptor involved in its execution.
The two examples you have shown in the question present a different way of setting metaclass field. In the first case:
def tracer = new TracingInterceptor(writer: new StringWriter())
def proxyMetaClass = ProxyMetaClass.getInstance(InspectMe)
proxyMetaClass.interceptor = tracer
InspectMe inspectMe = new InspectMe()
inspectMe.metaClass = proxyMetaClass // <-- setting metaClass with DefaultGroovyMethods
inspectMe.outer()
println(tracer.writer.toString())
we are invoking inspectMe.setMetaClass(proxyMetaClass) method using Groovy's MOP layer. This method gets added to InspectMe class by DefaultGroovyMethods.setMetaClass(GroovyObject self, MetaClass metaClass).
Now, if we take a quick look at how this setMetaClass method is implemented we will find something interesting:
/**
* Set the metaclass for a GroovyObject.
* #param self the object whose metaclass we want to set
* #param metaClass the new metaclass value
* #since 2.0.0
*/
public static void setMetaClass(GroovyObject self, MetaClass metaClass) {
// this method was introduced as to prevent from a stack overflow, described in GROOVY-5285
if (metaClass instanceof HandleMetaClass)
metaClass = ((HandleMetaClass)metaClass).getAdaptee();
self.setMetaClass(metaClass);
disablePrimitiveOptimization(self);
}
private static void disablePrimitiveOptimization(Object self) {
Field sdyn;
Class c = self.getClass();
try {
sdyn = c.getDeclaredField(Verifier.STATIC_METACLASS_BOOL);
sdyn.setBoolean(null, true);
} catch (Throwable e) {
//DO NOTHING
}
}
It invokes at the end private method disablePrimitiveOptimization(self). This method is responsible for assigning true to __$stMC class field (the constant Verifier.STATIC_METACLASS_BOOL stores __$stMC value). What does it mean in our case? It means that the predicate in outer() method:
return !__$stMC && !BytecodeInterface8.disabledStandardMetaClass() ? this.inner() : DefaultTypeTransformation.intUnbox(var1[0].callCurrent(this));
evaluates to false, because __$stMC is set to true. And in this case inner() method gets executed via MOP with metaClass and interceptor.
OK, but it explains the first case that works as expected. What happens in the second case?
def tracer = new TracingInterceptor(writer: new StringWriter())
def proxyMetaClass = ProxyMetaClass.getInstance(InspectMe)
proxyMetaClass.interceptor = tracer
InspectMe inspectMe = new InspectMe()
proxyMetaClass.use(inspectMe){
inspectMe.outer()
}
println(tracer.writer.toString())
Firstly, we need to check what does proxyMetaClass.use() look like:
/**
* Use the ProxyMetaClass for the given Closure.
* Cares for balanced setting/unsetting ProxyMetaClass.
*
* #param closure piece of code to be executed with ProxyMetaClass
*/
public Object use(GroovyObject object, Closure closure) {
// grab existing meta (usually adaptee but we may have nested use calls)
MetaClass origMetaClass = object.getMetaClass();
object.setMetaClass(this);
try {
return closure.call();
} finally {
object.setMetaClass(origMetaClass);
}
}
It's pretty simple - it replaces metaClass for the time of closure execution and it sets the old metaClass back when closure's execution completes. Sounds like something similar to the first case, right? Not necessarily. This is Java code and it invokes object.setMetaClass(this) method directly (the object variable is of type GroovyObject which contains setMetaClass method). It means that the field __$stMC is not set to true (the default value is false), so the predicate in outer() method has to evaluate:
BytecodeInterface8.disabledStandardMetaClass()
If we run the second example we will see that this method call returns false:
And that is why the whole expression
!__$stMC && !BytecodeInterface8.disabledStandardMetaClass()
evaluates to true and the branch that invokes this.inner() directly gets executed.
Conclusion
I don't know if it was intended or not, but as you can see dynamic setMetaClass method disables primitive optimizations and continues using MOP, while ProxyMetaClass.use() sets the metaClass keeping primitive optimizations enabled and caused a direct method call. I guess this example shows a corner case no one thought about when implementing ProxyMetaClass class.
UPDATE
It seems like the difference between these two methods exists because ProxyMetaClass.use() was implemented in 2005 for Groovy 1.x and it got updated for the last time in 2009. This __$stMC field was added in 2011 and the DefaultGroovyMethods.setMetaClass(GroovyObject object, Closure cl) was introduced in 2012 according to its javadoc that says this method is available since Groovy 2.0.
// What is the technical reason behind this scenarios..?
You're trying to use a statement other than a declaration directly inside the class - rather than within a method. When did you expect the method to get called?
Basically all you can have directly within a type is a bunch of declarations - methods, variables, constructors, events, nested types etc. Method calls (or any other statements) which aren't part of a declaration have to be written within methods, constructors etc.
Method call statement can not be part of a class declaration, but only within Function members declarations scope, such as Methods, Properties, Constructors etc.
For example:
public class ExampleClass
{
private void SayHelloWorld()
{
Console.Writeline("Hello World!");
}
public void CallSayHelloWorldMethod()
{
this.SayHelloWorld();
}
}
At the above example you can see that I call the SayHelloWorld method within the CallSayHelloWorldMethod metod.
Update:
The closest thing I can think of in your case is to use the class's constructor where your method call will be executed as soon as you'll instantiate your class:
public class ExampleClass
{
//The class constructor
public ExampleClass()
{
this.SayHelloWorld();
}
private void SayHelloWorld()
{
Console.Writeline("Hello World!");
}
}
And when you instantiating it, it will be immediately called:
//Your method call will be executed here
ExampleClass exampleClass = new ExampleClass();
You have a few problems... This won't even compile as you are trying to call the method obj.m1() in the class definition.
A obj = new A();
obj.m1(); // Why this code wont work??? --> This must be inside a method
When you create an instance of a class it will create a new member variable called obj which is an instance of A --> A obj = newA() above;
You will now be able to call obj's methods as in your second example.
Also, in order to get this to compile you will need to fix the m2 method:
public void m2() { //--> should have a curly brace
obj.m1(); // But This will work.
}
I know Task has a method updateProgress, I would need to bind progressbar to task, however I cannot do that, as I do not have progressbar as an object.
My program has a TableView. Once user enters download url and clicks download new row created in the TableView. Row has some info and progressbar column. I then start a new thread - task. Where all download is being done and I need to update progress bar in that row somehow.
I tried binding SimpleDoubleProperty to the Task but it does not update progress bar...
James D solved this in Oracle JavaFX forum thread: Table cell progress indicator. I have just copied that solution into this answer.
The solution creates multiple tasks and monitors their progress via a set of progress bars in a TableView.
The original thread also includes a solution which uses ProgressIndicators in case you prefer those to ProgressBars.
import java.util.Random;
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;
import javafx.application.Application;
import javafx.concurrent.Task;
import javafx.scene.Scene;
import javafx.scene.control.ProgressIndicator ;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.ProgressBarTableCell;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;
public class ProgressBarTableCellTest extends Application {
#Override
public void start(Stage primaryStage) {
TableView<TestTask> table = new TableView<TestTask>();
Random rng = new Random();
for (int i = 0; i < 20; i++) {
table.getItems().add(
new TestTask(rng.nextInt(3000) + 2000, rng.nextInt(30) + 20));
}
TableColumn<TestTask, String> statusCol = new TableColumn("Status");
statusCol.setCellValueFactory(new PropertyValueFactory<TestTask, String>(
"message"));
statusCol.setPrefWidth(75);
TableColumn<TestTask, Double> progressCol = new TableColumn("Progress");
progressCol.setCellValueFactory(new PropertyValueFactory<TestTask, Double>(
"progress"));
progressCol
.setCellFactory(ProgressBarTableCell.<TestTask> forTableColumn());
table.getColumns().addAll(statusCol, progressCol);
BorderPane root = new BorderPane();
root.setCenter(table);
primaryStage.setScene(new Scene(root));
primaryStage.show();
ExecutorService executor = Executors.newFixedThreadPool(table.getItems().size(), new ThreadFactory() {
#Override
public Thread newThread(Runnable r) {
Thread t = new Thread(r);
t.setDaemon(true);
return t;
}
});
for (TestTask task : table.getItems()) {
executor.execute(task);
}
}
public static void main(String[] args) {
launch(args);
}
static class TestTask extends Task<Void> {
private final int waitTime; // milliseconds
private final int pauseTime; // milliseconds
public static final int NUM_ITERATIONS = 100;
TestTask(int waitTime, int pauseTime) {
this.waitTime = waitTime;
this.pauseTime = pauseTime;
}
#Override
protected Void call() throws Exception {
this.updateProgress(ProgressIndicator.INDETERMINATE_PROGRESS, 1);
this.updateMessage("Waiting...");
Thread.sleep(waitTime);
this.updateMessage("Running...");
for (int i = 0; i < NUM_ITERATIONS; i++) {
updateProgress((1.0 * i) / NUM_ITERATIONS, 1);
Thread.sleep(pauseTime);
}
this.updateMessage("Done");
this.updateProgress(1, 1);
return null;
}
}
}
Explanatory Text Based on Comment Questions
You only need to read this section if you are having difficulties understanding how the above code works and want to gain a deeper understanding of cell value and property connections.
There is no kind of binding here (at least I do not see).
The binding (or ChangeListener, which amounts to the same thing) is hidden behind the implementation of the PropertyValueFactory and the ProgressBarTableCell. Let's look at the relevant code:
TableColumn<TestTask, Double> progressCol = new TableColumn("Progress");
progressCol.setCellValueFactory(
new PropertyValueFactory<TestTask, Double>("progress")
);
progressCol.setCellFactory(
ProgressBarTableCell.<TestTask> forTableColumn()
);
The progressCol is defined to take a TestTask as the data row and extract a double value out of the test task property.
The cell value factory defines how the double value for the column is populated. It is defined based upon a PropertyValueFactory which takes the parameter "progress". This tells the property value factory to use JavaFX naming conventions and the Java reflection API to lookup relevant methods to retrieve the data from a TestTask instance. In this case it will invoke a method named progressProperty() on the TestTask instance to retrieve the ReadOnlyDoubleProperty reflecting the tasks progress.
As it states in it's documentation, the PropertyValueFactory is just short hand for the mess of code below, but the key fact is that it is returning an ObservableValue which the Table implementation can use to set the value of the cell as the cell changes.
TableColumn<Person,String> firstNameCol = new TableColumn<Person,String>("First Name");
firstNameCol.setCellValueFactory(new Callback<CellDataFeatures<Person, String>, ObservableValue<String>>() {
public ObservableValue<String> call(CellDataFeatures<Person, String> p) {
// p.getValue() returns the Person instance for a particular TableView row
return p.getValue().firstNameProperty();
}
});
OK, so now we have a cell's value being reflected to the double value of the task's progress whenever the task makes any progress. But we still need to graphically represent that double value somehow. This is what the ProgressBarTableCell does. It is a table cell which contains a progress bar. The forTableColumn method creates a factory which produces the ProgressBarTableCells for each non-empty row in the column and sets the progress bar's progress to match the cell value which has been linked to the task's progress property by the PropertyValueFactory.
Confusing in understanding the detailed implementation . . . sure. But these high level helper factories and cells take care of a lot of the low level linkage details for you so that you don't need to code them over and over and from a plain API usage point of view it is (hopefully) simple and logical.
Also there is no properties (like SimpleStringProperty etc.) so the question would be, what if I need like two more columns with SimpleStringProperty, how do I add them to this kind of TableView?
Use the PropertyValueFactory once again. Let's image you have a string property called URL, then you can add the columns like this:
TableColumn<TestTask, Double> urlCol = new TableColumn("URL");
urlCol.setCellValueFactory(
new PropertyValueFactory<TestTask, Double>("url")
);
Note we only needed to set the cell value factory, this is because the default cell factory for the column will return a cell containing a label which directly displays the string value of the cell.
Now for the above to work correctly we need a method on TestTask which provides a url for the task, for example:
final ReadOnlyStringWrapper url = new ReadOnlyStringWrapper();
public TestTask(String url) {
this.url.set(url);
}
public ReadOnlyStringProperty urlProperty() {
return url.getReadOnlyProperty()
}
Note that the naming convention is really important here, it must be urlProperty() it can't be anything else or the PropertyValueFactory won't find the property value accessor.
Note for these purposes, a simple String value with a getUrl() would have worked just as well as a property as a PropertyValueFactory will work with a getter as well as a property method. The only advantage of using a property method is that it allows the table value data to update automatically based on property change events, which is not possible with a straight getter. But here because the url is effectively final and doesn't change for a given task, it doesn't make a difference whether a getter or property method is provided for this file from the task.