How to add custom property to Sprite object? - phaser-framework

I want to add custom property to my sprite object but when I try to get id property it returns "undefined". Is there a Phaser library bug or am I doing something wrong?
My update function;
function update() {
//When I debug below line I can see enemyTank.tank.id property
game.physics.arcade.overlap(enemyTank.tank, mytank.tank, enemyTankHitPlayer, null, this);
}
Callback function;
function enemyTankHitPlayer(myTankSprite, enemyTankSprite) {
//enemyTankSprite.id is undefined!
}

Related

How to register custom cell renderer in pe:sheet? [duplicate]

I am trying to implement a custom cell renderer to the pe:sheet component.
As this component is based on Handsontable, I tried the approach as described here:
https://handsontable.com/docs/6.2.2/demo-custom-renderers.html
I also changed the code for registering from Handsontable.renderers.registerRenderer('myRenderer', myCustomRenderer);
to
this.cfg.renderers.registerRenderer('myRenderer', myCustomRenderer);
in an attempt to access the instance of handsontable inside pe:sheet.
I am calling my sheetExtender via the extender attribute of pe:sheet.
function sheetExtender() {
// this.cfg.renderers.registerRenderer('myRenderer', myCustomRenderer);
// Handsontable.renderers.registerRenderer('myRenderer', myCustomRenderer);
console.log(this);
}
var myCustomRenderer = function (instance, td, row, col, prop, value, cellProperties) {
$(td).empty().append('TEST');
};
Adding 'myRenderer' to the colType attribute of a pe:sheetcolumn, I would expect the column values to be overwritten by 'TEST'.
When I use 'this.cfg...' I get an Uncaught TypeError: Cannot read property 'registerRenderer' of undefined.
When I use 'Handsontable...' I don't get the error, but no results either, as, I guess, this approach propably didn't add the renderer to the actual instance of handsontable.
Is there a way to add custom cell renderers in pe:sheet, or at least make a cell render HTML?
I am the author of pe:sheet. If you want to customize the renderer you can do the following...
This is where it happens in the component: https://github.com/primefaces-extensions/core/blob/master/src/main/resources/META-INF/resources/primefaces-extensions/sheet/1-sheet.js#L59-L116
You can just override the default TextCellRenderer with your own.
function sheetExtender() {
this.cfg.textCellRenderer = function (instance, td, row, col, prop, value, cellProperties) {
Handsontable.renderers.HtmlRenderer.apply(this, arguments);
// call your custom renderer method here
myCustomerRenderer(instance, td, row, col, prop, value, cellProperties);
}
}

Can javascript function name contain a space?

I copied the code from kraken. I don't understand why there is a space between get and app(). Can someone please explain what's going on here?
var kraken = {
get app() {
return this._app;
},
use: function (route, delegate) {
//.....
}
}
No, in javascript a function cannot contain spaces. The code you are showing is using the get keyword to bind a property to a object.
get
Binds an object property to a function that will be called when that property is looked up.
Have a look to getters and setters in javascript.
It's a getter.
Check out this link.
The function is get and it's exposing a property called app.

How to observe all object property changes?

