save_bitmap

Syntax: include image.e
i = save_bitmap(s, st)
Description: Create a bitmap (.bmp) file from a 2-element sequence s. st is the name of a .bmp "bitmap" file. s[1] is the palette:

{{r,g,b}, {r,g,b}, ..., {r,g,b}}

Each red, green, or blue value is in the range 0 to 255. s[2] is a 2-d sequence of sequences containing a pixel-graphics image. The sequences contained in s[2] must all have the same length. s is in the same format as the value returned by read_bitmap().

The result will be one of the following codes:

    global constant BMP_SUCCESS = 0,
                BMP_OPEN_FAILED = 1,
               BMP_INVALID_MODE = 4 -- invalid graphics mode
                                    -- or invalid argument
Comments: If you use get_all_palette() to get the palette before calling this function, you must multiply the returned intensity values by 4 before calling save_bitmap().

You might use save_image() to get the 2-d image for s[2].

save_bitmap() produces bitmaps of 2, 4, 16, or 256 colors and these can all be read with read_bitmap(). Windows Paintbrush and some other tools do not support 4-color bitmaps.

Example:
paletteData = get_all_palette() * 4
code = save_bitmap({paletteData, imageData},
                   "c:\\example\\a1.bmp")

See Also: save_image, read_bitmap, save_screen, get_all_palette

save_image

Platform: DOS32
Syntax: include image.e
s3 = save_image(s1, s2)
Description: Save a rectangular image from a pixel-graphics screen. The result is a 2-d sequence of sequences containing all the pixels in the image. You can redisplay the image using display_image(). s1 is a 2-element sequence {x1,y1} specifying the top-left pixel in the image. s2 is a sequence {x2,y2} specifying the bottom-right pixel.
Example:
s = save_image({0,0}, {50,50})
display_image({100,200}, s)
display_image({300,400}, s)
-- saves a 51x51 square image, then redisplays it at {100,200}
-- and at {300,400}

See Also: display_image, save_text_image

save_screen

Platform: DOS32
Syntax: include image.e
i = save_screen(x1, st)
Description: Save the whole screen or a rectangular region of the screen as a Windows bitmap (.bmp) file. To save the whole screen, pass the integer 0 for x1. To save a rectangular region of the screen, x1 should be a sequence of 2 sequences: {{topLeftXPixel, topLeftYPixel}, {bottomRightXPixel, bottomRightYPixel}}

st is the name of a .bmp "bitmap" file.

The result will be one of the following codes:

    global constant BMP_SUCCESS = 0,
                BMP_OPEN_FAILED = 1,
               BMP_INVALID_MODE = 4 -- invalid graphics mode
                                    -- or invalid argument
Comments: save_screen() produces bitmaps of 2, 4, 16, or 256 colors and these can all be read with read_bitmap(). Windows Paintbrush and some other tools do not support 4-color bitmaps.

save_screen() only works in pixel-graphics modes, not text modes.

Example 1:
-- save whole screen:
code = save_screen(0, "c:\\example\\a1.bmp")

Example 2:
-- save part of screen:
err = save_screen({{0,0},{200, 15}}, "b1.bmp")

See Also: save_image, read_bitmap, save_bitmap

save_text_image

Syntax: include image.e
s3 = save_text_image(s1, s2)
Description: Save a rectangular region of text from a text-mode screen. The result is a sequence of sequences containing ASCII characters and attributes from the screen. You can redisplay this text using display_text_image(). s1 is a 2-element sequence {line1, column1} specifying the top-left character. s2 is a sequence {line2, column2} specifying the bottom right character.
Comments: Because the character attributes are also saved, you will get the correct foreground color, background color and other properties for each character when you redisplay the text.

On DOS32, an attribute byte is made up of two 4-bit fields that encode the foreground and background color of a character. The high-order 4 bits determine the background color, while the low-order 4 bits determine the foreground color.

This routine only works in text modes.

