Welcome to Doom9's Forum, THE in-place to be for everyone interested in DVD conversion.

Before you start posting please read the forum rules. By posting to this forum you agree to abide by the rules.

 

Go Back   Doom9's Forum > Capturing and Editing Video > Avisynth Usage

Reply
 
Thread Tools Search this Thread Display Modes
Old 27th October 2013, 10:55   #1  |  Link
martin53
Registered User
 
Join Date: Mar 2007
Posts: 407
Runtime variables scope and lifetime

EDIT 13th November 2013: put discussion result here. The code example is a framework for a versatile and robust RTE usage.

Code:
#~ Example needs Gavino's GRunT, GScript and StainlessS' RT_Stats plugins

function RTE(clip c, string ExampleVarFromNonRTE_Parameter) {
    #######################################
    # Unique Identifier Definition
    #######################################
    Try { global RTE_InstanceNumber = RTE_InstanceNumber+1 } catch(err) { global RTE_InstanceNumber = 1 }

    # Runtime Environment Preparation & Call
    GScript(RT_StrReplace("""	#"   for use without GScript, use Eval( instead
        #######################################
        # 1) Unique Global Variables Initialization
        #######################################
        global RTE_last_frame%%% = -1
        # ... more variables as needed
        
        #######################################
        # 2) Unique Runtime Function Definition
        #######################################
        function RTE_%%%(clip c, string JustMyExampleString) {
            # ... insert complete runtime code here
            # NOTE: Avoid GScript("...") and Eval("...") inside this function, i.e. all functions which expect a script string
            Try {
                c
                Subtitle(string(current_frame - RTE_last_frame%%%))
                Subtitle(JustMyExampleString, align=4)
                global RTE_last_frame%%% = current_frame
                return last
            } catch (err) {
                assert(false, "RTE_ScriptClip %%%: "+err)
            }
        }
        
        #######################################
        # 3) Unique Runtime Call
        #######################################
        ARGS = "ExampleVarFromNonRTE_Parameter"
        c
        #ScriptClip must be a one-liner:
        GScriptClip("RTE_%%%(last, "+ARGS+")", local=true, args=ARGS)
    """, "%%%", string(RTE_InstanceNumber)))	#"
    return last
}

ExampleVarFromNonRTE = "hi there"
BlankClip()
StackHorizontal(last.RTE(ExampleVarFromNonRTE), last.RTE("it works"))

(probably this is a reopening of earlier discussions)

Many, especially powerful scripts like 'Srestore()' use the runtime environment to vary processing on frame level.

The variables they use inside the runtime environment are typically 'shared', in that they share one scope. The variables are 'static' in that their lifetime is same as script lifetime. During rendering stage, the value from the previously processed frame is still there when the function (graph node) is called again.

This approach has the advantage, that the function can build the processing on the previous processing, which is crucial for many algorithms. It has the severe disadvantage however, that multiple instances of the function mash up their variables (even worse: no matter if the same runtime function is used in several nodes of the graph, or even a different function uses a variable with the same name). It makes it impossible to use the function for more than one node in the video graph without interference, as shown in the example.

In a proper implementation and environment, both frames should show a '1' when the clip is rendered forward frame by frame, or the distance from the previous frame otherwise:
Code:
#~ Example needs Gavino's GRunt plugin!
function RTE(clip c) {
    c.GScriptClip("""	# "
    Try { last_frame = last_frame } catch(err) { last_frame = -100 }
    Subtitle(string(current_frame - last_frame))
    last_frame = current_frame
    last
    """, local=false)	#"
}
BlankClip()
StackHorizontal(last.RTE(), last.RTE())
Thanks to and since Gavino's GRunT plugin, the scope can be set to 'local=true'.

This makes the scopes of each RTE instance separate, which is highly desirable in many cases, allowing more than one instance (node) to work properly, and reliefs from problems like 'tunneling x' between different functions.
*But* as second effect, the lifetimes are then restricted to one execution of the function. For the next rendered frame, all previous information is lost. Thus, all algorithms that tie in with the previous frame can not be implemented this way - Except they use global variables, but then the other problem reappears.

For all plugins, it is not a question that it is possible to use them twice ore more in a script, and if they use static variables - no problem.
But for scripted functions, it seems impossible.

Any suggestions?