For arrays I know you can do something like this:
function() {
}.observes("array.#each")
What I did was convert the object into an array and observe the properties with a #each, but is there a better way to observe object all property changes without converting it into an array?
You can observe isDirty to see if any of the object's values have been modified since last save (if you are using Ember Data).
Alternatively you can pass a comma separated list of properties to observes. This might be long if you have a lot of properties on your object, but will work.
A third approach could be to override setUnknownProperty() and set a property, a 'dirty flag' (or perform any action you may want in there.
There's also an old SO post that gives the following answer:
App.WatchedObject = Ember.Object.extend({
firstProp: null,
secondProp: "bar",
init: function(){
this._super();
var self = this;
Ember.keys(this).forEach(function(key){
if(Ember.typeOf(self.get(key)) !== 'function'){
self.addObserver(key, function(){
console.log(self.get(key));
});
}
});
}
});
You could probably split this out into a Mixin to keep your code DRY.
probably you could create something like a blabbermouth mixin and override the set method to get notified of property changes:
App.BlabbermouthMixin = Ember.Mixin.create({
set: function(keyName, value) {
this.set('updatedProperty', keyName);
this._super(keyName, value);
}
});
and observe the updatedProperty property?
You can get a list of properties in an object and apply them to a new property:
attrs = Ember.keys(observedObject);
var c = Ember.computed(function() {
// Do stuff when something changes
})
Ember.defineProperty(target, propertyName, c.property.apply(c, attrs));
Here is a working jsbin. Creating an observer instead of a property should be possible using a similar approach.

monotouch DialogViewController RefreshRequested "System.ArgumentException: You should set the handler before the controller is shown"

I have some problems with getting the RefreshRequested event to work in one of my ViewControllers that implements the DialogViewController:
public CustomViewController () : base (null, true) {
RefreshRequested += delegate {
...
ReloadComplete ();
};
}
I am calling the CustomViewController from another ViewController like this:
var dvc = new CustomViewController();
this.ActivateController(dvc);
The error message I get is "Toplevel exception: System.ArgumentException: You should set the handler before the controller is shown"
Any pointers of what I am doing from here? Thanks
It looks like you do not have a RootElement specified, i.e. it's set to null by your own constructor, so you get warned that the internal state is not ready to set the event.
You should create an empty RootElement with your constructor and, later, add stuff to it (using the property). That should allow you to set the event in your own constructor. E.g.
public CustomViewController () : base (new RootElement (String.Empty), true)
Any pointers of what I am doing from here?
In doubt you can always see the entire source code MonoTouch.Dialog in it's github repository.
From my testing, the only place that you can set the event handler is in the constructor of the ViewController, as that's the only place where you can rely on the fact that the TableView property is null. I've tried the suggestion above of setting the RootElement in the constructor, but then always seem to have a TableView object before I can set the event handler. The problem with setting the event handler in the constructor though is that I don't have any way of resetting the event handler after cleaning it up.

DynamicMethod code unverifiable in .Net 4.0 (found ref 'this' pointer... expected ref '<>f__AnonymousType1`)

Was using this solution to convert anonymous types to dictionaries using reflection.emit. Was working fine until I changed to .Net 4.0 from 3.5.
Now, I'm getting the "System.Security.VerificationException: Operation could destabilize the runtime." error.
Converted the anonymously loaded dynamic method to one hosted in a dynamic assembly, saved it, then ran peverify.exe on it to find out what was wrong.
Got: [IL]: Error: [DynamicAssemblyExample.dll : MyDynamicType::MyMethod][offs
et 0x0000000D][found ref ('this' ptr) 'MyDynamicType'][expected ref '<>f__AnonymousType1`3[System.String,System.Int32,System.Byte]'] Unexpected type on the stac
k.
[IL]: Error: [DynamicAssemblyExample.dll : MyDynamicType::MyMethod][offs
et 0x0000000D] Method is not visible.
2 Error(s) Verifying DynamicAssemblyExample.dll
The code:
foreach (PropertyInfo property in itemType.GetProperties(attributes).Where(info => info.CanRead))
{
// load Dictionary (prepare for call later)
methIL.Emit(OpCodes.Ldloc_0);
// load key, i.e. name of the property
methIL.Emit(OpCodes.Ldstr, property.Name);
// load value of property to stack
methIL.Emit(OpCodes.Ldarg_0);
methIL.EmitCall(OpCodes.Callvirt, property.GetGetMethod(), null);
// perform boxing if necessary
if (property.PropertyType.IsValueType)
{
methIL.Emit(OpCodes.Box, property.PropertyType);
}
// stack at this point
// 1. string or null (value)
// 2. string (key)
// 3. dictionary
// ready to call dict.Add(key, value)
methIL.EmitCall(OpCodes.Callvirt, addMethod, null);
}
Is there a way to derefence the pointer to the actual property? Or do I have to cast it somehow? Any pointers?
Regards!
Sorry guys, made a mistake, since the actual dynamic method creates a delegate type that acts on the instance of the anonymous (or non-anonymous) type, the Ldarg_0 code is looking for a something that is not there in this debug implementation.
So I, changed it to OpCodes.Ldnull.
var attributes = BindingFlags.Instance | BindingFlags.Public | BindingFlags.FlattenHierarchy;
foreach (PropertyInfo property in itemType.GetProperties(attributes).Where(info => info.CanRead))
{
// load Dictionary (prepare for call later)
methIL.Emit(OpCodes.Ldloc_0);
// load key, i.e. name of the property
methIL.Emit(OpCodes.Ldstr, property.Name);
// load value of property to stack
methIL.Emit(OpCodes.Ldnull);
//methIL.Emit(OpCodes.Castclass, itemType);
methIL.EmitCall(OpCodes.Callvirt, property.GetGetMethod(), null);
// perform boxing if necessary
if (property.PropertyType.IsValueType)
{
methIL.Emit(OpCodes.Box, property.PropertyType);
}
// stack at this point
// 1. string or null (value)
// 2. string (key)
// 3. dictionary
// ready to call dict.Add(key, value)
methIL.EmitCall(OpCodes.Callvirt, addMethod, null);
}
But I still get a method not visible error after peverifying it. Is it that get methods for properties of anonymous types are not visible via reflection?
Just a suggestion, have you tried to rewrite the code that emits IL to actually write to the dictionary - i.e. no Reflection.Emit ? My bet is that the generated IL is not proper in some way, not the code that accesses the anonymous type.

Resources