This is a read-only snapshot of the ComputerCraft forums, taken in April 2020.
Lewisk3's profile picture

Run code when any function is called?

Started by Lewisk3, 27 November 2015 - 04:43 AM
Lewisk3 #1
Posted 27 November 2015 - 05:43 AM
Hey i was wondering if its possible to test if any function is called (just not the native os ones like print() write() ect.)
and if the function is called then run something before running the function

is there a _G lib that i can overwrite to accomplish this?

thanks for the help in advance.
Waitdev_ #2
Posted 27 November 2015 - 06:03 AM
maybe you could cycle through the _G library? i'm not sure how its possible, but maybe.
Lewisk3 #3
Posted 27 November 2015 - 06:06 AM
maybe you could cycle through the _G library? i'm not sure how its possible, but maybe.

thats exactly what i was thinking.
only problem is i dont know how or where the library is located
valithor #4
Posted 27 November 2015 - 06:21 AM
maybe you could cycle through the _G library? i'm not sure how its possible, but maybe.

thats exactly what i was thinking.
only problem is i dont know how or where the library is located

It is located in _G


local function yourfunction()
--# do stuff
end

local function cycle(tbl)
  for k,v in pairs(tbl) do
	if type(v) == "function" then
	  tbl[k] = function() yourfunction() return v() end
	elseif type(v) == "table" then
	  cycle(v)
	end
  end
end

cycle(_G)

That is just off the top of my head no guarantees it won't error.

edit:

Just know that will do all functions except for the shell, and multishell api iirc. It will not do those two due to how they are loaded.
Edited on 27 November 2015 - 05:22 AM
Bomb Bloke #5
Posted 27 November 2015 - 06:50 AM
_G won't help you if you truly want to cover "any" function. The CraftOS shell launches in a separate environment, and any scripts the user executes place their globals into that (as opposed to _G).

It'd be easy enough to get the desired environment table, but that still won't get you any variables the user defines as local to their scripts - and if the user's code is running, odds are you won't be able to do anything in between the time when they define and then execute new functions anyway!

So to me, the answer would be to load in their code as a string, alter it to do what you want it to do, then loadstring & pcall result.

But I suspect you're trying to hammer a square peg into a round hole here. You may be better off explaining what your actual end goal is, and asking how best to go about it.
Lewisk3 #6
Posted 27 November 2015 - 11:37 AM
_G won't help you if you truly want to cover "any" function. The CraftOS shell launches in a separate environment, and any scripts the user executes place their globals into that (as opposed to _G).

It'd be easy enough to get the desired environment table, but that still won't get you any variables the user defines as local to their scripts - and if the user's code is running, odds are you won't be able to do anything in between the time when they define and then execute new functions anyway!

So to me, the answer would be to load in their code as a string, alter it to do what you want it to do, then loadstring & pcall result.

But I suspect you're trying to hammer a square peg into a round hole here. You may be better off explaining what your actual end goal is, and asking how best to go about it.

ok im trying to make a no flicker api so before any function runs i was
to run term.current().setVisible(false)

then after i want to run
term.current().setVisible(true)
H4X0RZ #7
Posted 27 November 2015 - 12:49 PM
_G won't help you if you truly want to cover "any" function. The CraftOS shell launches in a separate environment, and any scripts the user executes place their globals into that (as opposed to _G).

It'd be easy enough to get the desired environment table, but that still won't get you any variables the user defines as local to their scripts - and if the user's code is running, odds are you won't be able to do anything in between the time when they define and then execute new functions anyway!

So to me, the answer would be to load in their code as a string, alter it to do what you want it to do, then loadstring & pcall result.

But I suspect you're trying to hammer a square peg into a round hole here. You may be better off explaining what your actual end goal is, and asking how best to go about it.

ok im trying to make a no flicker api so before any function runs i was
to run term.current().setVisible(false)

then after i want to run
term.current().setVisible(true)
If want to removed that, just either separate drawing and the calculations or use a buffer API.
Lewisk3 #8
Posted 27 November 2015 - 01:20 PM
If want to removed that, just either separate drawing and the calculations or use a buffer API.

i want to make my OWN api
and i want it to automatically use no flicker when a function is called
that way theres no user input required.
Edited on 27 November 2015 - 12:20 PM
H4X0RZ #9
Posted 27 November 2015 - 01:43 PM
If want to removed that, just either separate drawing and the calculations or use a buffer API.

i want to make my OWN api
and i want it to automatically use no flicker when a function is called
that way theres no user input required.

But why? If there are solutions, why code another one?
Bomb Bloke #10
Posted 27 November 2015 - 01:54 PM
"To see if one can." "For fun." "To learn something through the process." If no one wrote code that hadn't been done before, these forums would be rather empty.

ok im trying to make a no flicker api so before any function runs i was
to run term.current().setVisible(false)

then after i want to run
term.current().setVisible(true)

That particular method would cause a decent amount of slowdown; you'd be performing a full screen redraw every single time a function was called, whether or not that function actually attempted to perform a screen update.

You may be better off overriding os.pullEvent(), so that every time it's called it triggers a redraw if os.clock() has changed since it was last called and a term function was called within that time - the rest of the time you keep the window's visibility turned off. That way you only need to override the terminal object and os.pullEvent(), and you're also not going to be redrawing excessively.

That said, even with that technique there'll be minimal benefit - if any. It depends on the script you're running; 3D engines written prior to the introduction of term.blit() would probably see the most notable speed boosts, whereas some other scripts will simply run slower. When you get right down to it, the user's script is always going to be in a better position to figure out what should be drawn when.