Last edited by martin53; 13th November 2013 at 08:30. Reason: better (I think) wording
martin53 is offline   Reply With Quote
Old 27th October 2013, 11:49   #2  |  Link
Gavino
Avisynth language lover
 
Join Date: Dec 2007
Location: Spain
Posts: 3,431
Quote:
Originally Posted by martin53 View Post
But for scripted functions, it seems impossible.

Any suggestions?
One crude way is for the function to use unique variable names for each instance. For example, using a global counter to keep track of calls and appending the 'instance number' to each variable name. A bit messy since you need to build up the run-time script dynamically inside the function using string concatenation.
__________________
GScript and GRunT - complex Avisynth scripting made easier
Gavino is offline   Reply With Quote
Old 27th October 2013, 12:38   #3  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
As per Gavino method above but using string replacement rather than very messy concatenation, would be my choice.
__________________
I sometimes post sober.
StainlessS@MediaFire ::: AND/OR ::: StainlessS@SendSpace

"Some infinities are bigger than other infinities", but how many of them are infinitely bigger ???
StainlessS is offline   Reply With Quote
Old 27th October 2013, 14:41   #4  |  Link
Gavino
Avisynth language lover
 
Join Date: Dec 2007
Location: Spain
Posts: 3,431
Quote:
Originally Posted by StainlessS View Post
using string replacement rather than very messy concatenation
Yes, that's much neater.
__________________
GScript and GRunT - complex Avisynth scripting made easier
Gavino is offline   Reply With Quote
Old 27th October 2013, 14:57   #5  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
M53, how would a suite of eg
RT_ArrayAlloc, RT_ArrayGetInt, RT_ArrayGetFloat, RT_ArraySetInt, RT_ArraySetFloat, RT_ArrayAddInt, RT_ArrayAddFloat, RT_ArrayGetSize,
style funcs grab you, using a file to store 4 byte int or 4 byte floats which MUST be user controlled as far as contents is concerned, ie an
int would produce rubbish if accessed as float ?

It would provide fast random access to read array elements.

EDIT: Change of mind, would be of fixed type on RT_ArrayAlloc, int, float or string, with fixed maximum length strings if string (default 256).

Bit OT, hope you dont mind, guess I should have posted in RT thread.
__________________
I sometimes post sober.
StainlessS@MediaFire ::: AND/OR ::: StainlessS@SendSpace

"Some infinities are bigger than other infinities", but how many of them are infinitely bigger ???

Last edited by StainlessS; 27th October 2013 at 15:16.
StainlessS is offline   Reply With Quote
Old 27th October 2013, 15:37   #6  |  Link
martin53
Registered User
 
Join Date: Mar 2007
Posts: 407
Quote:
Originally Posted by Gavino View Post
For example, using a global counter to keep track of calls and appending the 'instance number' to each variable name. A bit messy ...
I omitted this concept from my 1st post for its imagined clumsiness...

Honestly, I thought it was near impossible. But in the run to demonstrate how messy an example would look like, I figured out something not *that* bad. The impact on RTE script readability is small, and it might even be seen as obvious marks for variables that persist between calls.

EDIT 13th Nov 2013: Extracted+assembled the runtime commands into a function definition. This is important because the string inside ScriptClip("") is re-evaluated for every frame and will make the AviSynth string heap overflow. AviSynth does not clean up the heap until script end.

Moved example to 1st post


I can't say I love it. But I think this will replace my previous ScriptClip() template. And of course I hope it may be useful for other RTE writers, too.
The marker %%% can be replaced with any personal favourite.

EDIT: included init part for global variables according to Gavino's proposal some posts below.
Note: The Try ... catch ... function inside the GScriptClip() is typically not needed for a RTE function which processes the output clip. But it is highly useful for RTE-made 'helper' clips, which themselves are used by another RTE function, because a potential error message in such a clip will not be visible in the output clip

Last edited by martin53; 13th November 2013 at 08:31. Reason: included var initialization
martin53 is offline   Reply With Quote
Old 27th October 2013, 15:56   #7  |  Link
martin53
Registered User
 
Join Date: Mar 2007
Posts: 407
EDIT: This post is outdated because the initialization is now included in the full example above.

And don't forget: It is dangerous/buggy to define global vars for RTE functions at global script level like it was usual all the time:

