How does one move items up in the stack?
(Pseudocode, because the code inside and the registers to push will vary.)
push registers to stack
alter the registers
get return value on top of the stack
keep the top of the stack but restore the registers
So the stack looks like this:
(Top)
(Return value)
(Register)
(Register)
...
(Register)
And I want to make it look like this:
(Top)
(Return value)
And then have the registers get their values from the stack. Is this at all possible? I am trying to do it in gas. Can this be done? Thank you in advance.
If I understand correctly, you want to put a return value (which you get from...?) before the registers on the stack, then pop the registers, but keep the return value?
One suggestion I could give is to make room for your return value on the stack first (like subl $4, %esp, in case your return value is 4 bytes) and then put your return value there, instead of on top of the stack.
Another suggestion (which may be easier to implement), is to make some room in the .datasection with .skip, move the return value there, and then after restoring the registers move it back to the stack.
It's hard to give you a concrete example, since I don't know much about the scenario.
Related
So I need to check if the stack is empty before returning a value that is being calculated.
if its not empty, then I will raise an error.
How can I check if the stack is empty or not?
Compare $sp with null, how?
or if starting address of $sp is always the same, should I hard code it? (if address of $sp equal to 270346..3, then empty) (this feels very wrong)
Any help would be appreciated
Thanks
You should never check if the call stack is "empty" — this concept doesn't really make sense — the call stack is supposed to always be there.
However, if you are pushing a dynamic number of things onto the stack, and later popping them all of them off, you can either:
Capture the value of stack pointer before any of the dynamic pushing, and then as part of dynamic popping compare the current stack pointer with that previously captured stack pointer — when they are equal, there's nothing to pop.
Alternately, start a count at zero before any dynamic pushing, and add to that count as items are pushed, decrement the count as they are popped — whenever the count is zero, then there's nothing to pop.
On the other hand, if you are writing a program that takes control directly from the simulator or from the operating system, these are special in that there is no one to return to. Because of this, usually we use custom startup code for that, and such startup code is not a classic function.
Any code that is written as a function can assume that it was called, and thus can return to its caller.
I'm trying to give a widget far down in the widget tree absolute positions. Because it is somewhere down in the widget tree, it is most likely that there will be certain layout constraints set by its ancestors. I'm looking for something that can ignore those constraints and just use absolute coordinates.
If the explanation is confusing, I drew a little scheme of something that represents my wanted outcome:
I tried doing this using a Stack, but that makes it difficult to pass in absolute coordinates, even with a Positioned because setting the property left: 0.0 would use relative coordinates to the ancestor. So setting it to zero would not necessarily mean that the widget would be positioned at the top left of the screen.
I also tried using an Overlay but I the results are pretty much the same as with the Stack implementation.
What is the recommended way of doing this in Flutter?
I'll describe two ways to do this, but I won't provide the code or an example as I don't think putting this out there in a copy-paste-able way is necessarily a good idea - I agree with #Remi's comment that if you need to do this in an app, there's a good chance that the app could be refactored to avoid it. However, there is a way to do this - although be warned, it might cause some problems with things such as touch events (although I think there's ways to get around that - see AbsorbPointer and IgnorePointer for starting points). Since you haven't really explained what you want this for, I'm going to assume that isn't something you need.
I would encourage you to look into other ways of doing whatever you're trying to do and ask if you'd like help figuring out that better way.
Anyways, on to the good stuff =P :
Method # 1 - using an existing overlay:
I have actually used this method myself for a modal loading indicator which I want to persist while between pages underneath are being pushed and which can be called from anywhere within an app without requiring any widgets be in the tree above it. That's a very specific use-case though which I think justifies this usage.
Basically, you want to use an Overlay, but instead of creating your own (which will have the same size as the widget you're dealing with), you want to use an existing one. If you're using a MaterialApp, WidgetApp, or even just a Navigator somewhere in your app, you have an Overlay already which is almost for sure the same size as the screen. If you have multiple layers of overlays, you want to get the one at the top as that's the most likely to cover the entire screen.
To get access to it, you can use OverlayState rootOverlay = context.rootAncestorStateOfType(const TypeMatcher<OverlayState>()); to get ahold of the root overlay (you'll probably want to assert that it actually found one).
Once you have access to it, you can make an OverlayEntry which builds whatever your widget is, and call rootOverlay.insert(...) to add it. The item built by your OverlayEntry will be positioned from the top left and to the extent of the screen so long as the overlay itself covers the entire screen (you can do the offset yourself). You'll also want to make sure you rootOverlay.remove(...) at some point, which means keeping a reference to the OverlayEntry. I'd personally create a class called OverlayInsertionManager or something which keeps track of the overlay entry and does insertion/removal.
Method #2 - using your own widget
I would consider this way of doing it slightly cleaner if you're just doing it within your own app, although still probably not a great idea.
Basically, what you want to do is create a Stateful Widget high up in your app - above anything that would take up space on the screen. This could theoretically mean above your MaterialApp/WidgetApp/etc although that might cause problems for you if you're using theme/text directionality/etc that WidgetApp provides. I think you can use the WidgetApp.builder to place your widget where you need it. Let's call it PageOverlay for convenience (with a corresponding PageOverlayState.
In your widget you'll have a static of method like the following (these are littered throughout flutter's source code and are more or less a convention):
static PageOverlayState of(BuildContext context) {
final PageOverlayState result = context.ancestorStateOfType(const TypeMatcher<PageOverlayState>());
assert(() {
if (result == null) {
throw new FlutterError(
'No Overlay widget found.\n'
);
}
return true;
}());
return result;
}
Within your PageOverlayState, you're going to have a variable something like WidgetBuilder _overlayBuidler which is normally null, and a method/setter something like set overlayBuilder(WidgetBuilder overlayBuilder) => setState(() => _overlayBuilder = overlayBuilder);
In the PageOverlayState's builder, you'll create a Stack; the first child will be the child you get passed into the WidgetApp.builder or MaterialApp.builder. You'll only create a second child if _overlayBuilder is not null; if it is not null the second child should be something like new Builder(builder: _overlayBuilder).
You might have to do something around sizing the stack properly (i.e. put it in an Expanded or something).
I give an example:
I am using two view controllers, lets name it Home and Sales. Firstly, i navigate from Home To Sales using push. In Sales view controller i have globally declared an int value and assign it to zero. Like this:
int example_int = 0;
After that, there is some process that going in Sales View Controller, and example_int value changed, for example it has value of 2. Next, it navigate back to Home using pop. For testing purpose, i navigate back to Sales and i NSLog example_int, it gave the same value of 2.
This gave me problem initially. But i have solved it by using func: viewWillDismiss and assign the example_int to 0(default value). So for now, i m just curios what is going on here.Thank you.
The global variable will persist through out the app life cycle, if the use of example_int variable is limited to sales view than in that case you should create example_int as the member variable of sales view controller. If at all there is a requirement to keep the example_int variable as global than in that case you need to reset the value of example_int to 0 as per your requirement (in your case inside viewDidDisappear or viewDidUnLoad methods of sales view controller).
I've been reading about Clean Architecture from Robert Martin and more specifically about VIPER.
Then I ran into this article/post Brigade’s Experience Using an MVC Alternative which describes pretty much what I'm currently doing.
After actually trying to implement VIPER on a new iOS project, I've ran into some questions:
Is it ok for the presenter to query information in the view or should the "information passing" always start from the view?
For example, if the view triggered some action in the presenter, but then, depending on the parameters passed through that action, the presenter might need more information.
What I mean is: the user tapped “doneWithState:”, if state == “something”, get information from the view to create an entity, if state == “something else”, animate something in the view. How should I handle this kind of scenario?
Lets say a "module" (group of VIPER components) decide to present another module modally. Who should be responsible for deciding if the second module will be presented modally, the first module's wireframe or the second module's wireframe?
Also, lets say the second module's view is pushed into a navigation controller, how should the "back" action be handled? Should I manually set a "back" button with an action in the second module's view controller, that calls the presenter, that calls the second module's wireframe that dismiss and tells the first module's wireframe that it was dismissed so that the first module's view controller might want to display something?
Should the different modules talk only through the wireframe or also via delegates between presenters? For example if the app navigated to a different module, but after that the user pressed "cancel" or "save" and that choice needs to go back and change something in the first module (maybe display an animation that it was saved or remove something).
Lets say a pin was selected on a map, than the PinEditViewController is displayed. When going back, the selected pin's color might need to change depending on use actions on the PinEditViewController. Who should keep the state of the current selected pin, the MapViewController, the MapPresenter or the MapWireframe in order for me to know, when going back, which pin should change color?
1. May the Presenter query information from the view
To answer this to your satisfaction, we need more details about the particular case. Why can't the view provide more context information directly upon callback?
I suggest you pass the Presenter a Command object so the Presenter doesn't have to know what to do in which case. The Presenter can execute the object's method, passing in some information on its own if needed, without knowing anything about the view's state (and thus introducing high coupling to it).
View is in a state you call x (opposed to y and z). It knows about its state anyway.
User finishes the action. View informs its delegate (Presenter) about being finished. Because it is so involved, it constructs a Data Transfer Object to hold all usual information. One of this DTO's attributes is a id<FollowUpCommand> followUpCommand. View creates a XFollowUpCommand (opposed to YFollowUpCommand and ZFollowUpCommand) and sets its parameters accordingly, then putting it into the DTO.
Presenter receives the method call. It does something with the data no matter what concrete FollowUpCommand is there. Then it executes the protocol's only method, followUpCommand.followUp. The concrete implementation will know what to do.
If you have to do a switch-case/if-else on some property, most of the time it'd help to model the options as objects inheriting from a common protocol and pass the objects instead of the state.
2. Modal Module
Should the presenting module or the presented module decide if it's modal? -- The presented module (the second one) should decide as long as it's designed to be used modally only. Put knowledge about a thing in the thing itself. If its presentation mode depends on the context, well, then the module itself can't decide.
The second module's wireframe will receive message like this:
[secondWireframe presentYourStuffIn:self.viewController]
The parameter is the object for which presentation should take place. You may pass along a asModal parameter, too, if the module is designed to be used in both ways. If there's only one way to do it, put this information into the affected module (the one presented) itself.
It will then do something like:
- (void)presentYourStuffIn:(UIViewController)viewController {
// set up module2ViewController
[self.presenter configureUserInterfaceForPresentation:module2ViewController];
// Assuming the modal transition is set up in your Storyboard
[viewController presentViewController:module2ViewController animated:YES completion:nil];
self.presentingViewController = viewController;
}
If you use Storyboard Segues, you'll have to do things a bit differently.
3. Navigation hierarchy
Also, lets say the second module's view is pushed into a navigation controller, how should the "back" action be handled?
If you go "all VIPER", yes, you have to get from the view to its wireframe and route to another wireframe.
To pass data back from the presented module ("Second") to the presenting module ("First"), add SecondDelegate and implement it in FirstPresenter. Before the presented module pops, it sends a message to SecondDelegate to notify about the outcome.
"Don't fight the framework", though. Maybe you can leverage some of the navigation controller niceties by sacrificing VIPER pure-ness. Segues are a step into the direction of a routing mechanism already. Look at VTDAddWireframe for UIViewControllerTransitioningDelegate methods in a wireframe which introduce custom animations. Maybe this is of help:
- (id<UIViewControllerAnimatedTransitioning>)animationControllerForDismissedController:(UIViewController *)dismissed
{
return [[VTDAddDismissalTransition alloc] init];
}
- (id<UIViewControllerAnimatedTransitioning>)animationControllerForPresentedController:(UIViewController *)presented
presentingController:(UIViewController *)presenting
sourceController:(UIViewController *)source
{
return [[VTDAddPresentationTransition alloc] init];
}
I first thought that you'd need to keep a stack of wireframes similar to the navigation stack, and that all "active" module's wireframes are linked to one another. But this isn't the case. The wireframes manage the module's contents, but the navigation stack is the only stack in place representing which view controller is visible.
4. Message flows
Should the different modules talk only through the wireframe or also via delegates between presenters?
If you directly send another module B's object a message from Presenter A, what should happen then?
Since the receiver's view is not visible, an animation cannot start, for example. The Presenter still has to wait for the Wireframe/Router. So it has to enqueue the animation until it becomes active again. This makes the Presenter more stateful, which makes it harder to work with.
Architecture-wise, think about the role the modules play. In Ports/Adapters architecture, from which Clean Architecture burrows some concepts, the problem is more evident. As an analogy: a computer has many ports. The USB port cannot communicate with the LAN port. Every flow of information has to be routed through the core.
What's at the core of your app?
Do you have a Domain Model? Do you have a set of services which are queried from various modules? VIPER modules center around the view. The stuff modules share, like data access mechanisms, don't belong to a particular module. That's what you may call the core. There, you should perform data changes. If another module becomes visible, it pulls in the changed data.
For mere animation purposes, though, let the router know what to do and issue a command to the Presenter depending on the module change.
In VIPER Todo sample code:
The "List" is the root view.
An "Add" view is presented on top of the list view.
ListPresenter implements AddModuleDelegate. If the "Add" module is finished, ListPresenter will know, not its wireframe because the view is already in the navigation stack.
5. Keeping state
Who should keep the state of the current selected pin, the MapViewController, the MapPresenter or the MapWireframe in order for me to know, when going back, which pin should change color?
None. Avoid statefulness in your view module services to reduce cost of maintaining your code. Instead, try to figure out whether you could pass a representation of the pin changes around during changes.
Try to reach for the Entities to obtain state (through Presenter and Interactor and whatnot).
This doesn't mean that you create a Pin object in your view layer, pass it from view controller to view controller, change its properties, and then send it back to reflect changes. Would a NSDictionary with serialized changes do? You can put the new color in there and send it from the PinEditViewController back to its Presenter which issues a change in the MapViewController.
Now I cheated: MapViewController needs to have state. It needs to know all pins. Then I suggested you pass a change dictionary around so MapViewController knows what to do.
But how do you identify the affected pin?
Every pin might have its own ID. Maybe this ID is just its location on the map. Maybe it's its index in a pin array. You need some kind of identifier in any case. Or you create an identifiable wrapper object which holds on to a pin itself for the duration of the operation. (That sounds too ridiculous for the purpose of changing the color, though.)
Sending Events to Change State
VIPER is very Service-based. There are lots of mostly stateless objects tied together to pass messages along and transform data. In the post by Brigade Engineering, a data-centric approach is shown, too.
Entities are in a rather thin layer. On the opposite of the spectrum I have in mind lies a Domain Model. This pattern isn't necessary for every app. Modeling the core of your app in a similar fashion may be beneficial to answer some of your questions, though.
As opposed to Entities as data containers into which everyone might reach through "data managers", a Domain protects its Entities. A Domain will inform about changes proactively, too. (Through NSNotificationCenter, for starters. Less so through command-like direct message calls.)
Now this might be suitable for your Pin case, too:
PinEditViewController changes the pin color. This is a change in a UI component.
The UI component change corresponds to a change in your underlying model. You perform the changes through the VIPER module stack. (Do you persist the colors? If not, the Pin Entity is always short-lived, but it's still an Entity because its identity matters, not just its values.)
The corresponding Pin has changed color and publishes a notification through NSNotificationCenter.
By happenstance (that is, Pin doesn't know), some Interactor subscribes to these notifications and changes its view's appearance.
Although this might work for your case, too, I think tying the edit
This answer may be a bit unrelated, but I'm putting it here for reference. The site Clean Swift is an excellent implementation of Uncle Bob's "Clean Architecture" in swift. The owner calls it VIP (it still contains the "Entities" and the Router/wireframe though).
The site gives you XCode templates. So let's say you want to create a new scene (he calls a VIPER modules, "scenes"), All you do is File->new->sceneTemplate.
This template creates a batch of 7 files containing all the headache of the boilerplate code for your project. It also configures them so that they work out of the box. The site gives a pretty thorough explanation of how every thing fits together.
With all the boiler plate code out of the way, finding solutions the questions you asked above is a bit easier. Also, the templates allow for consistency across the board.
EDIT -> In regards to the comments below, here's an explanation as to why I support this approach -> http://stringerstheory.net/the-clean-er-architecture-for-ios-apps/
Also this one -> The Good, the bad, and the Ugly about VIPER in iOS
Most of your questions are answered on this post: https://www.ckl.io/blog/best-practices-viper-architecture (sample project included). I suggest you pay special attention to the tips for Modules initialization/presentation: it's up to the source Router to do it.
Regarding back buttons, you can use delegates to trigger this message to the desired module. This is how I do it and it works great (even after you insert push notifications).
And yes, modules can definitely talk to each other by using delegates as well. It's a must for more complex projects.
Now, yes, there are hundreds of questions (and answers) of how to perform custom segues. However, and I'm no exaggerating, ALL of these answers are wrong (all 50+ I've seen)! Sorry, this might sound harsh, but the truth is, NONE of the suggested answers gives the same (correct) result as Apples built in transitions do (vertical cover etc.).
To be more specific, this is the result that's expected (confirmed with logs):
Segue begins (adds view to hierarchy, invokes viewWillAppear on destinationVC and viewWillDisappear on sourceVC and starts animation).
animation is performed for the whole duration
Segue ends (animation finished, sets the destinationVC as the current VC, either on stack or modally presented. Invokes viewDidAppear on destinationVC and viewDidDisappear on sourceVC).
In short: invoke viewWillAppear/Disappear -> animate transition -> invoke viewDidAppear/Disappear
Using apples built-in segues, this is the expected behavior but somehow not a single soul except me have had issues with this. A lot of versions even add the destination-view as subview first, animates it then removes it again and calls
[srcVC presentModalViewController:destVC animated:NO];
or
[srcVC.navigationController pushViewController:destVC animated:NO];
causing the view-events to be sent in all kinds of random order (same issue with CoreAnimations).
In my case, all I really want is the "Vertical Cover"-transition reverted (top to bottom), with all other events sent EXACTLY as expected (shown above).
So, am I just supposed to live with all kinds of ugly workarounds (doing my "tasks" in hard-coded methods called whenever I need them to etc.), or is there some hidden proper way of doing this in a reusable manner?
Funny thing: Even apple suggest that you do it the "wrong" way, making it seem like the right way but with inconsistent outcome compared to their own ways… So my best guess is that apple do this under the hood, and forgot to give enough flexibility for clients to perform the same operations (big flaw in other words), or that I'm just on some bad trip and see some issue that doesn't exist…
Okay, this might not be a true answer of how to solve it for custom segues (subclassing UIStoryboardSegue), but it does solve the general issue!
After some casual reading about new features, I stumbled upon a new way to do custom transitions between ViewControllers introduced in iOS7 called nothing more than "Custom Transitions" i guess!
Read about it here and here, or video from WWDC here.
I've just dipped my toes, but basically it is a new, closer to the system way of doing transitions and allows for better control = better looking transitions. After glancing at the example provided by the blog I referenced (git found here) I can confirm that FINALLY, we are able to do transitions which behave as ONE EXPECTS THEM TO with events fired at the expected occasions!
Since I'm just reading about it I can't give a thorough explanation yet, but check out the links :)
Note: This is maybe not supposed to completely replace custom segues, but can be used in a similar fashion (check examples) so if you need that little extra fancy transition, this is definitely the way to go by the looks of it! Basically you setup segues in the storyboard, and hook up the correct transition-delegates in the prepareForSegue:-method.