from backend count start form 0. and 0,1,2,3...... . For each count 10 product is showing
I have taken initially count = 0 like below
var currentCount: Int = 0
and added count perameter in JSON like below in service call: but here always shows only 10 products in collectionview... even if there are more products then also not showing.. why?
fileprivate func serviceCall(){
self.currentCount+=0
let param = ["jsonrpc": "2.0",
"params": ["type" : type, "count": currentCount]] as [String : Any]
APIReqeustManager.sharedInstance.serviceCall(param: param, vc: self, url: getUrl(of: .productByFeature), header: header) {(responseData) in
if self.currentCount > 0 {
self.viewmoreDB?.result?.products! += ViewMoreBase(dictionary: responseData.dict as NSDictionary? ?? NSDictionary())?.result?.products ?? [ViewMoreProducts]()
}
else{
self.viewmoreDB = ViewMoreBase(dictionary: responseData.dict as NSDictionary? ?? NSDictionary())
}
self.productsData = self.viewmoreDB?.result?.products
self.collectionView.reloadData()
}
}
and trying to use pagination like below at the end of the collectionview activity indicator is showing but if there are more products then also not loading
func scrollViewDidScroll(_ scrollView: UIScrollView) {
if scrollView == collectionView{
if (scrollView.contentOffset.y + scrollView.frame.size.height) == scrollView.contentSize.height {
serviceCall()
}
}
}
please do help
It could be any of may issues. One of the possible things is that you do not update currentCount when you get the data and your statement if self.currentCount > 0 always fails and the else part executes which means that data is not added but overwritten and you again have just one page of data.
If this is true you are probably missing currentCount = self.productsData.count or even better, you should simply make your currentCount as a computed property doing
var currentCount: Int { productsData?.count ?? 0 }
Since this is a guess a more appropriate answer is that you need to improve your skills when debugging. One of the widely used feature which is available in most modern IDEs is using breakpoints. In most IDEs you simply click left of the line you wish to put your breakpoint and an icon shows there. When your code executes with debugger it will stop at a breakpoint and you will be able to see all the information that is currently in the stack and you will be able to execute line by line to see what is going on. So in your case you could place a breakpoint at a first line after serviceCall and see which path the code takes you and why.
If using Xcode there is another feature that you can use WHILE stopped on breakpoint. You can use console on your bottom right of your IDE to print out values as chunks of code. So while stopped there you could enter "po self.currentCount" and you could see the count. More interesting would be to see things like "ViewMoreBase(dictionary: responseData.dict as NSDictionary? ?? NSDictionary())?.result?.products" to check if you get any products from the backend.
Related
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 5 hours ago.
Improve this question
I'm currently working on implementing MCTS for a game.
I have a method called
make_move
That looks like this:
(modified to be verbose for the sake of stackoverflow)
pub fn make_move(&mut self, index: usize, player: i8) -> MoveResult {
let mut result = MoveResult::Nothing;
// If the game is finished or the spot they're trying to play on is occupied set the result to be an error
// Otherwise make the move and return the result of that move (if someone won or if nothing happened)
if self.winner != 0 || self.board[index] != 0 {
self.display();
println!("Warning! Tried playing illegal move");
result = MoveResult::Error;
} else {
self.board[index] = player;
self.move_history.push(index);
result = self.check_for_win();
}
result
}
It uses this enumerator to return the result of a move
pub enum MoveResult {
// Completed meaning the move made the game over (either by win or draw)
Completed(i8),
Error,
Nothing
}
Originally, I just had a guard clause that returned an error for the first if statement, and then returned self.check_for_win() otherwise (which is always either Nothing or Completed). I've since modified it heavily in a desperate attempt to fix this bug.
The bug I'm referring to is when I use the method
let move_result = board.make_move(index, player);
move_result is always equal to either Nothing or Completed. It is never equal to Error.
In the terminal, it will even print out that there was an error, which means the if statement was true and the else shouldn't run, but it will still only return either Nothing or Completed.
I tried to check inside the method. If there was an error, the line before I return, I printed the value of result. And it printed it was equal to Error. But when I use the method and assign the return value to a variable, which I have confirmed through println's is of type Error, the variable is either Nothing or Completed!! It magically changes despite being equal to Error at every point in the process.
I have tried rewriting this method so many times in so many ways. It never works. I've been bashing my head into my keyboard all day and it simply will not cooperate. If anyone has any idea, I'd appreciate the help.
I cannot reproduce your error:
https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=cc3fc00a4cc4c486fd4d76b51f8f616d
#[derive(Debug, PartialEq)]
pub enum MoveResult {
// Completed meaning the move made the game over (either by win or draw)
Completed(i8),
Error,
Nothing
}
struct Game {
winner: i8,
board: Vec<i8>,
move_history: Vec<usize>
}
impl Game {
fn new(board_size: usize) -> Self {
Game{winner: 0, board: vec![0; board_size], move_history: Vec::new()}
}
fn check_for_win(&self) -> MoveResult {
MoveResult::Nothing // dummy because I don't know the win condition
}
fn display(&self) {
// pass
}
fn make_move(&mut self, index: usize, player: i8) -> MoveResult {
let mut result = MoveResult::Nothing;
// If the game is finished or the spot they're trying to play on is occupied set the result to be an error
// Otherwise make the move and return the result of that move (if someone won or if nothing happened)
if self.winner != 0 || self.board[index] != 0 {
self.display();
println!("Warning! Tried playing illegal move");
result = MoveResult::Error;
} else {
self.board[index] = player;
self.move_history.push(index);
result = self.check_for_win();
}
result
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn make_move_returns_error_when_winner_is_not_zero() {
let mut game = Game::new(10);
game.winner = 42;
let res = game.make_move(1, 2);
assert_eq!(res, MoveResult::Error);
}
#[test]
fn make_move_returns_error_when_playing_same_position_twice() {
let mut game = Game::new(10);
let res1 = game.make_move(1, 42);
assert_eq!(res1, MoveResult::Nothing);
let res2 = game.make_move(1, 55);
assert_eq!(res2, MoveResult::Error);
}
}
Of course all sorts of weird stuff might happen in your check_for_win method, but that method shouldn't even get executed if we're in the error-branch.
I am currently porting an UWP application from C++/CX to C++/WinRT. I encountered a safe_cast<Platform::IBoxArray<byte>^>(data) where data is of type Windows::Foundation::IInspectable ^.
I know that the safe_cast is represented by the as<T> method, and I know there are functions for boxing (winrt::box_value) and unboxing (winrt::unbox_value) in WinRT/C++.
However, I need to know the equivalent of Platform::IBoxArray in order to perform the cast (QueryInterface). According to https://learn.microsoft.com/de-de/cpp/cppcx/platform-iboxarray-interface?view=vs-2017, IBoxArray is the C++/CX equivalent of Windows::Foundation::IReferenceArray, but there is no winrt::Windows::Foundation::IReferenceArray...
Update for nackground: What I am trying to achieve is retrieving the view transform attached by the HoloLens to every Media Foundation sample from its camera. My code is based on https://github.com/Microsoft/HoloLensForCV, and I got really everything working except for this last step. The problem is located around this piece of code:
static const GUID MF_EXTENSION_VIEW_TRANSFORM = {
0x4e251fa4, 0x830f, 0x4770, 0x85, 0x9a, 0x4b, 0x8d, 0x99, 0xaa, 0x80, 0x9b
};
// ...
// In the event handler, which receives const winrt::Windows::Media::Capture::Frames::MediaFrameReader& sender:
auto frame = sender.TryAcquireLatestFrame();
// ...
if (frame.Properties().HasKey(MF_EXTENSION_VIEW_TRANSFORM)) {
auto /* IInspectable */ userData = frame.Properties().Lookup(MF_EXTENSION_VIEW_TRANSFORM);
// Now I would have to do the following:
// auto userBytes = safe_cast<Platform::IBoxArray<Byte> ^>(userData)->Value;
//viewTransform = *reinterpret_cast<float4x4 *>(userBytes.Data);
}
I'm also working on porting some code from HoloLensForCV to C++/WinRT. I came up with the following solution for a very similar case (but not the exact same line of code you ask about):
auto user_data = source.Info().Properties().Lookup(c_MF_MT_USER_DATA); // type documented as 'array of bytes'
auto source_name = user_data.as<Windows::Foundation::IReferenceArray<std::uint8_t>>(); // Trial and error to get the right specialization of IReferenceArray
winrt::com_array<std::uint8_t> arr;
source_name.GetUInt8Array(arr);
winrt::hstring source_name_str{ reinterpret_cast<wchar_t*>(arr.data()) };
Specifically, you can replace the safe_cast with .as<Windows::Foundation::IReferenceArray<std::uint8_t> for a boxed array of bytes. Then, I suspect doing the same cast as me (except to float4x4* instead of wchar_t*) will work for you.
The /ZW flag is not required for my example above.
I can't believe that actually worked, but using information from https://learn.microsoft.com/de-de/windows/uwp/cpp-and-winrt-apis/interop-winrt-cx, I came up with the following solution:
Enable "Consume Windows Runtime Extension" via /ZW and use the following conversion:
auto abi = reinterpret_cast<Platform::Object ^>(winrt::get_abi(userData));
auto userBytes = safe_cast<Platform::IBoxArray<byte> ^>(abi)->Value;
viewTransform = *reinterpret_cast<float4x4 *>(userBytes->Data);
Unfortunately, the solution has the drawback of generating
warning C4447: 'main' signature found without threading model. Consider using 'int main(Platform::Array^ args)'.
But for now, I can live with it ...
I would like to implement an infinite scroll populated by a very big json, within Angular 5. The idea is to show only the 5 first entries and then, when a user scroll, it shows the 5 more.
Now, I had a look on this : https://github.com/orizens/ngx-infinite-scroll but the array used for the view only take strings.
I had a look at an example : Plunker Example of ngx-infinite-scroll and what cause the problem is this :
addItems(startIndex, endIndex, _method) {
for (let i = 0; i < this.sum; ++i) {
this.array[_method]([i, ' ', this.generateWord()].join(''));
}
}
Where this.generateWord() only generate random strings and _method is push or unshift.
How could I push or concat parts of an object into this so I can still make it work with my *ngFor inside my html template ?
Any idea of a plugin that accept http request object or how to make ngx-infinite-scroll work ?
Thanks
Ok, I didn't follow "best practices" for the code layout and don't show how to actually get data from a server to populate it ... but I did answer the basic question of how to use an object instead of a string to display.
The result is here: https://stackblitz.com/edit/angular-a5ew8f
I just replaced the hard-coded string with entries from a hard-coded array:
addItems(startIndex, endIndex, _method) {
let movieIndex=0
for (let i = 0; i < this.sum; ++i) {
movieIndex++;
if (movieIndex >= this.movies.length) movieIndex=0;
this.array[_method](this.movies[movieIndex]);
}
}
In a real application, you would want to go to the server to get 'n' (this.sum) more items each time the addItems method is called.
How to take current view and set the view to orthographic?
I tried using viewer.getCamera() to get parameters how the view is currently set and then setting it with viewer.applyCamera().
var camera = viewer.getCamera();
console.log('Camera: ' + JSON.stringify(camera));
Which returns:
Camera: {
"metadata": {"version":4.3,"type":"Object","generator":"ObjectExporter"},
"object":{"uuid":"78D2EA86-853B-473F-9E0E-E3F0C8874E40",
"type":"Camera",
"matrix":[1,0,0,0,0,1,0.00009999999747378752,0,0,-0.00009999999747378752,1,0,114010.796875,88329.0078125,135503.609375,1],
"children":[
{"uuid":"53C7FA49-B00C-4616-9E7A-CCB94A661A45",
"type":"DirectionalLight",
"color":8355711,"intensity":0,
"matrix":1,0,0,0,0,1,0,0,0,0,1,0,-0.5,0.20000000298023224,0.05999999865889549,1]},
{
"uuid":"7D5EC244-7268-4190-8480-4BD1DD56F8CB",
"type":"Object3D","matrix":[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1]
}]}}
Then I tried setting, with the "matrix" array as params, but the view jumps.
viewer.setViewFromArray(params);
I followed the format of an array with the data from current camera and applied them by viewer.setViewFromArray. I kept all other parameters, but only set the last param to 1 (ortho).It looks working well at my side.
viewerApp.myCurrentViewer.setViewFromArray([
viewerApp.myCurrentViewer.getCamera().position.x,
viewerApp.myCurrentViewer.getCamera().position.y,
viewerApp.myCurrentViewer.getCamera().position.z,
viewerApp.myCurrentViewer.getCamera().target.x,
viewerApp.myCurrentViewer.getCamera().target.y,
viewerApp.myCurrentViewer.getCamera().target.z,
viewerApp.myCurrentViewer.getCamera().up.x,
viewerApp.myCurrentViewer.getCamera().up.y,
viewerApp.myCurrentViewer.getCamera().up.z,
viewerApp.myCurrentViewer.getCamera().aspect,
viewerApp.myCurrentViewer.getCamera().fov,
1,
1
]);
you can also check the source Viewer3D.js to get the workflow how setViewFromArray works.
Viewer3D.prototype.setViewFromArray = function(params, name){....}
IF you simply want to switch the view between perspective and orthographic, you can use the direct API:
Viewer.navigation.toOrthographic()
Viewer.navigation.toPerspective()
SKAction has waiting for duration abilities, for a period of time on a node. And seems to perform actions on nodes. Like moveTo, etc.
If I don't want that, rather I'd prefer to call functions within GameScene after a period of time, how do I do that with SpriteKit in the GameScene, not on a Sprite or other Node?
Are SKActions the way to do this? The only way to do this?
Yes. This question IS that ridiculously simple. I lack the heuristics and terminology to find an answer. Just keep looping around on how SKAction waits are calls on SKSprites for things like scale, rotation, etc, after time. Which isn't want I want/need.
Update:
Desired outcome, inside GameScene
doSetupStuff() // does some stuff...
waitForAWhile() // somehow wait, perhaps do somethings in here, while waiting
doSomethingElse() // does this after the waitForAWhile has waited
UPDATE 2:
What I think happens, again, inside didMove(to view...)
func wait(){
let timeToPause = SKAction.wait(forDuration: 3)
run(timeToPause)
}
let wontwait = SKAction.wait(forDuration: 3)
run(wontwait)
thisFunction(willnot: WAIT"it starts immediately")
wait()
thisFunction(forcedToWait: "for wait()'s nested action to complete")
UPDATE 3:
Found a way to get the delay without using SKActions. It's a little crude and brutal, but makes more sense to me than SKActions, so far:
DispatchQueue.main.asyncAfter(deadline: .now() + 10.0) {
print("I waited ten seconds before printing this!")
}
An option, as you cited, is to manage this externally. The way I typically manage this sort of thing is to have an externally run update cycle. One that
To drive this updater, you could use either CADisplayLink (which is what I use right now with my OpenGL renderer) or a dispatch source timer (which I have used with my SpriteKit engine). When you use an updated, you want to calculate the delta time. The tick handler could look something like:
func tickHandler() {
let currTime = NSDate().timeIntervalSince1970
let dt = lastTime - currTime // lastTime is a data member of the class
// Call all updaters here, pretend "updater" is a known updater class
updater.update(dt)
}
And updater's update method would look something like:
func update(deltaTime:NSTimeInterval) {
// Do your magic
}
I typically have a main overall updater running independent of what people are calling scenes. Example usage would be something like having an attract mode like in old school arcade games. There they show title screen, sample game play, high scores, rinse and repeat. Scenes would be title, game play, high score. Here you can your main updater manage the time and coordinate the construction/destruction/switching of the scenes. Note this implies having an overall scene manager (which is actually quite handy to have).
For your case, you could use this updater to drive the GameScene updater. It's updater could look something like:
func update(deltaTime:NSTimeInterval) {
switch state {
case .SetupState:
// noop?
println("I'm in setup") // Shown just so you can see there is a setup state
case .WaitState:
waitTime += deltaTime
if waitTime >= kWaitTime {
// Do whats you gots to do
doSomethingElse()
state = .NextState
}
case .NextState:
// blah blah blah blah
}
}
So the flow to do this call path from your driver (CADisplayLink or dispatch source) would be something like:
tickHandler -> master updater -> game scene updater
Some will def find this is perhaps a little heavy handed. I, on the other hand, find this very helpful. While there is obviously some time management and the loss of being able to fire and forget, it can help provide more control for orchestrating pieces, as well as arbitrarily changing state without having to worry about killing already queued actions. There is also nothing that says you still cannot mix SKAction. When I did use SpriteKit, I did all my updating this way along with some dispatched items. I only used SKAction to update hierarchy. Keep in mind that I used my own animation and physics system. So at least for me I had a lot less dependency on SpriteKit (it effectively was just a renderer for me).
Note you have to have your own means to handle pause and coming to foreground where your timer will need to be resynced (you only need to worry about tickHandler). Breakpoints also will cause time jumps.
You can use below function
#define ANIM_TIME 2
SKAction *customACtion = [SKAction customActionWithDuration: ANIM_TIME actionBlock:^(SKNode *node, CGFloat elapsedTime) {
// Do Something Here
}];
Another way to make something happen after a certain period of time is to make use of the 'current time' parm passed to update(). The following code will spawn a boss at intervals ranging from 20 to 30 seconds.
In your property definitions:
var timeOfLastBoss: CFTimeInterval = -1 //Indicate no boss yet
var timePerBoss = CFTimeInterval()
.
.
.
didMoveToView() {
...
timePerBoss = CFTimeInterval(Int.random(20...30))
'''
}
.
.
.
func update(currentTime: CFTimeInterval) {
...
spawnBossForUpdate(currentTime)
...
}
'
'
'
func spawnBossForUpdate(currentTime : CFTimeInterval) {
if ( timeOfLastBoss == -1 ) {timeOfLastBoss = currentTime}
if (currentTime - timeOfLastBoss < timePerBoss) {return}
// Rest of 'spawnBoss code
self.timePerBoss = CFTimeInterval(Int.random(20...30))
self.timeOfLastBoss = currentTime
}
One way, using SKActions, in Swift 3.0, looks like this:
DEFINE: aPatientlyWaitingFunction() at the top level of
GameScene class.
To cause a delay to happen before calling the above function, inside
didMove(to view...)
three ways I've found to do this using Actions:
All three ways seem to accomplish the exact same thing:
let timeToWait: TimeInterval = 3 // is seconds in SKAction thinking time
let waitSomeTime = SKAction.wait(forDuration: timeToWait)
// 1st way __________________________________________
// with a completion handler, the function can be called after Action
run(waitSomeTime) {self.aPatientlyWaitingFunction()}
// 2nd way __________________________________________
// as a completion to be done after action, in the run invocation:
run(waitSomeTime, completion: aPatientlyWaitingFunction)
// 3rd way __________________________________________
// alternatively, as part of a sequence of actions...
// Create a sequence, by making a run action from waitSomeTime and...
let thenDoThis = SKAction.run(aPatientlyWaitingFunction)
// then activate sequence, which does one action, then the next
run(SKAction.sequence([waitSomeTime, thenDoThis]))
// OR... for something different ____________________
////////////////////////////////////////////////////////
DispatchQueue.main.asyncAfter(deadline: .now() + timeToWait) {
self.aPatientlyWaitingFunction()
print("DispatchQueue waited for 3 seconds")
}