...
global RTE_myVar = 0
...

since no such variable without appended index will exist any more, and the really existing ones remain undefined.

To stay indeppendent from number of instances, maybe better style to define inside RTE, after check that they're undefined:
Code:
GScriptClip("""
    ...
    try { __ = RTE_myVar%%%%%% } catch(err) { global RTE_myVar%%%%%% = 0 }
    ...
    first use of RTE_myVar%%%%%% in RTE
    ...
""", local=true)
If you know what you do, you may define a whole bunch in one catch block (faster), or you may check each var separately.

Last edited by martin53; 27th October 2013 at 20:01. Reason: reference to init in post above
martin53 is offline   Reply With Quote
Old 27th October 2013, 15:59   #8  |  Link
martin53
Registered User
 
Join Date: Mar 2007
Posts: 407
Quote:
Originally Posted by StainlessS View Post
how would a suite ...
Glad you ask! performant arrays (i.e. not! abused strings!!! ) are needed desperately, but let's discuss in RT thread, and maybe not instantly.

Last edited by martin53; 27th October 2013 at 16:05.
martin53 is offline   Reply With Quote
Old 27th October 2013, 16:20   #9  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
M53, while i'm doing Array thing, I'll do an RT_IncrGlobal(String GlobalName,int "default"=1) style func.
__________________
I sometimes post sober.
StainlessS@MediaFire ::: AND/OR ::: StainlessS@SendSpace

"Some infinities are bigger than other infinities", but how many of them are infinitely bigger ???

Last edited by StainlessS; 27th October 2013 at 16:25.
StainlessS is offline   Reply With Quote
Old 27th October 2013, 16:55   #10  |  Link
martin53
Registered User
 
Join Date: Mar 2007
Posts: 407
Just applied the described concept on the AWB() script.

- It's great! For the first time, it is possible to compare settings side by side! That also would enrich Srestore() and others.
martin53 is offline   Reply With Quote
Old 27th October 2013, 18:03   #11  |  Link
Gavino
Avisynth language lover
 
Join Date: Dec 2007
Location: Spain
Posts: 3,431
Quote:
Originally Posted by martin53 View Post
To stay indeppendent from number of instances, maybe better style to define inside RTE, after check that they're undefined:
Code:
GScriptClip("""
    ...
    try { __ = RTE_myVar%%%%%% } catch(err) { global RTE_myVar%%%%%% = 0 }
    ...
    first use of RTE_myVar%%%%%% in RTE
    ...
""", local=true)
An alternative would be to initialise in the function, but outside the RTE, avoiding a try/catch on each frame.
Code:
Eval("global RTE_myVar"+string(RTE_InstanceNumber)+"=0")
Both approaches are a bit ugly!

If staying with the try/catch approach, note the assignment to __ is unnecessary:
Code:
    try { RTE_myVar%%%%%% } catch(err) { global RTE_myVar%%%%%% = 0 }
__________________
GScript and GRunT - complex Avisynth scripting made easier
Gavino is offline   Reply With Quote
Old 27th October 2013, 19:34   #12  |  Link
martin53
Registered User
 
Join Date: Mar 2007
Posts: 407
Quote:
Originally Posted by Gavino View Post
An alternative would be to initialise in the function, but outside the RTE, avoiding a try/catch on each frame.
Code:
Eval("global RTE_myVar"+string(RTE_InstanceNumber)+"=0")
Both approaches are a bit ugly!

If staying with the try/catch approach, note the assignment to __ is unnecessary:
Code:
    try { RTE_myVar%%%%%% } catch(err) { global RTE_myVar%%%%%% = 0 }
Thank you very much for your interest in my question and the participation!
The first suggestion is good. I think I'd use the RT_StrReplace again instead of the concatenation, so a whole bunch of variables can be processed in one script block and it still looks readable.

I think I thoroughly tried the elimination of the assignment, but I failed. I remember you gave me that same hint already, and tried to use it - will try again, maybe I just almost used the right syntax.

EDIT: checked both positive. Will edit the above post.

Last edited by martin53; 27th October 2013 at 19:42. Reason: Checked proposals
martin53 is offline   Reply With Quote
Old 28th June 2014, 11:10   #13  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
That is a very long Safari you are on M53, when are you coming back ?

