Saving state and returning from any location in program 
Author Message
 Saving state and returning from any location in program

Hi, all.

My skill level is beginner. I've been writing a program that has
"modules" (groups of related subroutines). As the user does things he/she
may move around within the same module or cross-over to other modules
back and forth many times.

I would like to provide a "save" function (accessible by the ESC key)
that will allow the user to exit the program no matter how deep in any of
the modules. Upon re-entry into the program, I would like the exact same
program state to be restored. Same screen, same menu, etc.

Any ideas on how to accomplish this?

Thanks so much!

--Tim
Please remove "_nonono_" if you'd like to email me.



Sun, 27 Jun 2004 07:58:00 GMT  
 Saving state and returning from any location in program
Quote:

> Hi, all.

> My skill level is beginner. I've been writing a program that has
> "modules" (groups of related subroutines). As the user does things he/she
> may move around within the same module or cross-over to other modules
> back and forth many times.

> I would like to provide a "save" function (accessible by the ESC key)
> that will allow the user to exit the program no matter how deep in any of
> the modules. Upon re-entry into the program, I would like the exact same
> program state to be restored. Same screen, same menu, etc.

> Any ideas on how to accomplish this?

> Thanks so much!

Don't thank anybody yet. You dream the impossible dream. You can't
"save" history. It is past. You want to continually save the present so
that in the future when that ESC key is pressed you already know
everything you need to get back to where you are now. This is massively
non-trivial. Do think about it though. Dreams are what the future is
made of.
--

"Everything should be made as simple as possible, but not simpler."
                    --- Albert Einstein ---


Sun, 27 Jun 2004 11:59:52 GMT  
 Saving state and returning from any location in program

Quote:

> Hi, all.

> My skill level is beginner. I've been writing a program that has
> "modules" (groups of related subroutines). As the user does things he/she
> may move around within the same module or cross-over to other modules
> back and forth many times.
> [snip]

hi,

One best way to do it save all the window related stuff [modulename,
menus, location, ...] into a file while exiting. Later while init'ing
you could read this file and rebuild the system. Many systems,
including Opera Browser, Windows 3x do it this way [they use files
called .ini files].

This is conceptually, the same thing that many OOP languages call
Persistance.

Hope this helps.

Later
Raj



Sun, 27 Jun 2004 15:51:10 GMT  
 Saving state and returning from any location in program
[...]
Quote:
> I would like to provide a "save" function (accessible by the ESC key)
> that will allow the user to exit the program no matter how deep in any of
> the modules. Upon re-entry into the program, I would like the exact same
> program state to be restored. Same screen, same menu, etc.

[...]

As Raj implied in a separate response, there is no simple magic solution.
The programmer must identify everything worth preserving (which menu is
active, where the windows are positioned, which data file is open, etc),
and save that to a file before exiting.  Your program must then provide
a way to jump straight into a module, given the information read back
from the file.

I'll give you a simple example.  If your program's user interface is
strictly structured in a tree-like menu system, like so:

  main -+- option 1 -+- option 1-1
        |            +- option 1-2
        |
        +- option 2 -+- option 2-1
                     +- option 2-2
                     +- option 2-3

you can number each possible state (main = 1, option 1 = 2, and so on),
and just remember which number you were in when the program exited.
It may be a bit harder, in this case, to just jump to "option 2-1" deep
in the menu tree if you have to.

Another way to do this is to remember the whole "path" from main.  So
if the user must press "1" and then "2" to get to "option 1-2", store
a string "12" in the file.  When you restart the program, just walk
through the string and pretend that the user was pressing the keys.
This is likely to be simpler and more flexible than the previous
solution.

However, you must go through your whole program to understand what
you're _not_ preserving.  For example, many programs have an "undo"
function, and unless you preserve that, selecting "undo" after a
restart may no longer work.  That might be okay for some applications,
but not for others.  As a rule of thumb, any function with a "static"
variable may not perform exactly the same way if the program is
restarted.  For example, your rand() function (assuming you don't call
srand() at all) might give you the same sequence of numbers { 5, 100, 2,
4, 16 } every time you restart the program.  The next number that rand()
would've returned, if you did not exit, might be 4301.  However, if you
exit and then resume your program, the next number would again be 5,
not 4301.  Again, this may or may not matter to you, but you need to
know that.

