How can I dynamically change the delay within my CCSequence? - cocos2d-iphone

I have a sequence that I am trying to repeat, and change the delay time with each occurance of the repeat... Something like:
__block CCDelayTime *delayTime = [CCDelayTime actionWithDuration:myDelay];
[CCRepeat actionWithAction:[CCSequence actions:
[CCCallFunc actionWithTarget:self selector:#selector(doSomething)],
delayTime,
[CCCallBlock actionWithBlock:^{
delayTime.duration = delayTime.duration / 2
}....
I am getting no where real fast.. Depsite the fact that the instance of CCDelayTime's duration_ ivar is in fact properly getting set to half of its previous value, when stepping through the code, it appears that as soon as control reaches one of the base class' (CCActionInterval) methods such as step or update:, the duration_ ivar is back to the original value (what myDelay was set to).
I spent quite a bit of time going through the cocos code trying to figure out why this is happening but eventually decided to give up and see if anyone here can help me. Perhaps there is a better way to do what I am trying to do in the first place?

what you do here is: call a function, wait for some time (delay), run a block that changes the waiting time of the action that already ran.
What you need to use is CCSpeed, add the delay action to it, and keep a reference to CCSpeed so that you can modify the speed from outside the sequence.

Related

Emberjs inside of get computed making request to backend multiple times cause infinite loop

I have a table basically in every row i have get function that makes a backend request with store service. But somehow when there is one row it works expect, but when there is multiple rows it always try to recalculate get function which makes sending infinite request to backend. I am using glimmer component
I cannot use model relation on ember side at this point, there is deep chain on backend side. Thats why i am making backend request.
get <function_name>() {
return this.store.query('<desired_model_name>', { <dependent1_id>: <dependent1_id_from_args>, <dependent2_id>: <dependent2_id_from_args> });
}
I fixed this problem with using constructor. But do you have any idea why this get function re-calculate all the time? Dependent_ids are constant.
Weird thing is when results are [] empty array it does not re calculate every time. Even the query results are same it still try to recalculate every time and making infinite request to backend.
But do you have any idea why this get function re-calculate all the time?
When something like this happens, it's because you're reading #tracked data that is changed later (maybe when the query finishes).
because getters are re-ran every access, you'll want to throw #cached on top of it,
// cached is available in ember-source 4.1+
// or as early as 3.13 via polyfill:
// https://github.com/ember-polyfills/ember-cached-decorator-polyfill
import { cached } from '#glimmer/tracking';
// ...
#cached
get <function_name>() {
return this.store.query(/* ... */);
}
this ensures a stable object reference on the getter that the body of the getter only re-evaluates if tracked data accessed within the getter is changed.
Weird thing is when results are [] empty array it does not re calculate every time. Even the query results are same it still try to recalculate every time and making infinite request to backend.
Given this observation, it's possible that when query finishes, that it's changing tracked data that it, itself is consuming during initial render -- in which case, you'd still have an infinite loop, even with #cached (because tracked-data is changing that was accessed during render).
To get around that is fairly hard in a getter.
Using a constructor is an ok solution for getting your initial data, but it means you opt out of reactive updates with your query (if you need those, like if the query changes or anything).
If you're using ember-source 3.25+ and you're wanting something a little easier to work with, maybe ember-data-resourecs suits your needs
the above code would be:
import { query } from 'ember-data-resources';
// ...
// in the class body
data = query(this, 'model name', () => ({ query stuff }));
docs here
This builds off some primitives from ember-resources which implement the Resource pattern, which will be making a strong appearance in the next edition of Ember.

Repeated use of OfflineTileProvider freezes app

I have an activity with a fragment which contains a MapView. The MapView uses an OfflineTileProvider, with tiles downloaded using the CacheManager. When entering and exiting the activity repeatedly, the app will sometimes freeze. Sometimes it happens after revisiting the activity once or twice, and sometimes it takes many more times(20 or more) before it freezes.
Every time I enter the activity there are two kinds of exceptions being thrown, the first one being:
Error loading tile
java.lang.IllegalStateException: Cannot perform this operation because the connection pool has been closed.
at android.database.sqlite.SQLiteConnectionPool.throwIfClosedLocked(SQLiteConnectionPool.java:962)
at android.database.sqlite.SQLiteConnectionPool.waitForConnection(SQLiteConnectionPool.java:677)
at android.database.sqlite.SQLiteConnectionPool.acquireConnection(SQLiteConnectionPool.java:348)
at android.database.sqlite.SQLiteSession.acquireConnection(SQLiteSession.java:894)
at android.database.sqlite.SQLiteSession.executeForCursorWindow(SQLiteSession.java:834)
at android.database.sqlite.SQLiteQuery.fillWindow(SQLiteQuery.java:62)
at android.database.sqlite.SQLiteCursor.fillWindow(SQLiteCursor.java:145)
at android.database.sqlite.SQLiteCursor.getCount(SQLiteCursor.java:134)
at org.osmdroid.tileprovider.modules.MapTileSqlCacheProvider$TileLoader.loadTile(MapTileSqlCacheProvider.java:209)
at org.osmdroid.tileprovider.modules.MapTileModuleProviderBase$TileLoader.run(MapTileModuleProviderBase.java:297)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
at java.lang.Thread.run(Thread.java:760)
and the second one:
Unable to store cached tile from Mapnik /0/0/0 db is null
java.lang.NullPointerException: Attempt to invoke virtual method 'int android.database.sqlite.SQLiteDatabase.delete(java.lang.String, java.lang.String, java.lang.String[])' on a null object reference
at org.osmdroid.tileprovider.modules.SqlTileWriter.saveFile(SqlTileWriter.java:175)
at org.osmdroid.tileprovider.modules.MapTileDownloader$TileLoader.loadTile(MapTileDownloader.java:251)
at org.osmdroid.tileprovider.modules.MapTileModuleProviderBase$TileLoader.run(MapTileModuleProviderBase.java:297)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
at java.lang.Thread.run(Thread.java:760)
Have anyone else had similar issues, or know what to do?
That's a fun one. Looks like a lifecycle/concurrency problem. It's possible that the old instances of the map fragment are still alive. You may be able to work around the issue by forcing android to execute now:
From osmdroid test/instrumentation package
fm.beginTransaction().replace(org.osmdroid.R.id.samples_container, basefrag, ExtraSamplesActivity.SAMPLES_FRAGMENT_TAG)
.addToBackStack(ExtraSamplesActivity.SAMPLES_FRAGMENT_TAG).commit();
fm.executePendingTransactions();
Basically, it forces the fragment transaction to happen immediately which should force the android lifecycle stuff to happen.
The other possibility is that you have a static reference to the map or something that's holding on to the map reference or your offline tile provider instance. Are any of those possible?
Edit: I just tested map in a fragment by loading and unloading the map a bunch of times and could not reproduce it. Are you programmatically creating the map or are you using xml layout?

Ember.js - Function finished before store is done

I'm building an ember app, and I keep running into the same problem where I make a call to the store, but the function keeps compiling before the store has retrieved the data from the backend. Specifically I'm having the problem with a findRecord. I've implemented it both ways:
var admin = this.store.findRecord('admin', 1);
console.log(admin.get('season'));
console.log('Are we here?');
and
this.store.findRecord('admin', 1).then(function(admin) {
console.log(admin.get('season'));
});
console.log('Are we here?');
In both cases, the Are we here? is logged BEFORE the season. Obviously the console logs are just for the example, and it creates an actual problem with what I'm trying to get done. Does anybody know a simple fix for this delay?
Thanks.
Of course it is. It's an asynchronous behavior. It takes some time to solve promise which is returned from findRecord(), thus the consequence is:
this.store.findRecord(); //synchronous
console.log('we are here'); //synchronous
in the meantime a promise returned from findRecord() gets resolved (asynchronous behavior)
console.log(admin.get('season'));
An asynchronous call will not stop your code from progressing, that´s the purpose of it. Else it would block UI updates and user interaction while loading data.

IsAwake always YES albeit SetSleepingAllowed

got a CClayer with many b2bodies and fixtures etc.
all b2_body objects are allowsleeping set to true. but they never sleeps.
notes:
all b2_body ‘s :setAwake are TRUE at initial creation.
all b2_body ‘s :setActive are TRUE at initial creation.
all fixture.friction is 0.001 or 0. no difference
got a custom simple Contact Listener class...
when I check the velocity via
b2Vec2 velocity = b->GetLinearVelocity();
velocity.Length();
is zero. but somehow b->IsAwake() is always YES.
it seems some of bodies are jiggling back and forth infititely with a very little bit velocities.
yes they are stacked.
what may be the reason ?or is there a method to fix this problemma ?
should I stop linear velocities of contact bodies in my custom contactClass ?or...
thank you.

2 computed properties based on the same dependency fire only once

Having 2 computed properties based on the same dependency only one computed property runs. The docs says that it is cached what about a situation when I'd like to have the following:
foo: (->
console.log 'foo'
).property('dependency')
bar: (->
console.log 'bar'
).property('dependency')
Now the bar isn't called and I have to resort to observer. Can I make it work?
Edit
The question is about computed properties but it wasn't reflected in the example code - instead of property I used observes. It is now changed. Sorry for confusion.
Edit#2
I modified the great example by #MilkyWayJoe so that it now looks like my solution. Unfortunately (or fortunately) it works, but my solution didn't. Here's the gist what I was after:
With the help of a slider I could set a balance value to be transferred to another credit card provider. Let's say that the value is transferValue. Whenever it changed I had to calculate the annual interest to which the transfer fee was added.
So for example let's say that in my current credit card I have $1000 and the annual interest rate is 19%. It's way too much so I look for another, cheaper solution. It turns out that Bank X offers Balance Transfer Credit Card Y which interest rate is 10% + 3.5% transfer fee.
OK. So I set $1000 on the slider and here goes the magic. I want to calculate interest rate and transfer fee whenever the value changes.
In the modified example it works: http://jsfiddle.net/gqSMU/2/
but failed to do so in my first solution. It was kind of this one:
cardInterest: (->
apr = #get 'purchaseRate'
amount = #get 'transferValue'
#get('calculatedTransferFee') + #calculateInterest apr, amount
).property('transferValue', 'calculatedTransferFee')
As you can see it accesses calculatedTransferFee. The problem was that the value wasn't recalculated. I'm not sure it is worth of mentioning but in the first solution only cardInterest was requested by Handlebars template.
And this is my current solution with observer:
calculatedTransferFee: 0
transferValueDidChange: (->
if #get('isCurrentCardChosen')
transferFee = parseFloat #get('balanceTransferRate') / 100
transferValue = #get 'transferValue'
calculatedTransferFee = if isNaN(transferFee) then 0 else transferFee * transferValue
#set 'calculatedTransferFee', calculatedTransferFee
).observes('transferValue')
It isn't a nice solution, is it? That's why I thought it may be a better solution than to resort to an observer.
I hope that now it is clearer. I'd be grateful for any further feedback!
Not quite sure if I understand what you're trying to achieve since you're talking about property but your code is using observes (I realize this is a conceptual sample code, just not sure where you're going).
Usually, property will be a "reactive accessor" to a value, and 99.9% of the time you want it to be cached (it is by default, unless you say .property('whatever').volatile()), while observe will fire a function when whatever property it is watching changes. If you just want to have two properties firing for the same dependency you could:
App.SomeModel = Em.Object.extend({
someDependency: true,
foo: function() {
// all that's in here will fire only once when 'dependency' changes, and store
// the returning value in cache, and every time something reads this property,
// it will retrieve the cached value.
// A way to test this, is to run the following from your View:
// "alert(this.controller.get('content.foo'));"
// It will alert the string but will not log "whatever bro" again.
console.log('whatever bro');
return "this.foo %# a dependency".fmt(this.get('someDependency') ? "has" : "doesn't have");
}.property('someDependency'),
bar: function() {
// same as above
console.log('whatever dude');
return "this.bar %# a dependency".fmt(this.get('someDependency') ? "has" : "doesn't have");
}.property('someDependency'),
nope: function() {
// same as above, except this is volatile
// and will fire the console.log every time
console.log('y\'all need science');
return "this.nope %# a dependency".fmt(this.get('someDependency') ? "has" : "doesn't have");
}.property('someDependency').volatile()
});
(see fiddle)
If you need it to be logged everytime (perhaps for debugging or whatever reason), you could use volatile or observes.
If I'm tripping and this's not what you want, perhaps you could rephrase your question or refresh the sample code to something closer to your real-life scenario to clarify what's being asked.