I've just been playing with this to good effect (great multi-instance scene change detector coming).

Below my preferred usage of your example framework.
I've used '@@@' rather than '%%%' as '%' can be used in eg String() func and some RT_Stats formatted output funcs.
I've also re-ordered some things and implemented Debug output so you can verify conformity with intent.

EDIT: Also, I think eg ImageSource() uses '%%' as an Escape for '%' where you want a single percent char
in a filename, and I think it is also possible that eg '%%%' could be legally used in ImageSource, to mean literal
single percent, followed by inserted frame number.

Here tis:
Code:
Function RTE(clip c, string "ExampleVarFromNonRTE_Parameter") {
    FuncS="""
        #######################################
        # 1) Unique Runtime Function Definition
        #######################################
        Function RTE_@@@(clip c, string JustMyExampleString) {               # No Optional Arguments in unique RTE func
            # ... insert complete runtime code here
            # NOTE: Avoid GScript("...") and Eval("...") inside this function, i.e. all functions which expect a script string
            # Can use Gscript if/else etc in here if called via GScript(InstS) rather than Eval(InstS)
            Try {
                c
                Subtitle(string(current_frame - RTE_last_frame@@@))
                Subtitle(JustMyExampleString, align=4)
                global RTE_last_frame@@@ = current_frame
                return last
            } catch (err) {
                assert(false, "RTE_ScriptClip @@@: "+err)
            }
        }
        #######################################
        # 2) Unique Global Variables Initialization
        #######################################
        global RTE_last_frame@@@ = -1
        # ... more variables as needed
        #######################################
        # 3) Unique Runtime Call
        #######################################
        ARGS = "ExampleVarFromNonRTE_Parameter"
        #ScriptClip must be a one-liner:
        Last.GScriptClip("RTE_@@@(last, "+ARGS+")", local=true, args=ARGS)  # Grunt needed for Args
    """
    # Optional args must be handled in main function
    ExampleVarFromNonRTE_Parameter=Default(ExampleVarFromNonRTE_Parameter,"No Example String given")
    #######################################
    # 4) Unique Identifier Definition
    #######################################
    RT_IncrGlobal("RTE_InstanceNumber")                                    # Instead of Try/Catch
    InstS = RT_StrReplace(FuncS,"@@@",String(RTE_InstanceNumber))          # Unique Instance function string
    RT_TxtWriteFile(InstS,"DEBUG_RTE_"+String(RTE_InstanceNumber)+".TXT")
    c
    # Runtime Environment Call
    GScript(InstS)                                                         #   for use without GScript, use Eval( instead
    return last
}


ExampleVarFromNonRTE = "hi there"
#ExampleVarFromNonRTE = RT_Undefined
BlankClip()
StackHorizontal(last.RTE(ExampleVarFromNonRTE), last.RTE("it works"))
Debug output from Instance 2
Code:
        #######################################
        # 1) Unique Runtime Function Definition
        #######################################
        Function RTE_2(clip c, string JustMyExampleString) {               # No Optional Arguments in unique RTE func
            # ... insert complete runtime code here
            # NOTE: Avoid GScript("...") and Eval("...") inside this function, i.e. all functions which expect a script string
            # Can use Gscript if/else etc in here if called via GScript(InstS) rather than Eval(InstS)
            Try {
                c
                Subtitle(string(current_frame - RTE_last_frame2))
                Subtitle(JustMyExampleString, align=4)
                global RTE_last_frame2 = current_frame
                return last
            } catch (err) {
                assert(false, "RTE_ScriptClip 2: "+err)
            }
        }
        #######################################
        # 2) Unique Global Variables Initialization
        #######################################
        global RTE_last_frame2 = -1
        # ... more variables as needed
        #######################################
        # 3) Unique Runtime Call
        #######################################
        ARGS = "ExampleVarFromNonRTE_Parameter"
        #ScriptClip must be a one-liner:
        Last.GScriptClip("RTE_2(last, "+ARGS+")", local=true, args=ARGS)  # Grunt needed for Args
EDIT: Oops, RT_WriteFile not as yet available in RT_Stats, (fixed above).
__________________
I sometimes post sober.
StainlessS@MediaFire ::: AND/OR ::: StainlessS@SendSpace

"Some infinities are bigger than other infinities", but how many of them are infinitely bigger ???