Hope this helps.



Mon, 28 Jun 2004 03:50:13 GMT  
 Saving state and returning from any location in program
Thanks for the response, Joe!

I don't think it's _completely_ impossible, as I've seen it done. Maybe
only _partly_ impossible. :)

Also, I don't want to save "history." I'm trying to save the user's
_current_ status in the program so the same state can be restored when
the program is re-entered.

Some info I left out: This project is in C (using the DJGPP compiler).

The main() part of the program initiates a menu. The user can navigate
the menu to different subroutines to do stuff. At any moment in time the
user may be several menus "deep."

Although my program doesn't do it yet, it should be possible for the user
to exit the current menu/subroutine tree and climb onto a different one
(at any level).

Finally, no matter where the user is in the program, I'd like them to be
able to pull up a menu with a save option. Upon restarting the program
they'll be back at the same screen in the same menu like they never left.

In my opinion, this will have to be accomplished structurally. (As
opposed to something like Visual Basic which is event driven.)

Any ideas?

Thanks!

--Tim


Quote:
> Don't thank anybody yet. You dream the impossible dream. You can't
> "save" history. It is past. You want to continually save the present so
> that in the future when that ESC key is pressed you already know
> everything you need to get back to where you are now. This is massively
> non-trivial. Do think about it though. Dreams are what the future is
> made of.



Mon, 28 Jun 2004 11:34:59 GMT  
 Saving state and returning from any location in program
Hi, Raj. Thanks for the response. Yes, it helps. I was thinking along
similar lines, but unfortunately, don't know how to accomplish it.

Normally, when my program loads, the user's keystrokes dictate what
happens in the program. If I'm understanding you correctly, there could
be some sort of "automated" mode when the program starts to get back to
where the user left off. (The restoring of values in the global variables
should be easy, I think.)

Another idea I had was using some sort of "breadcrumbs" that would allow
the program to backtrack back up the subroutine tree to get to the main()
function prior to executing the save. I'm not sure how this would work
but think it would involve adding some "breadcrumb" code to every
possible subroutine that could be saved from.

Any of this make sense?

Thanks for the help!

--Tim



Quote:
> One best way to do it save all the window related stuff [modulename,
> menus, location, ...] into a file while exiting. Later while init'ing
> you could read this file and rebuild the system. Many systems,
> including Opera Browser, Windows 3x do it this way [they use files
> called .ini files].

> This is conceptually, the same thing that many OOP languages call
> Persistance.

> Hope this helps.



Mon, 28 Jun 2004 11:39:03 GMT  
 Saving state and returning from any location in program

Quote:

> ...
> Another idea I had was using some sort of "breadcrumbs" that would allow
> the program to backtrack back up the subroutine tree to get to the main()
> function prior to executing the save. I'm not sure how this would work
> but think it would involve adding some "breadcrumb" code to every
> possible subroutine that could be saved from.

> Any of this make sense?

Of course it does, if you were to put this whole thing in the OO
paradigm,
you could ask each and every object [whose state could be saved] to
provide its state representation, which then you could record
somewhere, possibly a file.
[The above does'nt mean that you _can't_ do it in C]

A sample internal representation could look something like this:
[Module]
 |-[Windows]
 |    |-[Menu]
 |        |-[Items]
 |        |-[ActiveItem]
 |-[OtherData]

Starting from the BRANCHES and proceeding to the ROOT, the ActiveItem
[if at all] could report to the Items, which in turn report to Menu,
which in turn could report to Window/s which in turn reports to main
Module, wherein the whole stuff is saved.

Then on starting up, you could rebuild the whole thing again, this
time starting from the ROOT.

It's not that horribly difficult. Think about it.

Quote:
> Thanks for the help!

> --Tim

You are welcome.

Raj



Mon, 28 Jun 2004 16:13:27 GMT  
 Saving state and returning from any location in program
Hi, Steven. Thanks so much for the response!

I'm not an expert C programmer, so please do not point and laugh (too
much) but I'm going to post some code I came up with after pondering your
message.

Am I on the right track?

Thanks!

--Tim

/* menu.c - attempting to save and restore program state
 * this code compiles and runs under DJGPP */
#include <conio.h>
#include <string.h>

