How do you add an if statement to a TimerComponent in Flame Game Flutter? - flutter

I'm trying to add code to my Flame Game to check if a list isn't empty and if it isn't, then send it to a function. However, I'm receiving an error on the if statement that says "Expected an identifier". How do I change my code to run an if statement here? Additionally, how would I cancel the Timer after it runs?
var instructions = [];
myGame(){
add(
TimerComponent(period: 2, repeat: true, onTick: () =>
if(instructions != null){populateInfo(instructions)}),
);
}

You can use runtimeType, Use runtimeType to get the runtime type.
A property of the Object class, which is the base class of all objects in Dart, and of type Type.
for (final element in gameRef.children) {
if (element.runtimeType == Instructions) {
//my element exist in the scene
}
}
I used the last code for explain the use of runtimeType, but with Dart you have more options like to
children.query<Intructions>();

Related

Understanding binding and selection in Word Add-in

I'm trying to build an add-in with similar behaviour like the comment system.
I select a part of text.
Press a button in my add-in. A card is created that links to that text.
I do something else, like write text on a different position.
When I press the card in my add-in, I'd like to jump back to the selected text (in point 1).
I studied the API, documentation. And learned that I could do something like that with Bindings. A contentcontrol might also be an option, although I noticed that you can't connect and eventhandler (it's in beta). I might need an eventhandler to track changes later.
Create binding (step 2)
Office.context.document.bindings.addFromSelectionAsync(Office.BindingType.Text, { id: 'MyBinding' }, (asyncResult) => {
if (asyncResult.status == Office.AsyncResultStatus.Failed) {
console.log('Action failed. Error: ' + asyncResult.error.message);
} else {
console.log('Added new binding with id: ' + asyncResult.value.id);
}
});
Works. Then I click somewhere else in my document, to continue with step 4.
View binding (step 4).
So I click the card and what to jump back to that text binding, with the binding selected.
I figured there are multiple ways.
Method #1
Use the Office.select function below logs the text contents of the binding. However, it doesn't select that text in the document.
Office.select("bindings#MyBinding").getDataAsync(function (asyncResult) {
if (asyncResult.status == Office.AsyncResultStatus.Failed) {
}
else {
console.log(asyncResult.value);
}
});
Method #2
Use the GoToById function to jump to the binding.
Office.context.document.goToByIdAsync("MyBinding", Office.GoToType.Binding, function (asyncResult) {
let val = asyncResult.value;
console.log(val);
});
This shows like a blue like frame around the text that was previously selected and puts the cursor at the start.
I'd prefer that I don't see that frame (no idea if that's possible) and I would like to the text selected.
There is the Office.GoToByIdOptions interface that mentions:
In Word: Office.SelectionMode.Selected selects all content in the binding.
I don't understand how pass that option in the function call though and I can't find an example. Can I use this interface to get the selection?
https://learn.microsoft.com/en-us/javascript/api/office/office.document?view=common-js-preview#office-office-document-gotobyidasync-member(1)
goToByIdAsync(id, goToType, options, callback)
If there are other ways to do this, I'd like to know that as well.
With some help I could figure it out. I learned that an Interface is just an object.
So in this case:
const options = {
selectionMode: Office.SelectionMode.Selected
};
Office.context.document.goToByIdAsync("MyBinding", Office.GoToType.Binding, options, function (asyncResult) {
console.log(asyncResult);
});
This gives the selected result.
Sure someone can provide a better answer than this, as it's unfamiliar territory for me, but...
When you create a Binding from the Selection in Word, you're going to get a Content Control anyway. So to avoid having something that looks like a content control with the blue box, you either have to modify the control's display or you have to find some other way to reference a region of your document. In the traditional Word Object model, you could use a bookmark, for example. But the office-js APIs do not seem very interested in them.
However, when you create a Binding, which is an Office object, you don't get immediate access to the Content Control's properties (since that's a Word object). So instead of creating the Binding then trying to modify the Content Control, you may be better off creating the Content Control then Binding to it.
Something like this:
async function markTarget() {
Word.run(async (context) => {
const cc = context.document.getSelection().insertContentControl();
// "Hidden" means you don't get the "Bounding Box"
// (blue box with Title), or the Start/End tag view
cc.appearance = "Hidden";
// Provide a Title so we have a Name to bind to
cc.title = "myCC";
// If you don't want users changing the content, you
// could uncomment the following line
//cc.cannotDelete = true;
return context.sync()
.then(
() => {
console.log("Content control inserted");
// Now create a binding using the named item
Office.context.document.bindings.addFromNamedItemAsync("myCC",
Office.BindingType.Text,
{ id: 'MyBinding' });
},
() => console.log("Content control insertion failed")
).then(
() => console.log("Added new binding"),
() => console.log("Binding creation failed")
)
});
}
So why not just create the ContentControl, name it, and then you should be able to select it later using its Title, right? Well, getting the "data" from a control is one thing. Actually selecting it doesn't seem straightforward in the API, whereas Selecting a Binding seems to be.
So this code is pretty similar to your approach, but adds the parameter to select the whole text. The syntax for that is really the same syntax as { id: 'MyBinding' } in the code you already have.
function selectTarget() {
Office.context.document.goToByIdAsync(
"MyBinding",
Office.GoToType.Binding,
{ selectionMode: Office.SelectionMode.Selected },
function(asyncResult) {
let val = asyncResult.value;
console.log(val);
}
);
}
Both the Binding and the ContentControl (and its Title) are persisted when you save/reopen the document. In this case, the Binding is persisted as a piece of XML that stores the type ("text"), name ("MyBinding") and a reference to the internal ID of the content control, which is a 32-bit number, although that is not immediately obvious when you look at the XML - in an example here, the Id Word stores for the ContentControl is -122165626, but "Office" stores the ID for the Binding as 4172801670, but that's because they are using the two different two's complement representations of the same number.

Flutter : How to use setter to reset value

I have variable called to totalQuantity in provider:
get totalQuantity => total_quantity();
total_quantity() {
var totalQty = 0;
for (var x in myCart) {
totalQty += (x.quantity);
}
return totalQty;
}
I use it in the app bar:
child: Text('${prod.totalQuantity}',
I have a logout function I want when I pressed on it to reset totalQuantity, I guess using setter for that in provider, but I don't know how to do that.
IconButton(
onPressed: () {
prod.clear_myCart();
loginProd.log_out();
// ----------------- I want to reset it here
},
I found my mistake ,I forgot to add listen notifier
void clear_myCart() {
myCart.clear();
notifyListeners();
}
after I add it ,it works fine
I understand that you want to return totalQuantity to the original (empty) value, so lets have a look at where it gets its value from:
Your total_quantity() function depends on one variable, myCart.
So, if you clear myCart in prod.clear_myCart();, the quantity should also be updated accordingly.
Now, what your code does not show is how the value change of myCart is being handled in your code;
I am speculating here because your code snippets don't provide enough information, but your ChangeNotifier might just not call notifyListeners() when you call prod.clear_myCart(); (See https://flutter.dev/docs/development/data-and-backend/state-mgmt/simple).

Update a series of variable in SetState() efficiently (Dart-Flutter)

I can't find a simple way to update a series of variables in my Flutter project.
I first tried using Enums and functions to change the variables inside a setState((){}) call.
I have something like this:
void changeMode(Mode mode) {
if (mode == Mode.start) {
print('App is now in start mode');
mode = Mode.start;
bool1 = true;
bool2 = false;
bool3 = false;
color1 = kAColor1;
color2 = kAColor2;
} else if ...}
But nothing gets updated, I imagine it's due the fact that my function doesn't return anything.
If I hard code every single variable in setState((){}) it works fine, but it's absolutely inefficient and a mess to correct.
Maybe I should go with classes? Would I need to create a superclass containing all the subclasses to do something like this?
Every time that you call setState you UI will rebuild. You can use class or map to manipulate your data.
With class:
setState(() {
currentData = actualData.copyWith(bool1: false)
})
This way, you change only data that is different from currentData. On this example, I maintain all information from currentData and change only bool1 value.
Obs: copyWith is a factory that return the same type of
currentData.

Best practice for testing for data-testid in a nested component with React Testing Library?

I'm trying to write a test to check if my app is rendering correctly. On the initial page Ive added a data-testid of "start". So my top level test checks that the initial component has been rendered.
import React from "react";
import { render } from "react-testing-library";
import App from "../App";
test("App - Check the choose form is rendered", () => {
const wrapper = render(<App />);
const start = wrapper.getByTestId("start");
// console.log(start)
// start.debug();
});
If I console.log(start) the I can see all the properties of the node. However if I try and debug() then it errors saying it's not a function.
My test above does seem to work. If I change the getByTestId from start to anything else then it does error. But I'm not using the expect function so am I violating best practices?
There are two parts to this question -
Why console.log(start) works and why not start.debug()?
getByTestId returns an HTMLElement. When you use console.log(start), the HTMLElement details are logged. But an HTMLElement does not have debug function. Instead, react-testing-library provides you with a debug function when you use render to render a component. So instead of using start.debug(), you should use wrapper.debug().
Because you don't have an expect function, is it a good practice to write such tests ?
I am not sure about what could be a great answer to this, but I will tell the way I use it. There are two variants for getting an element using data-testid - getByTestId and queryByTestId. The difference is that getByTestId throws error if an element with the test id is not found whereas queryByTestId returns null in such case. This means that getByTestId in itself is an assertion for presence of element. So having another expect which checks if the element was found or not will be redundant in case you are using getByTestId. I would rather use queryByTestId if I am to assert the presence/absence of an element. Example below -
test("App - Check the "Submit" button is rendered", () => {
const { queryByTestId } = render(<App />)
expect(queryByTestId('submit')).toBeTruthy()
});
I would use getByTestId in such tests where I know that the element is present and we have expects for the element's properties (not on the element's presence/absence). Example below -
test("App - Check the "Submit" button is disabled by default", () => {
const { getByTestId } = render(<App />)
expect(getByTestId('submit')).toHaveClass('disabled')
});
In the above test, if getByTestId is not able to find the submit button, it fails by throwing an error, and does not execute the toHaveClass. Here we don't need to test for presence/absence of the element, as this test is concerned only with the "disabled" state of the button.

targeting sprites from a method in the document class - null object reference

I am trying to code a flash app entirely in the document class. I am using GestureWorks with a touch screen. When a user essentially presses a button it calls a method that should hide a specific graphic but not the graphic they touched.
Essentially I need a way to refer to a graphic on the screen using a method besides 'e.target'.
I am receiving this error: Error #1009: Cannot access a property or method of a null object reference.
//This code works
private function photo1SpriteFlickHandler(e:GestureEvent):void {
var openTween:Tween = new Tween(e.target, "x", Strong.easeOut, 232, 970, 5, true);
}
//this code gives me a null object reference
private function photo1SpriteFlickHandler(e:GestureEvent):void {
var openTween:Tween = new Tween(photo1Sprite, "x", Strong.easeOut, 232, 970, 5, true);
}
//photo1Sprite has already been programatically added to the screen as so:
var photo1Sprite = new TouchSprite();
var photo1Loader=new Loader();
photo1Loader.load(new URLRequest("media/photos1/photo1.jpg"));
photo1Loader.contentLoaderInfo.addEventListener(Event.COMPLETE,loaderComplete);
photo1Sprite.x = 232;
photo1Sprite.y = 538;
photo1Sprite.scaleX = .3;
photo1Sprite.scaleY = .3;
photo1Sprite.blobContainerEnabled = true;
photo1Sprite.addEventListener(TouchEvent.TOUCH_DOWN, startDrag_Press);
photo1Sprite.addEventListener(TouchEvent.TOUCH_UP, stopDrag_Release);
photo1Sprite.addChild(photo1Loader);
addChild(photo1Sprite);
It can access photo1Sprite as 'e.target' when the button click happens on the photo1Sprite.
The problem happens when to click one button (not photo1Sprite) and have it effect photo1Sprite.
So I can make photo1Sprite react if my method is attached to it directly using 'e.target' but not if I am trying to call it from a method that was called from another element on the screen.
I'm not sure what the Tween class constructor expects as it first argument. Is it a Sprite instance or is it the name of a Sprite instance? In any case make sure that - in the context of photo1SpriteFlickHandler - photo1Sprite is 1) defined! and 2) refers to the correct thing.