You might use this function in a text-mode graphical user interface to save a portion of the screen before displaying a drop-down menu, dialog box, alert box etc.

On DOS32, if you are flipping video pages, note that this function reads from the current active page.

Example: If the top 2 lines of the screen have:
   Hello
   World
And you execute:
s = save_text_image({1,1}, {2,5})
Then s is something like:
    {"H-e-l-l-o-",
     "W-o-r-l-d-"}
where '-' indicates the attribute bytes

See Also: display_text_image, save_image, set_active_page, get_screen_char

scroll

Syntax: include graphics.e
scroll(i1, i2, i3)
Description: Scroll a region of text on the screen either up (i1 positive) or down (i1 negative) by i1 lines. The region is the series of lines on the screen from i2 (top line) to i3 (bottom line), inclusive. New blank lines will appear at the top or bottom.
Comments: You could perform the scrolling operation using a series of calls to puts(), but scroll() is much faster.

The position of the cursor after scrolling is not defined.

Example Program: bin\ed.ex
See Also: clear_screen, text_rows

seek

Syntax: include file.e
i1 = seek(fn, a1)
Description: Seek (move) to any byte position in the file fn or to the end of file if a1 is -1. For each open file there is a current byte position that is updated as a result of I/O operations on the file. The initial file position is 0 for files opened for read, write or update. The initial position is the end of file for files opened for append. The value returned by seek() is 0 if the seek was successful, and non-zero if it was unsuccessful. It is possible to seek past the end of a file. If you seek past the end of the file, and write some data, undefined bytes will be inserted into the gap between the original end of file and your new data.
Comments: After seeking and reading (writing) a series of bytes, you may need to call seek() explicitly before you switch to writing (reading) bytes, even though the file position should already be what you want.

This function is normally used with files opened in binary mode. In text mode, DOS converts CR LF to LF on input, and LF to CR LF on output, which can cause great confusion when you are trying to count bytes.

Example:
include file.e

integer fn
fn = open("mydata", "rb")
-- read and display first line of file 3 times:
for i = 1 to 3 do
    puts(1, gets(fn))
    if seek(fn, 0) then
        puts(1, "rewind failed!\n")
    end if
end for

See Also: where, open

sequence

Syntax: i = sequence(x)
Description: Return 1 if x is a sequence else return 0.
Comments: This serves to define the sequence type. You can also call it like an ordinary function to determine if an object is a sequence.
Example 1:
sequence s
s = {1,2,3}

Example 2:
if sequence(x) then
    sum = 0
    for i = 1 to length(x) do
        sum = sum + x[i]
    end for
else
    -- x must be an atom
    sum = x
end if

See Also: atom, object, integer, atoms and sequences

set_active_page

Platform: DOS32
Syntax: include image.e
set_active_page(i)
Description: Select video page i to send all screen output to.
Comments: With multiple pages you can instantaneously change the entire screen without causing any visible "flicker". You can also save the screen and bring it back quickly.

video_config() will tell you how many pages are available in the current graphics mode.

By default, the active page and the display page are both 0.

This works under DOS, or in a full-screen DOS window. In a partial-screen window you cannot change the active page.

Example:
include image.e

-- active & display pages are initially both 0
puts(1, "\nThis is page 0\n")
set_active_page(1)     -- screen output will now go to page 1
clear_screen()
puts(1, "\nNow we've flipped to page 1\n")
if getc(0) then        -- wait for key-press
end if
set_display_page(1)    -- "Now we've ..." becomes visible
if getc(0) then        -- wait for key-press
end if
set_display_page(0)    -- "This is ..." becomes visible again
set_active_page(0)

See Also: get_active_page, set_display_page, video_config

set_display_page

Platform: DOS32
Syntax: include image.e
set_display_page(i)
Description: Set video page i to be mapped to the visible screen.
Comments: With multiple pages you can instantaneously change the entire screen without causing any visible "flicker". You can also save the screen and bring it back quickly.

video_config() will tell you how many pages are available in the current graphics mode.