void    add_sub(void);
void    bold_sub(void);
void    cat_sub(void);
char    one_key(char *s);

/* global variables */
char *program_state = "c ua ub uq";

int main(void) {
        int key;
        printf("Welcome\n");
        while (1==1) {
                printf("Main Menu\n");
                key = one_key("abcq");
                switch(key) {
                        case 'a' :
                                add_sub();
                                break;
                        case 'b' :
                                bold_sub();
                                break;
                        case 'c' :
                                cat_sub();
                                break;
                        case 'q' :
                                printf("Goodbye.\n");
                                exit(0);
                }
        }

Quote:
}

void add_sub(void) {
        char key;
        printf("[Add mode].\n");
        while (1==1) {
                key = one_key(" u");
                switch (key) {
                        case ' ' :
                                printf("Hmm, just did some adding.\n");
                                break;
                        case 'u' :
                                printf("Exiting add mode.\n");
                                return;
                }
        }

Quote:
}

void bold_sub(void) {
        char key;
        printf("[Bold mode].\n");
        while (1==1) {
                key = one_key(" u");
                switch (key) {
                        case ' ' :
                                printf("Hmm, just made something bold.\n");
                                break;
                        case 'u' :
                                printf("Exiting bold mode.\n");
                                return;
                }
        }

Quote:
}

void cat_sub(void) {
        char key;
        printf("[Cat mode].\n");
        while (1==1) {
                key = one_key(" u");
                switch (key) {
                        case ' ' :
                                printf("Hmm, I just pet a cat.\n");
                                break;
                        case 'u' :
                                printf("Exiting cat mode.\n");
                                return;
                }
        }

Quote:
}

char one_key(char *s) {
  char ch;
        if (strlen(program_state) == 0) {
        while (!strchr(s, ch = getch()));
        } else {
                ch = program_state[0];
                program_state++;
        }
        return(ch);

Quote:
}



Quote:
> As Raj implied in a separate response, there is no simple magic solution.
> The programmer must identify everything worth preserving (which menu is
> active, where the windows are positioned, which data file is open, etc),
> and save that to a file before exiting.  Your program must then provide
> a way to jump straight into a module, given the information read back
> from the file.

> I'll give you a simple example.  If your program's user interface is
> strictly structured in a tree-like menu system, like so:

>   main -+- option 1 -+- option 1-1
>         |            +- option 1-2
>         |
>         +- option 2 -+- option 2-1
>                      +- option 2-2
>                      +- option 2-3

> you can number each possible state (main = 1, option 1 = 2, and so on),
> and just remember which number you were in when the program exited.
> It may be a bit harder, in this case, to just jump to "option 2-1" deep
> in the menu tree if you have to.

> Another way to do this is to remember the whole "path" from main.  So
> if the user must press "1" and then "2" to get to "option 1-2", store
> a string "12" in the file.  When you restart the program, just walk
> through the string and pretend that the user was pressing the keys.
> This is likely to be simpler and more flexible than the previous
> solution.

> However, you must go through your whole program to understand what
> you're _not_ preserving.  For example, many programs have an "undo"
> function, and unless you preserve that, selecting "undo" after a
> restart may no longer work.  That might be okay for some applications,
> but not for others.  As a rule of thumb, any function with a "static"
> variable may not perform exactly the same way if the program is
> restarted.  For example, your rand() function (assuming you don't call
> srand() at all) might give you the same sequence of numbers { 5, 100, 2,
> 4, 16 } every time you restart the program.  The next number that rand()
> would've returned, if you did not exit, might be 4301.  However, if you
> exit and then resume your program, the next number would again be 5,
> not 4301.  Again, this may or may not matter to you, but you need to
> know that.



Wed, 30 Jun 2004 12:36:36 GMT  
 
 [ 8 post ] 

 Relevant Pages 

1. Assembly.Location returning shadowed location

2. How to save CToolBar object location?

3. Controlling the default location for saving files.

4. saving toolbar location

5. Include Directory location cannot be saved

6. Setting the default location for save as

7. Saving the State of the Processor

8. Window state save/restore

9. Saving state of multiple toolbars?

10. toolbar: save restore state

11. save outline state

12. Saving and Restoring the state of a ToolBar

 

 
Powered by phpBB® Forum Software