Last edited by StainlessS; 1st July 2014 at 18:04.
StainlessS is offline   Reply With Quote
Old 29th June 2014, 13:51   #14  |  Link
fvisagie
Registered User
 
Join Date: Aug 2008
Location: Isle of Man
Posts: 588
Quote:
Originally Posted by martin53 View Post
EDIT 13th Nov 2013: Extracted+assembled the runtime commands into a function definition. This is important because the string inside ScriptClip("") is re-evaluated for every frame and will make the AviSynth string heap overflow. AviSynth does not clean up the heap until script end.

Moved example to 1st post
Unfortunately for someone without much experience like myself the original example no longer exists to illustrate the context of the string inside ScriptClip() that could cause this problem. Are you saying string declarations inside ScriptClip() could cause this - care to elaborate?

In martin53's presumed absence, feel free to pipe up with an explanation, StainlessS or Gavino .
fvisagie is offline   Reply With Quote
Old 29th June 2014, 15:09   #15  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
I'm not sure exactly what M53 was referring to there, I have had a bit of a look for another thread that
resulted in this thread, but could not find it.

But,

Whenever you do something like Subtitle("AveLuma="+String(AverageLuma)) inside ScriptClip, it results in a new string
(the concatenated string, and at every frame, perhaps even 3 strings, the string for "AveLuma=", the String(AverageLuma)
and the concatenated one) that occupies heap memory until Avisynth closes down (I was personally
quite shocked when I discovered that there was no memory garbage collection, not even strings created in script local
functions [I think]).

I'm not alogether sure but think that, if you call scriptclip with ScriptClip("""Subtitle("AveLuma="+String(AverageLuma))""")
then the ScriptClip string arg is instantiated only once, but the SubTitle string arg at every frame.
EDIT: Same with Eval(), strings created at every frame if used inside of Scriptclip, but if you eg
use Grunt()'s 'args' arg, then you can pass in a named argument string variable from outside, and could do an Eval on this
arg string variable that was instantiated only once at main script level.
EDIT: Just had a think about it, ScriptClip does NOT instantiate string mem for its arg at every frame, it is a filter that is linked
into the filter graph, and so the string would only be created when calling the Scriptclip constructor, before frame serving starts.
Inside of ScriptClip, ScriptClip parses the string given to its constructor and at every frame, and every function and filter
is called as if for the first time, all quoted strings inside of Scriptclip are instantiated and on each frame.
If a GScript function is instantiated, eg GSCript(""" Function fn() { Return "Hello"} """) , I dont know if it is in some way tokenized,
and the "Hello" string allocated memory just the once, or every time the function is called.
Perhaps even ScriptClip tokenizes its string arg and so string literals may only be allocated once, perhaps the chosen one will
enlighten us (although he has probably enlightened me on same subject several gazillon times already).



Oh, just found this in developer forum, perhaps of some interest.
http://forum.doom9.org/showthread.php?p=1587841
__________________
I sometimes post sober.
StainlessS@MediaFire ::: AND/OR ::: StainlessS@SendSpace

"Some infinities are bigger than other infinities", but how many of them are infinitely bigger ???

Last edited by StainlessS; 29th June 2014 at 16:22.
StainlessS is offline   Reply With Quote
Old 30th June 2014, 00:19   #16  |  Link
Gavino
Avisynth language lover
 
Join Date: Dec 2007
Location: Spain
Posts: 3,431
As StainlessS says, the string argument to ScriptClip() is instantiated once only, when the outer script is parsed.

However, at run-time, that string is itself parsed afresh by ScriptClip() for every frame, each time using up space in Avisynth's string table for variable names, etc. Most of the time, this is not significant, but if ScriptClip is called with a very long run-time script or called recursively to a great depth, coupled with lots of source frames, it could eventually eat up a lot of memory.

To avoid this, it is recommended to use functions to cut down the size of a long run-time script. See this post.
__________________
GScript and GRunT - complex Avisynth scripting made easier
Gavino is offline   Reply With Quote
Old 30th June 2014, 09:40   #17  |  Link
fvisagie
Registered User
 
Join Date: Aug 2008
Location: Isle of Man
Posts: 588
That's very helpful, thanks guys.