By default, the active page and the display page are both 0.

This works under DOS, or in a full-screen DOS window. In a partial-screen window you cannot change the active page.

Example: See set_active_page() example.
See Also: get_display_page, set_active_page, video_config

set_rand

Syntax: include machine.e
set_rand(i1)
Description: Set the random number generator to a certain state, i1, so that you will get a known series of random numbers on subsequent calls to rand().
Comments: Normally the numbers returned by the rand() function are totally unpredictable, and will be different each time you run your program. Sometimes however you may wish to repeat the same series of numbers, perhaps because you are trying to debug your program, or maybe you want the ability to generate the same output (e.g. a random picture) for your user upon request.
Example:
sequence s, t
s = repeat(0, 3)
t = s

set_rand(12345)
s[1] = rand(10)
s[2] = rand(100)
s[3] = rand(1000)

set_rand(12345)  -- same value for set_rand()
t[1] = rand(10)  -- same arguments to rand() as before
t[2] = rand(100)
t[3] = rand(1000)
-- at this point s and t will be identical

See Also: rand

set_vector

Platform: DOS32
Syntax: include machine.e
set_vector(i, s)
Description: Set s as the new address for handling interrupt number i. s must be a protected mode far address in the form: {16-bit segment, 32-bit offset}.
Comments: Before calling set_vector() you must store a machine-code interrupt handling routine at location s in memory.

The 16-bit segment can be the code segment used by Euphoria. To get the value of this segment see demo\dos32\hardint.ex. The offset can be the 32-bit value returned by allocate(). Euphoria runs in protected mode with the code segment and data segment pointing to the same physical memory, but with different access modes.

Interrupts occurring in either real mode or protected mode will be passed to your handler. Your interrupt handler should immediately load the correct data segment before it tries to reference memory.

Your handler might return from the interrupt using the iretd instruction, or jump to the original interrupt handler. It should save and restore any registers that it modifies.

You should lock the memory used by your handler to ensure that it will never be swapped out. See lock_memory().

It is highly recommended that you study demo\dos32\hardint.ex before trying to set up your own interrupt handler.

You should have a good knowledge of machine-level programming before attempting to write your own handler.

You can call set_vector() with the far address returned by get_vector(), when you want to restore the original handler.

