CO538 Anonymous Questions and Answers Keyword Index |
This page provides a keyword index to questions and answers. Clicking on a keyword will take you to a page containing all questions and answers for that keyword, grouped by year.
To submit a question, use the anonymous questions page. You may find the keyword index and/or top-level index useful for locating past questions and answers.
Keyword reference for animation
2012 |
Submission reference: IN2206
My output is behaving very strangely. When I run the program, the output comes in chunks and all squashed inline, rather than one by one, line by line. I can't work out if it's to do with the following code in my q7 process:
SHARED ! CHAN REPORT report! PAR SEQ i = 0 FOR n.philosophers secure.college (report!) display (report?,screen!)
however if I change this to:
secure.college(report!) display(report?,screen!)
then I get an error in the fork process saying that I need to claim a channel before I use it. However, it is being claimed like it is in other places in my program, on the line:
CLAIM REPORT ! fork.down;id ... [snip code] PROC display (CHAN REPORT in?, CHAN BYTE screen!) ... [snip code] SEQ out.string ("stuff", 0, screen!) cursor.down (1, screen!) --screen ! FLUSH ... [snip more code] :
The reason for the strange output is because you have commented out the 'FLUSH' outputs that force the program's output buffer to empty. The procedure 'cursor.down' will emit an escape sequence that moves the cursor, but isn't guaranteed to flush the output. The normal way to flush the output is to write out a newline sequence (the output is line-buffered), e.g.:
out.string ("*c*n", 0, screen!)
The replicated SEQ around the call to 'secure.college' is redundant — it doesn't make sense to loop over n.philosophers iterations of the college. Running the 'secure.college' in parallel with the 'display' process is sufficient. The error that you get as a result, however, looks unrelated. Looking at the code you pasted, the error is that 'REPORT' is written like that, meaning the "REPORT" protocol, and not the 'report' channel (lowercase). Outputs to the 'report' channel here should look similar to elsewhere (e.g. in the philosopher code).
Submission reference: IN2200
I am just wondering what the right way to implement the animation is. So far, I have already tried using the display process already coded, but instead of outputting lines of text, lines of characters forming a shape of some sort, however this always seems to deadlock after one step. It however, does not deadlock when running the original display process.
This suggests there is a problem with the modified display process. Without seeing the code it's fairly hard to diagnose, but do check, line-for-line, that the display process is doing what you think it ought to be. Common causes of this sort of deadlock are deleting some necessary loop (i.e. the display process handles one message then deadlocks), or dependencies added internally, e.g. with loops and delays for the animation, that break the overall operation of the system. If the problem isn't obvious, I'd recommend asking your seminar leader, who'll be able to offer some rapid advice on what's wrong and where.
In the case of complex animations (e.g. sprites moving around the screen), the logic that moves such things step-by-step should be separate to the main "display" process (i.e. as parallel processes between the philosophers/forks/etc. and display).
2011 |
Submission reference: IN2080
ok the good news is that i managed to get things moving inside my prgram, ie, things move to diffrent parts of the screen, the bad news however, is that all that are moving are words rperesenting thte various itmes i have some mulitdimensional arrays set up that create stickmen like figures to use instead of the words, but the problem is, that out.string doesnt seem to acept multidimenisonal arrays, is there a way around this?
You can easily write your own process to output a 2D array of characters (BYTEs) to the screen. For example, here's one (with a testrig program):
#INCLUDE "course.module" VAL [][]BYTE stickman IS [" O ", " | ", "/ \"]: PROC out.icon (VAL BYTE x, y, VAL [][]BYTE icon, CHAN BYTE out!) SEQ INITIAL BYTE yy IS y: SEQ i = 0 FOR SIZE icon SEQ cursor.x.y (x, yy, out!) out.string (icon[i], 0, out!) yy := yy + 1 -- move down a line out ! FLUSH : PROC icon (CHAN BYTE keyboard?, screen!, error!) SEQ erase.screen (screen!) out.icon (39, 11, stickman, screen!) out.string ("*c*n*n*n*n*n*n", 0, screen!) :
Please see opening rant in the answer to Question 45 (2011).
Keywords: q7 , animation , cursor
Submission reference: IN2076
I'm currently trying to get me animation processes running in parallel and I'm not sure how to go about this.
I have the display process receiving inputs on a shared channel from the forks, philosophers, and security that is correctly interpreting the input. But anytime I use one of my animation processes it is done in sequence due to the display process not except another input until the animation process has finished, so everything is animated in sequence.
I've tried all that I can think of to fix this. Any advice?
See Question 39 (2011). All the forks, philosophers and the security guard processes must have separate report channels (not a shared one) to separate animation processes that can all operate in parallel. The animation processes then compete with each other to send incremental movement messages over the same shared channel to a display process that handles them.
For example, a philosopher animation process might want to move its philosopher icon from one part of the screen to another by some interesting route (e.g. when its philosopher process reports it is hungry). It animates by a sequence of incremental moves (e.g. erase the icon from its current position, which it has to remember, and re-draw at slightly further on along its route). It can hold its philosopher process till this is complete by using an extended input to receive its messages and doing the animation in the extended rendezvous block (see Shared-etc slide 59). The same effect can be achieved without using the extended input syntax (see Shared-etc slide 61, where the ack channel is not needed in this case if you make the philosopher (or fork or security) send each of its messages twice).
Keywords: q7 , shared-channel , animation
Submission reference: IN2070
I have followed the plan and have a shared channel, but it seems I can't achieve parallel output of the animation when reports only come in sequence...
My security guard's counter always seems to be out of sync with the actual number of philosophers at the table, but I'm unsure why. Any ideas how to achieve this?
For the first problem, you may want to consider adding additional processes to help control the animation. Clearly having all the animation handled by "display" which has a single input channel from everything isn't going to work (as you say, it's serialised). What you would need to do is introduce helper processes which do the legwork of the animation and only communicate step-by-step animation actions to the "display" process. That way lots of things can be animating at once without a problem.
As for the issue about the security guard counter, are you flushing the output after writing the integer to the screen? If not, it may be stale. If that's not the problem, try mailing your code to your seminar leader who should be able to spot the problem quickly.
Keywords: q7 , shared-channel , animation
Referrers: Question 44 (2011)
2009 |
Submission reference: IN1851
Hi there, I'm currently doing my animation for dining philosophers, and I'm trying to make the animations happen in parallel, but I can't figure out how to do this.
I have a case statement that reads in the reports on the report channel, then depending on what comes in, does the animation. But until the animation finishes, I can't finish the CASE to get the next command in to animate that.
Is there someway to get the CASE to loop round and start dealing with the next report while the body of one of the case commands is still running? Or if not, any other suggestions about how to deal with this problem? Thanks.
As you say, you can't do this with a single display process. See the last two paragraphs of the answer to Question 49 (2009).
Submission reference: IN1849
In Question 48 (2009), you answered:
"You have to erase the string-icon (by writing spaces where it used to be) just before you write it in the next position (and FLUSH)".
I'm sorry but I don't understand what you mean. Could you explain further? Sorry.
For instance:
VAL []BYTE icon IS ":0": -- 1-D (horizontal) icon SEQ cursor.x.y (string[X], string[Y], screen!) SEQ i = 0 FOR 5 SEQ out.string (icon, 0, screen!) screen ! FLUSH pause (50000) -- 1/20 second cursor.left (SIZE icon, screen!) -- move cursor back out.ch (' ', SIZE icon, screen!) -- erase icon cursor.right (1, screen!) -- next icon position screen ! FLUSH
Note: in the above, the icon moves right by 1 position in each cycle. In your code in Question 48 (2009), your icon moved right by 3 places each cycle (leaving a trail).
If you do this in the standard display process, only one icon will be animated at a time. For parallel icon animations, you will need parallel animation processes writing to a fairly dumb display process over a SHARED channel.
With the assessment due today, you probably don't have time to bother with parallel animation! For future work, take a look at the shared_screen module.
Referrers: Question 33 (2010) , Question 50 (2009)
2008 |
Submission reference: IN1619
I'm trying to model my q7 on a7.basic, but I'm having difficulty displaying any sort of sensible output. The phils, forks and security each output their state via a shared channel to the display, which outputs to the screen based on which channel the input was received on, using the id of the forks and phils to output to the correct column/row on the screen. However, my display only ever shows (almost) all the phils and forks in all the states at the same time. However, sometimes there is no display to the screen at all. I'm not sure whether it's because I'm not setting my seed correctly, of if its a more general problem with the wiring.
[snip code]
I'm also curious to know why in a7.basic the philosophers often skip the hungry and sitting states, going straight from thinking to eating. Surely the progression through the states happens sequentially?
The code you had there looks fine, so I don't think that's the problem. Check, however, that your display process is flushing the output correctly. That is, terminal output is line-buffered by default, so you normally wouldn't see program output until a newline occurs. You can force the output by writing the FLUSH value to the screen channel, or by including a newline at the end of every chunk of output sent to the screen. That would be my first thought, anyway. Incorrectly set seed values are more likely to result in a non-random animation, rather than a broken animation.
PHW adds: if your display shows all phils and forks in all states (almost) all the time, are you erasing text indicating a previous state when writing the text for the new state? To erase previous text, just overwrite with space characters – of course, you have to work out where the text indicating the previous state is on the screen (but that's no harder than working out where to write the new text).
As far as the model answer goes, the philosophers do go through all the various states sequentially, but this can sometimes happen quickly. Quick to the point where you may not actually get to see it on the screen (i.e. if the "hungry" state is drawn on the terminal and then erased for the next state, before the terminal has had a chance to redraw itself — at 60 Hz or however fast).
Submission reference: IN1607
Hey there, several questions for you here, all of them q7 related!
Firstly, a while ago in the slides you mentioned using "Windows" (not the OS!) to output to certain areas of the screen as part of a test rig. How is this done (and what slides was is in!)? It seems like a necessary thing to do in order to do some nice animation effects.
Secondly - colour. I'm using ASCII art - is there a way to make this colourful in occam? How?
Finally - could you give us more information on how marks are distributed for this piece of coursework. Will there be marks for implementation (should I hold back until more or protocols/shared channels etc has been covered?) and code documentation? How much extra to you gain from making the animation 'nice'?
The part about using 'windows' for debugging output is about putting your debugging output at the right place on the screen. If you're using PROTOCOLs to drive a display process, and/or a SHARED CHAN BYTE, you can engineer this in fairly simply. The main point is to stop debugging output being trashed by other screen-drawing code (which will probably happen if you just write messages to the top-level "screen" or "error" channels). For example:
PROTOCOL DISPLAY CASE ... existing cases debug; INT::[]BYTE --* Debug message (counted array of BYTEs) : PROC display (CHAN DISPLAY in?, CHAN BYTE screen!) ... existing code in ? CASE ... existing tagged inputs INT mlen: [256]BYTE msg: debug; mlen::msg SEQ cursor.x.y (1, 24, screen!) out.string ([msg FOR mlen], 0, screen!) :
Or if you have the top-level "screen" passed down as a shared channel:
PROC philosopher (..., SHARED CHAN BYTE debug!) WHILE TRUE SEQ ... existing code CLAIM debug! SEQ cursor.x.y (1, 24, debug!) out.string ("This is a debug message in the right place*n", 0, debug!) ... more existing code :
Regarding colour, yes, this will work provided you're using a terminal that understands the various VT220/ANSI escape sequences for this. There is some support for this in the shared-screen library that comes with KRoC, although that is fairly old now. Details on the actual things that need to be output to generate this can be found here: Wikipedia:ANSI escape code.
As a quick example, however:
VAL BYTE FG.WHITE IS 37: VAL BYTE BG.BLUE IS 44: ... other colours PROC set.fg.bg.col (VAL BYTE fg, bg, CHAN BYTE screen!) SEQ out.string ("*#1B[", 0, screen!) out.byte (fg, 0, screen!) screen ! ';' out.byte (bg, 0, screen!) screen ! 'm' : PROC display (CHAN DISPLAY in?, CHAN BYTE screen!) ... existing code in ? CASE ... other tagged inputs show.title SEQ -- draw a banner of some form cursor.x.y (2, 4, screen!) set.fg.bg.col (FG.WHITE, BG.BLUE, screen!) out.string ("Welcome to the display process", 0, screen!) screen ! FLUSH :
As far as marking is concerned, you will be marked on a combination of the output your solution produces, and the code that implements it. These are divided amongst the tasks that you have to complete, weighted according to relative difficulty, e.g. "adding a display process", "sensible reporting for the forks", etc. There are, however, a number of "bonus" marks available for solutions that go above and beyond the basic requirements. As a general rule, the model "q7" answer (simple text animation), if perfectly coded, can score 100%. A fully-featured animation (with characters walking around the screen, etc.), as we've shown you in the lectures and seminars, can tolerate some coding errors and still score 100%.
Keywords: q7 , colour , animation , ansi
2004 |
I have a quick question relating to my 'animation' - could you give any tips/ideas for nice(r) way of making the philosophers move about the screen without hard coding in the locations of every movement?
In my more 'advanced' animation (which has been a challenge to say the least) I have had a lot of hassle using a hard coded method. The code just to move a philosopher to the table (and it's currently not very smooth) is around 300 lines. Ouch.
I am sure there is a better way of doing things but I have racked my brains and I can't think of anything :(. The only other idea was to create a "large" VAL [][5][2]BYTE array that stored all the locations, and for each movement the required value is pulled out the array. That doesn't seem much nicer though; occam doesn't seem to allow you to span this sort of thing over multiple lines either.
Any sort of help would be greatly appreciated, however small!
If ever you find yourself writing long sequences of repetitive code, where the differences are primarily in number values, you are doing something wrong, ugly and inefficient! So, your 300 lines of code is not a good idea.
Your 'better way' is much better, although it can be improved (see towards the end of this answer). Your VAL [][5][2]BYTE is, presumably, a 2-dimensional array of coordinates (i.e. [2]BYTEs), with the [5] index being for the philosophers and the unsized outermost dimension (i.e. []) being for the number of coordinates (i.e. the length of the path). That might make slightly more sense (and convenience for programming) with the two outer dimensions swapped around -- i.e. VAL [5][][2]BYTE.
occam does allow long lines to be broken across multiple lines ... but maybe I never told you! You can break a long line after commas, operators and the keyword IS. For example, the very long one-line declaration:
VAL [n.phils][][2]BYTE path IS [[[13, 12], [14, 12], [14, 13], [14, 14], [14, 15]], [[23, 12], [24, 12], [24, 13], [24, 14], [24, 15]], [[33, 22], [34, 22], [34, 23], [34, 24], [34, 25]], [[83, 82], [84, 82], [84, 83], [84, 84], [84, 85]], [[93, 92], [94, 92], [94, 93], [94, 94], [94, 95]]]:
can be much more readibly laid out:
VAL [n.phils][][2]BYTE path IS [[[13, 12], [14, 12], [14, 13], [14, 14], [14, 15]], [[23, 12], [24, 12], [24, 13], [24, 14], [24, 15]], [[33, 22], [34, 22], [34, 23], [34, 24], [34, 25]], [[83, 82], [84, 82], [84, 83], [84, 84], [84, 85]], [[93, 92], [94, 92], [94, 93], [94, 94], [94, 95]]]:
The rule about indentation for continuation lines is that any indentation at least as great as the initial line is allowed. So, the following, rather stupid, layout is also possible:
VAL [n.phils][][2]BYTE path IS [[[13, 12], [14, 12], [14, 13], [14, 14], [14, 15]], [[23, 12], [24, 12], [24, 13], [24, 14], [24, 15]], [[33, 22], [34, 22], [34, 23], [34, 24], [34, 25]], [[83, 82], [84, 82], [84, 83], [84, 84], [84, 85]], [[93, 92], [94, 92], [94, 93], [94, 94], [94, 95]]]:
but we wouldn't, of course, ever do that! Another use of breaking lines after commas we have seen lots of times -- in PROC headers with long parameter lists:
PROC thing (CHAN OF INT in0, in1, CHAN OF BYTE keyboard, screen, error, VAL INT id, interval, [][]REAL64 data)
instead of:
PROC thing (CHAN OF INT in0, in1, CHAN OF BYTE keyboard, screen, error, VAL INT id, interval, [][]REAL64 data)
Breaking lines after operators helps keep large expressions neat -- for example:
first := (first - second) + ( ((-first) + (third - second)) * (rotational.torque - (ratio/2)) )
could be written:
first := (first - second) + ( ((-first) + (third - second)) * (rotational.torque - (ratio/2)) )
which might help a little.
Getting back to improving your path description for a wandering philosopher ... rather than declare a table of absolute coordinates for each path position, consider a table of relative movements. For example:
VAL [n.phils][][2]BYTE path IS [[[left, 3], [up, 5], [right, 2], [up, 4], [left, 1], [down, 2]], [[down, 8], [up, 3], [left, 6], [down, 1], [left, 6], [down, 3]], [[right, 3], [down, 2], [right, 8], [down, 9], [right, 1], [down, 5]], [[up, 5], [left, 5], [down, 2], [up, 2], [down, 1], [up, 3]], [[up, 9], [right, 9], [up, 2], [left, 2], [up, 3], [left, 6]]]:
where your movement code interprets [left, 3] as "move left 3 places" etc. Predeclared, of course, would need to be something like:
VAL BYTE left IS 0: VAL BYTE right IS 1: VAL BYTE up IS 2: VAL BYTE down IS 3:
Elsewhere would be needed a table of absolute start coordinates for each path movement.
That just leaves the problem that all the above path lengths have to be the same length? With the modern occam-pi language, that's not a problem ... we can use dynamically sized mobile arrays. For classical occam, you could pad out short paths with some dummy movement elements - e.g. STAY where:
VAL BYTE stay IS 255: VAL [2]BYTE STAY IS [stay, 0]: VAL [n.phils][][2]BYTE path IS [[[left, 3], [up, 5], [right, 2], [up, 4], STAY, STAY], [[down, 8], [up, 3], [left, 6], [down, 1], [left, 6], STAY], [[right, 3], [down, 2], [right, 8], [down, 9], [right, 1], [down, 5]], [[up, 5], [left, 5], STAY, STAY, STAY, STAY], [[up, 9], [right, 9], [up, 2], [left, 2], [up, 3], STAY]]:
Keywords: q7 , animation , long-lines
Referrers: Question 43 (2009) , Question 30 (2008)
2003 |
Hi,
Until recently I had my dining philosophers program running fine with scrolling text output, now I have added the table style animation it runs very slowly and sometimes there is a visible pause as it outputs a word. Are there any obvious things that could be causing this?
I an doing the animations like this:
SEQ clear.states (4 + (4 * n), out) cursor.x.y (32, BYTE (4 + (4 * n)), out) out.string ("Sitting", 0, out) flush (out)
Thank you.
Nothing looks wrong with the code you posted. If you're running it over a network (e.g. on raptor logged in from home), that could be the reason. It might also be raptor being slow (with everyone else doing their dining philosophers on it).
I lost my notes from the seminar where we did arranging stuff on the screen, could you tell me the commands for relocating the cursor, blanking the screen and changing text colour.
The other answers under the animation keyword should be useful. In summary, though:
PROC cursor.x.y (VAL BYTE x, y, CHAN BYTE out!) PROC erase.screen (CHAN BYTE out!)
... and many others. Changing the text colour isn't entirely trivial -- there are no pre-defined PROCs to do it for you. However, here's a simple example that prints some text in bold red (before restoring the default colour/attributes):
SEQ out.string ("*#1B[1;31m", 0, screen!) out.string ("Hello, bold red world!", 0, screen!) out.string ("*#1B[0m", 0, screen!) screen ! FLUSH
The various ANSI/VT100 escape codes and suchlike can be found via google. A basic, but useful, reference can be found here.
Keywords: animation
Referrers: Question 113 (2004) , Question 113 (2004)
Are there any example source files of animation; I attended the seminar, but am having problems with even starting to animate.
There were four seminars you should have attended ...
You could look at `test_utils.occ' in:
/usr/local/courses/co516/examples
on Raptor. Or `examples/sort_pump.occ', but that uses `goto.x.y', which is now deprecated, rather than `cursor.x.y' (the two are essentially similar, however).
Essentially, text-animation is a repeating process of: move cursor, then output something. This can be seen most obviously in the `a7' model answer.
Source code for other animations can be found on Fred's occam page. These range from trivial to rather complex.
I have some mystery regarding Q7 I'd like to clear up. As I understand it the college must communicate its status to the display process via a number of channels. I think the only thing the display process needs to know is the status of each philosopher; the status of security and the forks can be deduced if we know what the philosophers are doing.
As it stands the college is self contained and there is no obvious way to report, at any given time, its status to another process. One solution I can see is to replicate all communications between the processes in college, and route them to the display process. The display process would maintain its own picture of the college, which it updates according to the inputs on its channels. This seems rather complicated.
Alternately the display process could again recieve a copy of all internal college communications, but conforming to a protocol such that it can update its picture of the college without other information about its status. For example, when a philosopher wishes to sit down, instead of outputting a boolean he outputs a specific message the display process knows to mean "waiting to sit down" and can update its picture accordingly. This is assuming that the animation is not drawn frame at a time, but continuously updated as information comes in.
In these cases what does display need to communicate with in order to get a complete picture ? Security can tell it who is wanting to sit down and stand up, but it also needs to know the fork status. Presumably this will be the job of either forks or philosopher.
I have trawled the anonymous questions of old, none of the answers to which have baffled me, but I still cannot get this fundamental.
All the questions you have asked have been discussed in your seminar groups for the last 4 weeks. These Q&A pages are in no way a substitute for attending those seminars. Your question suggests ideas that are either illegal (with respect to occam semantics) or far too complex. Simple solutions have been presented in the seminars.
Having said this, I will attempt to answer your questions. However, those who know how to do this problem should skip these answers, as correcting the confusion in your questions may confuse others unnecessarily.
In response to your first paragraph, yes, the state of the forks can be deduced from the philosopher, but it's easier to have the forks report their state. It also makes more sense; the state of a fork should be reported by the fork, not by something else.
You are sort of correct in your second paragraph, although I'm not sure what you mean by `replicate all communications'. Thankfully, setting up this extra `wiring' is not complicated in occam. However, the `display' process does not need to maintain the `state' of the college (see the next paragraph). The extra wiring can be handled using an array of channels; the `display' process gets the inputting ends as a `bundle' (array), whilst the outputting ends are distributed amongst the other processes. This will require some modifications to the `secure.college' process.
The third paragraph is essentially what we're expecting you to do for this assignment. The `philosopher', `fork' and `security' processes report their actions to the display as they happen. The display process just inputs these messages and draws on the screen accordingly. The animation should indeed be updated on-the-fly; it should not be done frame-by-frame. The only disadvantage is that the display cannot be completely redrawn (i.e. if it got corrupted, somehow). This isn't a problem for this assignment, however.
The various messages are best handled using a tagged protocol. The previous assignment, q6.occ, used a tagged protocol. The various `messages' have been discussed in the seminar groups. The q7.occ file gives some indication of what is required:
Your task is to animate this demonstration. Links will need to be made from the college to its external environment, through which the philsophers (and, maybe, the forks and the security guard) report their state. These links are gathered by a fair-ALTing server that drives a screen display in response to incoming information from the college. Thinking and eating by the philosphers should be modelled by random (but finite!) delays. The animated display should reflect the round table in the dining room ...
Running the example solutions (on raptor, see Question 80 (2003)) should give you an indication of what is required -- i.e. what is being displayed (and therefore reported) there ? (`a7' is the example minimum-but-full-marks solution; the other example solutions are more animated).
Reporting by each process should be restricted to its own `state'. I.e., the security process should not report that philosophers are trying to stand up or sit down. This is actually very hard. The only state the security process maintains is how many philosophers are actually sat down -- it should report this. When a philosopher stands up or sits down, that should be reported by the philosopher -- not anything else. It is both more logical and simpler to have things this way, since it keeps the logic of each process `intact'. E.g. I might take your philosopher, fork, security and display processes, completely re-wire the nextwork (within reason), and still expect it to work. Having the correct functioning of processes depend on their external wiring is not really a good idea.. (such processes must conform to the protocol that they conceputally agreed on, however).
I hope this clears things up a bit. If you still have queries, or want some points explained in more detail, I'd suggest emailing or visiting your seminar-leader or other member of the course team (we all have a desk somewhere on campus).
2002 |
I would like to use colour in my solution to Q7. The PROC fg.col in shared_screen.occ looks useful ... however, I am unable to use the shared_screen.occ code. I have the following lines at the top of my source code:
#INCLUDE "shared_screen.occ" #USE "shared_screen.inc"
Many errors are generated relating to this, such as:
Error-oc-shared_screen.occ(337)- pc subscripted too many times Serious-oc- Too many errors, maximum is 100.
What am I doing wrong?
Sorry - we hadn't told you how to use this package. It's not part of the basic "course" library! Before explaining how to access, let me stress that noone needs to find out about and use this stuff - it's only there to provide a rich set of drawing mechanisms for those who want to do some really fancy animation. Even then, you don't have to use it ... but you will end up inventing something similar.
Something anyone could have done is simply copy those two files:
libsrc/shared_screen.inc libsrc/shared_screen.occ
into the start of your own q7.occ file. Then, your own code could simply use anything defined in them. Note that the order is important - the shared_screen.inc must go before the shared_screen.occ file (which uses protocols and data types defined in shared_screen.inc).
Better would be to copy those files into the same directory as your q7.occ file and start your file with:
#INCLUDE "shared_screen.inc" #INCLUDE "shared_screen.occ"
Again, note the ordering! These directives simply tell the compiler to pull in those files at the point of those #INCLUDEs.
Best is not to copy those files at all and use the library. All you haven't been told is the name of the library - which is "ss". Currently, only PROCs and FUNCTIONS are saveable in kroc libraries, which means that constants, data types, prototcols (etc.) have to be pulled in as #INCLUDEs. Anyway, to do this, your file needs to start with:
#INCLUDE "ss.inc" #USE "ss.lib"
These can be followed, or preceeded, by other library accesses - e.g.
#INCLUDE "consts.inc" -- standard course library constants #USE "course.lib" -- standard course library
We're not quite done. When compiling, the occam compiler (invoked by the kroc shell script) will find the relevant files. [Note: those working with the Linux kroc need to ensure their OCSEARCH environment variable is set up correctly.] When doing final linking (also invoked by the kroc shell script), we have to tell the linker where to find the library code. In fact, the kroc script uses the standard gcc (Gnu C Compiler) to do this linking - i.e. something different from OCSEARCH happens. Anyway, the compile command needed is:
kroc q7.occ -lss
Linux users have always had to do something like this to link in the course library (which the kroc script on Solaris machines has been set up to do automatically). So, on Linux, if you want both libraries linked in to your executable, the command is:
kroc q7.occ -lss -lcourse
Enjoy!
Keywords: q7 , colour , animation
2000 |
A friend told me that I should be using:
out ! FLUSH
after every single output. My program works perfectly well without them. Do I need to include them for safety?
Not for safety reasons. Unix flushes characters written to its standard output whenever the associated memory buffer gets full or when it gets a new line character. In addition, KRoC forces Unix to flush its buffer when the FLUSH character is sent.
You should flush your animation output after each completed update of the screen (but not, of course, after each character). If you did not and action was progressing slowly in your animation, you would not see anything until the Unix buffer became full when, suddenly, you would see everything that had happened since the last time the buffer was flushed. This is because individual animation updates would not usually include a new line character. If your animation is very active, you will be continually filling the Unix buffer and, so, would see things happening suddenly in bursts (as a full buffer is flushed), separated by periods in which nothing seems to happen (as the buffer is being filled).
However, if your animation is very active but includes a user freeze command and you haven't sent a FLUSH, the animation would freeze but you would not see the latest updates. Of course, you could respond to a freeze by sending a FLUSH ...
But if there are other ways of interacting with the animation (see a7-1997 and a7-1998 in the answers directory on raptor), you will need those FLUSHes. Otherwise you may run into latency problems: what you see on the screen might be the state of the animation a while back - the latest updates are buffered up somewhere and have not been sent to your screen yet!
Referrers: Question 33 (2010) , Question 37 (2009) , Question 51 (2004) , Question 114 (2003)
Just a small point - I have tried to remove the cursor from the screen using cursor.invisible (out). However, this would apear to do nothing and my dislplay still has a big black cursor jumping all over the place?
I'm afraid we are at the mercy of the completeness of the VT100 terminal emulation provided by the system we are using to get a text window. Most do not implement this make cursor invisible function and there's nothing we can do about it (apart from hacking the source code of the terminal emulator if we can get hold of it). In the good old days, we used to have real VT220 (which superceded VT100) terminals and this cursor.invisible procedure worked just fine!
Keywords: animation , cursor.invisible
I've forgotten how to implement the lookup table for the screen positions for the dining philosophers. Any help would be appreciated.
Your animation code should not be highly repetitive with the same logic repeated with different magic numbers - e.g. for displaying new positions of the different philosophers. Having a table of anchor coordinates for each philosopher may help. A table is simply an array of VALues (i.e. constants). For example:
VAL [][2]BYTE phil.anchor IS [[40, 5], [70, 10], [55, 15], [35, 15], [10, 10]]:
where the [][2]BYTE could have just been [][]BYTE, but being specific about the dimension of the coordinates (rather than the number of them) seems right. We could have been even more explicit and written [5][2]BYTE, but that seems too much. Any way, the compiler will fill in the sizes of any blanks in what we write after the IS.
With the above, it's nice to give names to the two indices of the [2]BYTE array coordinates - e.g.
VAL INT X IS 0: VAL INT Y IS 1:
Then, if we want to move the screen cursor to the anchor point for philosopher i - and we know that that i is a valid philosopher number (i.e. 0 through 4):
cursor.x.y (phil.anchor[i][X], phil.anchor[i][Y], screen)
or, more efficiently:
VAL [2]BYTE phil.i IS phil.anchor[i]: cursor.x.y (phil.i[X], phil.i[Y], screen)
since it only checks the array index (for out-of-bounds error) and calculates the address of phil.anchor[i] once.
Keywords: q7 , cursor , table , animation
Referrers: Question 43 (2009) , Question 30 (2008) , Question 84 (2003) , Question 29 (2002)
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 Unported License. |