More on topic, what about nested variables and arguments of functions pre-defined at the top-level script scope but called at runtime? According to the documentation
Quote:
The lifetime of variables defined at nested local scopes spans from the time of the definition in the nested local scope to the end of the nested local scope's lifetime.
It's well understood that such variables and arguments - not that there's much distinction in this regard - are not usable beyond the lifetime of the nested scope. But what about the memory occupied by them - when does that get released, specifically when called from runtime? If only when the script is closed, I would imagine the best way to limit per-frame memory growth from calling functions at runtime would be to use 'static' variables, i.e. globals and top-level script variables, wherever sensible? If so and assuming no calls to runtime functions from top-level code, are there any clear pros and cons to using globals vs. top-level script variables?

When is memory used by variables declared in "top-level" runtime code released? And, for the sake of completeness, that of variables and arguments of functions declared in runtime code (not that I can think of any good reason for that)?

EDIT: I suspect some or most of this is probably addressed by StainlessS' post above, in which case I humbly ask your indulgence for my limited understanding!

Last edited by fvisagie; 30th June 2014 at 09:48.
fvisagie is offline   Reply With Quote
Old 30th June 2014, 10:25   #18  |  Link
Gavino
Avisynth language lover
 
Join Date: Dec 2007
Location: Spain
Posts: 3,431
Quote:
Originally Posted by fvisagie View Post
It's well understood that such variables and arguments - not that there's much distinction in this regard - are not usable beyond the lifetime of the nested scope. But what about the memory occupied by them - when does that get released, specifically when called from runtime?
All values (of all types) in Avisynth are structures referenced via so-called 'smart' pointers, and are freed the moment there is no longer anything pointing at them. In general then, when a variable goes out of scope, its value will be freed, unless there is another reference to it somewhere (eg via 'last').

However, string values themselves just contain pointers to the actual characters which (for most strings, and certainly those created by script operations) are stored in the string heap. As StainlessS pointed out above, the contents of this heap are not freed until the script is unloaded, even though the string values pointing to them may have been deleted.
__________________
GScript and GRunT - complex Avisynth scripting made easier
Gavino is offline   Reply With Quote
Old 30th June 2014, 11:55   #19  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
Even if desired by Avisynth developers, I dont think strings (the actual string characters) could be freed, as it is
in docs that plugin devs can return a string to Avisynth using env->SaveString to make a copy of a plugin's
string (mem allocation is quite separate between plugins and Avisynth, string memory is copied from plugin memory
heap to Avisynth memory heap, giving Avisynth total ownership and duty to later free mem), and if they
(plug devs) keep a pointer to that memory block they can re-use it so long as they do not overwrite the bounds
of that memory block which is owned by Avisynth.
One thing I have found though, (and I dont think it was mentioned in docs anywhere), if setting a local or global variable
from within a plugin, it is unnecessary to env->SaveString() the name of the variable, if it already exists, Avisynth will
not re-create another variable (with identical name) in the string table, the old one will be re-used. (kinda makes sense really).
The only way that some script local strings could be freed would be if future versions of avisynth kept separate track of strings
created locally by the parser, and were in no way returned by - or created by a plugin.
[Although perhaps a new env-SaveString2() or whatever could be added which plugin writers could not later access contents of.]

EDIT: I'm not actually aware of any plugin that later uses string memory now belonging to Avisynth, although I would not
be surprised if AVSLib did so.
__________________
I sometimes post sober.
StainlessS@MediaFire ::: AND/OR ::: StainlessS@SendSpace

"Some infinities are bigger than other infinities", but how many of them are infinitely bigger ???

Last edited by StainlessS; 30th June 2014 at 12:10.
StainlessS is offline   Reply With Quote
Old 30th June 2014, 13:45   #20  |  Link
fvisagie
Registered User
 
Join Date: Aug 2008
Location: Isle of Man
Posts: 588
Thanks again, guys.

Just to cross the Ts and dot the Is,
Quote:
Originally Posted by StainlessS View Post
Code:
    # Runtime Environment Call
    GScript(InstS)                                                         #   for use without GScript, use Eval( instead
Is it true to say that were Eval() to be used instead of GScript(), current_frame would have to be passed as a parameter to RTE_@@@()?
fvisagie is offline   Reply With Quote
Reply

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT +1. The time now is 22:38.


Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2024, vBulletin Solutions Inc.