Example:
set_vector(#1C, {code_segment, my_handler_address})

Example Program: demo\dos32\hardint.ex
See Also: get_vector, lock_memory, allocate

sin

Syntax: x2 = sin(x1)
Description: Return the sine of x1, where x1 is in radians.
Comments: This function may be applied to an atom or to all elements of a sequence.
Example:
sin_x = sin({.5, .9, .11})
-- sin_x is {.479, .783, .110}

See Also: cos, tan

sleep

Syntax: include misc.e
sleep(i)
Description: Suspend execution for i seconds.
Comments: On WIN32 and Linux/FreeBSD, the operating system will suspend your process and schedule other processes. On DOS32, your program will go into a busy loop for i seconds, during which time other processes may run, but they will compete with your process for the CPU.

With multiple tasks, the whole program sleeps, not just the current task. To make just the current task sleep, you can call task_schedule(task_self(), {i, i}) and then execute task_yield().

Example:
puts(1, "Waiting 15 seconds...\n")
sleep(15)
puts(1, "Done.\n")
See Also: lock_file, abort, time

sort

Syntax: include sort.e
s2 = sort(s1)
Description: Sort s1 into ascending order using a fast sorting algorithm. The elements of s1 can be any mix of atoms or sequences. Atoms come before sequences, and sequences are sorted "alphabetically" where the first elements are more significant than the later elements.
Example 1:
x = 0 & sort({7,5,3,8}) & 0
-- x is set to {0, 3, 5, 7, 8, 0}

Example 2:
y = sort({"Smith", "Jones", "Doe", 5.5, 4, 6})
-- y is {4, 5.5, 6, "Doe", "Jones", "Smith"}

Example 3:
database = sort({{"Smith",   95.0, 29},
                 {"Jones",   77.2, 31},
                 {"Clinton", 88.7, 44}})

-- The 3 database "records" will be sorted by the first "field"
-- i.e. by name. Where the first field (element) is equal it
-- will be sorted by the second field etc.

-- after sorting, database is:
               {{"Clinton", 88.7, 44},
                {"Jones",   77.2, 31},
                {"Smith",   95.0, 29}}

See Also: custom_sort, compare, match, find

sound

Platform: DOS32
Syntax: include graphics.e
sound(i)
Description: Turn on the PC speaker at frequency i. If i is 0 the speaker will be turned off.
Comments: On WIN32 and Linux/FreeBSD no sound will be made.
Example:
sound(1000) -- starts a fairly high pitched sound


sprint

Syntax: include misc.e
s = sprint(x)
Description: The representation of x as a string of characters is returned. This is exactly the same as print(fn, x), except that the output is returned as a sequence of characters, rather than being sent to a file or device. x can be any Euphoria object.
Comments: The atoms contained within x will be displayed to a maximum of 10 significant digits, just as with print().
Example 1:
s = sprint(12345)
-- s is "12345"

Example 2:
s = sprint({10,20,30}+5)
-- s is "{15,25,35}"

See Also: print, sprintf, value, get

sprintf

Syntax: s = sprintf(st, x)
Description: This is exactly the same as printf(), except that the output is returned as a sequence of characters, rather than being sent to a file or device. st is a format string, x is the value or sequence of values to be formatted. printf(fn, st, x) is equivalent to puts(fn, sprintf(st, x)).
Comments: Some typical uses of sprintf() are:

1. Converting numbers to strings.
2. Creating strings to pass to system().
3. Creating formatted error messages that can be passed to a common error message handler.

Example:
s = sprintf("%08d", 12345)
-- s is "00012345"

See Also: printf, value, sprint, get, system

sqrt

Syntax: x2 = sqrt(x1)
Description: Calculate the square root of x1.
Comments: This function may be applied to an atom or to all elements of a sequence.

Taking the square root of a negative number will abort your program with a run-time error message.

Example:
r = sqrt(16)
-- r is 4

See Also: log, power

system

Syntax: system(st, i)
Description: Pass a command string st to the operating system command interpreter. The argument i indicates the manner in which to return from the call to system():

When i is 0, the previous graphics mode is restored and the screen is cleared.

When i is 1, a beep sound will be made and the program will wait for the user to press a key before the previous graphics mode is restored.

When i is 2, the graphics mode is not restored and the screen is not cleared.

Comments: i = 2 should only be used when it is known that the command executed by system() will not change the graphics mode.

You can use Euphoria as a sophisticated "batch" (.bat) language by making calls to system() and system_exec().

system() will start a new DOS or Linux/FreeBSD shell.

system() allows you to use command-line redirection of standard input and output in the command string st.

Under DOS32, a Euphoria program will start off using extended memory. If extended memory runs out the program will consume conventional memory. If conventional memory runs out it will use virtual memory, i.e. swap space on disk. The DOS command run by system() will fail if there is not enough conventional memory available. To avoid this situation you can reserve some conventional (low) memory by typing:

    SET CAUSEWAY=LOWMEM:xxx
where xxx is the number of K of conventional memory to reserve. Type this before running your program. You can also put this in autoexec.bat, or in a .bat file that runs your program. For example:
    SET CAUSEWAY=LOWMEM:80
    ex myprog.ex
This will reserve 80K of conventional memory, which should be enough to run simple DOS commands like COPY, MOVE, MKDIR etc.
Example 1:
system("copy temp.txt a:\\temp.bak", 2)
-- note use of double backslash in literal string to get
-- single backslash

Example 2:
system("ex \\test\\myprog.ex < indata > outdata", 2)
-- executes myprog by redirecting standard input and
-- standard output

See Also: system_exec, dir, current_dir, getenv, command_line

system_exec

Syntax: i1 = system_exec(st, i2)
Description: Try to run the command given by st. st must be a command to run an executable program, possibly with some command-line arguments. If the program can be run, i1 will be the exit code from the program. If it is not possible to run the program, system_exec() will return -1. i2 is a code that indicates what to do about the graphics mode when system_exec() is finished. These codes are the same as for system():

When i2 is 0, the previous graphics mode is restored and the screen is cleared.

When i2 is 1, a beep sound will be made and the program will wait for the user to press a key before the previous graphics mode is restored.

When i2 is 2, the graphics mode is not restored and the screen is not cleared.

Comments: On DOS32 or WIN32, system_exec() will only run .exe and .com programs. To run .bat files, or built-in DOS commands, you need system(). Some commands, such as DEL, are not programs, they are actually built-in to the command interpreter.

On DOS32 and WIN32, system_exec() does not allow the use of command-line redirection in the command string st, nor does it allow you to quote strings that contain blanks, such as file names.

exit codes from DOS or Windows programs are normally in the range 0 to 255, with 0 indicating "success".

You can run a Euphoria program using system_exec(). A Euphoria program can return an exit code using abort().

system_exec() does not start a new DOS shell.

Example 1:
integer exit_code
exit_code = system_exec("xcopy temp1.dat temp2.dat", 2)

if exit_code = -1 then
    puts(2, "\n couldn't run xcopy.exe\n")
elsif exit_code = 0 then
    puts(2, "\n xcopy succeeded\n")
else
    printf(2, "\n xcopy failed with code %d\n", exit_code)
end if

Example 2:
-- executes myprog with two file names as arguments
if system_exec("ex \\test\\myprog.ex indata outdata", 2) then
    puts(2, "failure!\n")
end if

See Also: system, abort

tan

Syntax: x2 = tan(x1)
Description: Return the tangent of x1, where x1 is in radians.
Comments: This function may be applied to an atom or to all elements of a sequence.
Example:
t = tan(1.0)
-- t is 1.55741

See Also: sin, cos, arctan

task_clock_start

Syntax: task_clock_start()
Description: Restart the clock used for scheduling real-time tasks. Call this routine, some time after calling task_clock_stop(), when you want scheduling of real-time tasks to continue.
Comments: task_clock_stop() and task_clock_start() can be used to freeze the scheduling of real-time tasks.

task_clock_start() causes the scheduled times of all real-time tasks to be incremented by the amount of time since task_clock_stop() was called. This allows a game, simulation, or other program to continue smoothly.

Time-shared tasks are not affected.

Example:
-- freeze the game while the player answers the phone
task_clock_stop()
while get_key() = -1 do
end while
task_clock_start()
See Also: task_clock_stop, task_schedule, task_yield, task_suspend

task_clock_stop

Syntax: task_clock_stop()
Description: Stop the scheduling of real-time tasks. Scheduling will resume when task_clock_start() is called. Time-shared tasks can continue. The current task can also continue, unless it's a real-time task and it yields.
Comments: Call task_clock_stop() when you want to take time out from scheduling real-time tasks. For instance, you want to temporarily suspend a game or simulation for a period of time.

The time() function is not affected by this.

See Also: task_clock_start, task_schedule, task_yield, task_suspend

task_create

Syntax: a2 = task_create(i1, s)
Description: Create a new task. i1 is the routine id of a user-defined Euphoria procedure. s is the list of arguments that will be passed to this procedure when the task starts executing. The result, a2, is a task identifier, created by the system. It can be used to identify this task to the other Euphoria multitasking routines.
Comments: task_create() creates a new task, but does not start it executing.

Each task has its own set of private variables and its own call stack. Global and local variables are shared between all tasks.

If a run-time error is detected, the traceback will include information on all tasks, with the offending task listed first.

Many tasks can be created that all run the same procedure, possibly with different parameters.

A task cannot be based on a function, since there would be no way of using the function result.

Each task id is unique. task_create() never returns the same task id as it did before. Task id's are integer-valued atoms and can be as large as the largest integer-valued atom (15 digits).

Example:
mytask = task_create(routine_id("myproc"), {5, 9, "ABC"})

See Also: task_schedule, task_yield, task_suspend, task_self

task_list

Syntax: s = task_list()
Description: Get a sequence containing the task id's for all active or suspended tasks.
Comments: This function lets you find out which tasks currently exist. Tasks that have terminated naturally, or have been killed are not included. You can pass a task id to task_status() to find out more about a particular task.
Example:
sequence tasks
     
tasks = task_list()
for i = 1 to length(tasks) do
    if task_status(tasks[i]) > 0 then
        printf(1, "task %d is active\n", tasks[i])
    end if
end for
See Also: task_status, task_create, task_schedule, task_yield, task_suspend

task_schedule

Syntax: task_schedule(a, x)
Description: Schedule task a to run using scheduling parameter x. a must be a task identifier returned by task_create(). If x is a positive atom, then x tells the task scheduler how many times it should run time-shared task a in one burst before it considers running other tasks. If x is a sequence, it must be a 2-element sequence {min, max}, both values greater than or equal to 0, where min and max indicate the minimum and maximum times, in seconds, to wait before running real-time task a. min and max also set the time interval for subsequent runs of task a, unless overridden by another call to task_schedule() or task_suspend().
Comments: The task scheduler, which is built-in to the Euphoria run-time system, will use the scheduling parameter x as a guide when scheduling this task. It may not always be possible to achieve the desired number of consecutive runs, or the desired time frame. For instance, a task might take so long before yielding control, that another task misses it's desired time window.

Real-time tasks have a higher priority. Time-shared tasks are run when no real-time task is ready to execute. A task can switch back and forth between real-time and time-shared. It all depends on the last call to task_schedule() for that task. The scheduler never runs a real-time task before the start of its time frame (min value), and it tries to avoid missing the task's deadline (max value).

For precise timing, you can specify the same value for min and max. However, by specifying a range of times, you give the scheduler some flexibility. This allows it to schedule tasks more efficiently, and avoid non-productive delays. When the scheduler must delay, it calls sleep(), unless the required delay is very short. sleep() lets the operating system run other programs.

The min and max values can be fractional. If the min value is smaller than the resolution of the scheduler's clock (currently 0.01 seconds on Windows and Linux/FreeBSD, and 0.55 seconds on DOS unless tick_rate() is called) then accurate time scheduling cannot be performed, but the scheduler will try to run the task several times in a row to approximate what is desired. For example, if you ask for a min time of 0.002 seconds, then the scheduler will try to run your task .01/.002 = 5 times in a row before waiting for the clock to "click" ahead by .01. During the next 0.01 seconds it will run your task (up to) another 5 times etc. provided your task can be completed 5 times in one clock period.

At program start-up there is a single task running. Its task id is 0, and initially it's a time-shared task allowed 1 run per task_yield(). No other task can run until task 0 executes a task_yield().

If task 0 (top-level) runs off the end of the main file, the whole program terminates, regardless of what other tasks may still be active.

If the scheduler finds that no task is active, i.e. no task will ever run again (not even task 0), it terminates the program with a 0 exit code code, similar to abort(0).

Example:

-- Task t1 will be executed up to 10 times in a row before
-- other time-shared tasks are given control. If a real-time
-- task needs control, t1 will lose control to the real-time task.
task_schedule(t1, 10) 

-- Task t2 will be scheduled to run some time between 4 and 5 seconds
-- from now. Barring any rescheduling of t2, it will continue to
-- execute every 4 to 5 seconds thereafter.
task_schedule(t2, {4, 5})

See Also: task_create, task_yield, task_suspend, task_suspend

task_self

Syntax: a = task_self()
Description: Return the task id of the current task.
Comments: This value may be needed, if a task wants to schedule, kill or suspend itself.
Example:
-- schedule self
task_schedule(task_self(), {5.9, 6.0})

See Also: task_create, task_schedule, task_yield, task_suspend

task_status

Syntax: i2 = task_status(a)
Description: Return the status of a task. Status values are 1 (active), 0 (suspended), and -1 (task does not exist)
Comments: A task might want to know the status of one or more other tasks when deciding whether to proceed with some processing.

A -1 value could indicate a task that never existed, or a task that terminated naturally or was killed.

Example:
integer s
     
s = task_status(tid)
if s = 1 then
    puts(1, "ACTIVE\n")
elsif s = 0 then
    puts(1, "SUSPENDED\n")
else
    puts(1, "DOESN'T EXIST\n")
end if
See Also: task_list, task_create, task_schedule, task_suspend

task_suspend

Syntax: task_suspend(a)
Description: Suspend execution of task a.
Comments: This causes task a to be suspended. Task a will not be executed again unless there is a call to task_schedule() for task a. a is a task id returned from task_create().

Any task can suspend any other task. If a task suspends itself, the suspension will start as soon as the task calls task_yield().

Example:
-- suspend task 15
task_suspend(15)

-- suspend current task
task_suspend(task_self())

See Also: task_create, task_schedule, task_self, task_yield

task_yield

Syntax: task_yield()
Description: Yield control to the scheduler. The scheduler can then choose another task to run, or perhaps let the current task continue running.
Comments: Tasks should call task_yield() periodically so other tasks will have a chance to run. Only when task_yield() is called, is there a way for the scheduler to take back control from a task. This is what's known as cooperative multitasking.

A task can have calls to task_yield() in many different places in it's code, and at any depth of subroutine call.

The scheduler will use the current value of {min, max} or the current number of consecutive runs remaining, in determining when to return to the current task.

When control returns, execution will continue with the statement that follows task_yield(). The call-stack and all private variables will remain as they were when task_yield() was called. Global and local variables may have changed, due to the execution of other tasks.

Tasks should try to call task_yield() often enough to avoid causing real-time tasks to miss their time window, and to avoid blocking time-shared tasks for an excessive period of time. On the other hand, there is a bit of overhead in calling task_yield(), and this overhead is slightly larger when an actual switch to a different task takes place.

A task should avoid calling task_yield() when it is in the middle of a delicate operation that requires exclusive access to some data. Otherwise a race-condition could occur, where one task might interfere with an operation being carried out by another task. In some cases a task might need to mark some data as "locked" or "unlocked" in order to prevent this possibility. With cooperative multitasking, these concurrency issues are much less of a problem than with the preemptive multitasking that other languages support.

Example:
-- From Language war game.
-- This small task deducts life support energy from either the 
-- large Euphoria ship or the small shuttle.
-- It seems to run "forever" in an infinite loop, 
-- but it's actually a real-time task that is called
-- every 1.7 to 1.8 seconds throughout the game.
-- It deducts either 3 units or 13 units of life support energy each time.

global procedure task_life()
-- independent task: subtract life support energy 
    while TRUE do
        if shuttle then
            p_energy(-3)
        else
            p_energy(-13)
        end if
        task_yield()
    end while
end procedure
 
See Also: task_create, task_schedule, task_suspend task_suspend

text_color

Syntax: include graphics.e
text_color(i)
Description: Set the foreground text color. Add 16 to get blinking text in some modes. See graphics.e for a list of possible colors.
Comments: Text that you print after calling text_color() will have the desired color.

When your program terminates, the last color that you selected and actually printed on the screen will remain in effect. Thus you may have to print something, maybe just '\n', in WHITE to restore white text, especially if you are at the bottom line of the screen, ready to scroll up.

Example:
text_color(BRIGHT_BLUE)

See Also: bk_color

text_rows

Platform: DOS32, WIN32
Syntax: include graphics.e
i2 = text_rows(i1)
Description: Set the number of lines on a text-mode screen to i1 if possible. i2 will be set to the actual new number of lines.
Comments: Values of 25, 28, 43 and 50 lines are supported by most video cards.
See Also: graphics_mode

tick_rate

Platform: DOS32
Syntax: include machine.e
tick_rate(a)
Description: Specify the number of clock-tick interrupts per second. This determines the precision of the time() library routine. It also affects the sampling rate for time profiling.
Comments: tick_rate() is ignored on WIN32 and Linux/FreeBSD. The time resolution on WIN32 is always 100 ticks/second.

On a PC the clock-tick interrupt normally occurs at 18.2 interrupts per second. tick_rate() lets you increase that rate, but not decrease it.

tick_rate(0) will restore the rate to the normal 18.2 rate. Euphoria will also restore the rate automatically when it exits, even when it finds an error in your program.

If a program runs in a DOS window with a tick rate other than 18.2, the time() function will not advance unless the window is the active window.

With a tick rate other than 18.2, the time() function on DOS takes about 1/100 the usual time that it needs to execute. On Windows and FreeBSD, time() normally executes very quickly.

While ex.exe is running, the system will maintain the correct time of day. However if ex.exe should crash (e.g. you see a "CauseWay..." error) while the tick rate is high, you (or your user) may need to reboot the machine to restore the proper rate. If you don't, the system time may advance too quickly. This problem does not occur on Windows 95/98/NT, only on DOS or Windows 3.1. You will always get back the correct time of day from the battery-operated clock in your system when you boot up again.

Example:
tick_rate(100)
-- time() will now advance in steps of .01 seconds
-- instead of the usual .055 seconds

See Also: time, time profiling

time

Syntax: a = time()
Description: Return the number of seconds since some fixed point in the past.
Comments: Take the difference between two readings of time(), to measure, for example, how long a section of code takes to execute.

The resolution with DOS32 is normally about 0.05 seconds. On WIN32 and Linux/FreeBSD it's about 0.01 seconds.

Under DOS32 you can improve the resolution by calling tick_rate().

Under DOS32 the period of time that you can normally measure is limited to 24 hours. After that, the value returned by time() will reset and start over. If however, you have called tick_rate(), and clock ticks are happening at a rate that is higher than the usual 18.2/sec, time() will continue much longer, since in that case, Euphoria handles the clock-tick interrupt directly, and accumulates the ticks in a larger, 32-bit variable.

DOS emulation under Windows XP is not perfect. When you do time profiling, (with profile_time) the time() function might be off by several percent. This problem does not occur on Windows ME/98/95.

Example:
constant ITERATIONS = 1000000
integer p
atom t0, loop_overhead

t0 = time()
for i = 1 to ITERATIONS do
    -- time an empty loop
end for
loop_overhead = time() - t0

t0 = time()
for i = 1 to ITERATIONS do
    p = power(2, 20)
end for
? (time() - t0 - loop_overhead)/ITERATIONS
-- calculates time (in seconds) for one call to power

See Also: date, tick_rate

trace

Syntax: with trace
trace(i)
Description: If i is 1 or 2, turn on full-screen interactive statement tracing/debugging. If i is 3, turn on tracing of statements to a file called ctrace.out. If i is 0, turn off tracing. When i is 1 a color display appears. When i is 2 a monochrome trace display appears. Tracing can only occur in routines that were compiled "with trace", and trace() has no effect unless it is executed in a "with trace" section of your program.

See Part I - 3.1 Debugging for a full discussion of tracing / debugging.

Comments: Use trace(2) if the color display is hard to view on your system.

All forms of trace() are supported by the Interpreter.

Only trace(3) is supported by the Euphoria To C Translator.

Example:
if x < 0 then
    -- ok, here's the case I want to debug...
    trace(1)
    -- etc.
    ...
end if

See Also: profile, debugging and profiling

 

... continue
 
from A to B   |   from C to D   |   from E to G   |   from H to O   |   from P to R   |   from S to T   |   from U to Z