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

Taskforce PREVIEW - Run multiple programs at the same time

Started by Jan, 01 January 2013 - 01:01 AM
Jan #1
Posted 01 January 2013 - 02:01 AM
Introduction
After dropping the development of Frames a few months ago, I decided to make a successor for newer versions of computercraft. Although it has quite the same interface and functionality as Frames, it has different (and I hope better) code.

Little screenshot

Above: a craftOS-shell running lua
Below: the Taskforce taskbar with 3 tabs


Features
- Works on all sizes of displays, colored/non colored, even works on external monitors
- Has a windowmanager called 'tabland' that renders tabs, a taskbar and allows you to switch tabs with the TAB-key
- Has 'craftemu' which emulates the CraftOS shell, so you can run normal programs in a Taskforce tab.
- Mouse support for the taskbar

Upcoming Features

- Right-click menu for Tabs, with close and other API-programmable options.
- There will be a start-menu (letters 'tf') that works like a normal tab (Like the 'new tab' option in google chrome),
but I don't know exactly what I must put in there.
- The start-menu will have a right-click menu, so you can quickly shutdown, start a new shell Tab etc…


Instructions
- Run taskforce, press TAB to change tabs.
- Hold CRTL+T to exit Taskforce
NOTE: use "taskforce d" to enable debug labels


Download Latest version
Preview 3
http://pastebin.com/eBw7Mp2G
SpoilerPreview 2:
http://pastebin.com/LNWM4Nyy

preview 1
http://pastebin.com/WJ3m46hJ


Changelog
- Preview 1 released
- Fixed term.clear bug in preview 2
- Added start menu, updated tabland to support mouseclicks in preview 3
API Documentation

SpoilerAPI Documentation

grab
Low-level event grabber. It pulls events and then forwards the event to each of its 'event processors'.
After that it calls the 'renderer' and then it pulls another event.

local processor = grab.createProcessor()
Returns a new 'event processor'. After creating one you must define the key 'execute' with a function like so:

processor.label = "Something"
Define the label of the processor. Optional

processor.execute = function(…) end
Define the execute function of the processor. This will be called every time a new event comes, with the event as argument.

processor.kill()
Destroys a processor when it should be executed anymore.

grab.rendername = "Something"
Define the name of the renderer. Optional. Note there can only be one renderer.

grab.renderer = function(…) end
The renderer is called after the event processors have been called. The event is the argument.

grab.go()
Call this after the processors and renderer are ready. It will pull events and forward them to the processors, and call the renderer.
Hold CTRL+T to break the loop and return.

Here is an example of a redstone program:
Spoiler

local pro1 = grab.createProcessor()
pro1.label = "redstone forwarder"
pro1.execute = function(...)
rs.setOutput("left",rs.getInput("right"))
end
local pro2 = grab.createProcessor()
pro2.label = "redstone inverter"
pro2.execute = function(...)
rs.setOutput("front",not rs.getInput("back"))
end
grab.go()

License
Taskforce is public domain. This means you are free to use (parts of) the code in your own program.

Please report bugs and give me feedback, thanks :)/>
gngz #2
Posted 01 January 2013 - 02:10 AM
Very good.
ds84182 #3
Posted 01 January 2013 - 02:08 PM
I love this :D/>
When I first released DSOS, I had something like this (pressing Home to go to shell, End to end the current program, and Page Up and Down to cycle programs)
Dlcruz129 #4
Posted 01 January 2013 - 04:18 PM
I love this :D/>/>
When I first released DSOS, I had something like this (pressing Home to go to shell, End to end the current program, and Page Up and Down to cycle programs)

I wouldn't use those exact keys. I believe some laptops lack end and home.
kornichen #5
Posted 02 January 2013 - 03:36 AM
Is it real multitasking or are the not opened processes paused then?
CoolisTheName007 #6
Posted 02 January 2013 - 05:00 AM
I think the first rendering engine is well done (ardera), might use as inspiration.
GravityScore #7
Posted 02 January 2013 - 05:03 AM
Love this program!

I love the ability to run multiple Firewolf servers at once :D/>
1lann #8
Posted 02 January 2013 - 06:03 AM
This is awesome! Although for some reason it ain't work that well with firewolf :P/> I didn't really expect it to, though one strange problem is that the background color of firewolf becomes black :-/ Though don't get me wrong, this is reallyyy epic! :D/>
Jan #9
Posted 02 January 2013 - 09:50 AM
Is it real multitasking or are the not opened processes paused then?
It is real multitasking. The events are sent to each 'grab processor'. The grab processor will, in the case of craftemu, forward every event using coroutine.resume(), except when it key/mouse event and the tab isnt focussed.
Also graphics still work when the tab isnt active, because the rendering engines store the term call in an queue (voodoo), or write it in a raster (ardera).

I think the first rendering engine is well done (ardera), might use as inspiration.
Thanks, I got the inspiration to write ardera from this program.
Though the code isnt similiar, the principle of storing the terminal in a table is.

A problem with Ardera is that rendering is very expensive. Each collumn and each row is printed individually.
Therefore I wrote Voodoo, which remembers the term commands in a queue, and 're-executes' them on rendering.
Because the queue could grow too big, it is 'rebuild' when it is larger than 3000 commands. (see code)


Love this program!

I love the ability to run multiple Firewolf servers at once :D/>

Thanks :)/>

This is awesome! Although for some reason it ain't work that well with firewolf :P/> I didn't really expect it to, though one strange problem is that the background color of firewolf becomes black :-/ Though don't get me wrong, this is reallyyy epic! :D/>

Hmmm, the background becoming black must be a bug indeed… I will look into it.
Thanks for the feedback!

EDIT: broken link fixed
CoolisTheName007 #10
Posted 02 January 2013 - 10:29 AM
Thanks, I got the inspiration to write ardera from this program.
Though the code isnt similiar, the principle of storing the terminal in a table is.

A problem with Ardera is that rendering is very expensive. Each collumn and each row is printed individually.
Therefore I wrote Voodoo, which remembers the term commands in a queue, and 're-executes' them on rendering.
Because the queue could grow too big, it is 'rebuild' when it is larger than 3000 commands. (see code)

term calls are the most expensive. I will try to optimize by detecting when I can do more with fewer term calls, e.g. detecting same color lines, ect.
Jan #11
Posted 02 January 2013 - 10:50 AM
Thanks, I got the inspiration to write ardera from this program.
Though the code isnt similiar, the principle of storing the terminal in a table is.

A problem with Ardera is that rendering is very expensive. Each collumn and each row is printed individually.
Therefore I wrote Voodoo, which remembers the term commands in a queue, and 're-executes' them on rendering.
Because the queue could grow too big, it is 'rebuild' when it is larger than 3000 commands. (see code)

term calls are the most expensive. I will try to optimize by detecting when I can do more with fewer term calls, e.g. detecting same color lines, ect.
The voodoo.rebuild command actually does that, it renders all commands on an ardera field of cells, and then it searches for the fragments with the came front and back color, and puts it in a queue.
You can try to run 'taskforce d' , and then go to 'edit rom/programs/shell'.
When you go down you will see the queue command counter reach 3000, and then drop because of the rebuild.

Maybe the solution is to always do a rebuild before rendering?


voodoo.render = function(offx,offy,tab,target,skip)
if #tab.queue>3000 and skip==nil then
  voodoo.rebuild(tab)
end

NEWCODE:
voodoo.render = function(offx,offy,tab,target,skip)
if skip==nil then
  voodoo.rebuild(tab)
end

This would require some testing
Jan #12
Posted 02 January 2013 - 11:34 AM
This is awesome! Although for some reason it ain't work that well with firewolf :P/> I didn't really expect it to, though one strange problem is that the background color of firewolf becomes black :-/ Though don't get me wrong, this is reallyyy epic! :D/>

Hmmm, the background becoming black must be a bug indeed… I will look into it.
Thanks for the feedback!
The problem with the background was a bug in both rendering engines:
term.clear() resets the background and text color.
In the next release you will see this fixed

But the program is still not rendered fine, the title above is missing in some sites:
This is because the Tab is one row smaller than a default window, and therefore scrolling causes the
first line to dissappear.

There are 3 simple solutions:
- Do not render the bar at the top in Taskforce
- Do not render the bar at the bottom in Taskforce
- Do not render the taskbar temporary

What do you think is the best solution?

(a bit of off-topic question for all)
How should the start menu of Taskforce look like?
Lyqyd #13
Posted 02 January 2013 - 03:19 PM
I don't know if you've seen it before or not, but you may wish to take a quick look at the rendering function in my compositor API (a part of LyqydOS): https://github.com/lyqyd/LyqydOS/blob/master/compositor

The relevant function starts at line 183. This is designed for character-bordered windows, and so must handle transparency between layers, but the final draw of the buffer to the screen may give you some ideas or inspiration.
pielover88888 #14
Posted 03 January 2013 - 02:08 PM
Anybody notice that making the taskforce program the startup completely crash Computercraft Emulator, and lag and completely kill your actual computer? xD
Thank goodness that Opera has "Open from last time" ;D
CoolisTheName007 #15
Posted 04 January 2013 - 11:22 AM
Last time I checked, after a term.clear() font color isn't reset, so the voodoo engine makes some extra operations.
kornichen #16
Posted 04 January 2013 - 10:51 PM
Maybe I can use it in KREOS to run more than one program?
Jan #17
Posted 05 January 2013 - 02:15 AM
Maybe I can use it in KREOS to run more than one program?
Sure, you may use (parts of) my code if you want :)/>
kornichen #18
Posted 05 January 2013 - 02:26 AM
Maybe I can use it in KREOS to run more than one program?
Sure, you may use (parts of) my code if you want :)/>

Thank you!
Jan #19
Posted 07 January 2013 - 08:37 AM
Update: in preview 3 you can click on the letters 'tf' to open a start menu :D/>
It is very primitive, but it works. Also you can click on other Tabs to focus them.
seal6000 #20
Posted 07 January 2013 - 09:04 AM
I found a bug.

The tab all say MISSINGNO



The other thing I want to point out is that you should make it so you cant run taskforce inside a taskforce tab, creating "taskception"
Jan #21
Posted 07 January 2013 - 09:09 AM
I found a bug.

The tab all say MISSINGNO



The other thing I want to point out is that you should make it so you cant run taskforce inside a taskforce tab, creating "taskception"
The MISSINGNO was a debug thing in preview 2. It was also visible in non-debug mode, sorry, it is fixed now.

The taskception could be possible maybe if I changed the global APIS into locals… I'll try that

EDIT: It was easier than I thought! Made all APIS local, and taskception is possible :D/>
It will be possible in the next release (if you cant wait, add 'local' before each API declaration)
seal6000 #22
Posted 07 January 2013 - 09:12 AM
oh yes, just realized it was fixed, hadnt updated
pielover88888 #23
Posted 07 January 2013 - 02:09 PM
Hey Jan,
Could I have a mass amount of information on tabland and it's api? I poked with the program but I still can't make a program that can close tabs.. o_O *accidentally made alot of tabs, can't close them, irked*
Jan #24
Posted 08 January 2013 - 08:13 AM
Hey Jan,
Could I have a mass amount of information on tabland and it's api? I poked with the program but I still can't make a program that can close tabs.. o_O *accidentally made alot of tabs, can't close them, irked*
When you have a tab object, you can do tab.kill to disable it.
Also you can list the tabs in tabland.tab[index] or use tabland.activetab[index] for active tabs

In the future I am going to make Taskforce more like an API with multitasking tools,
so that you will be able to create the components (grab,tabland) you need via an API function.
But now I am busy with school again…
nutcase84 #25
Posted 08 January 2013 - 11:04 AM
Awesome program.
pielover88888 #26
Posted 08 January 2013 - 12:47 PM
Yeaah… that didn't really help, tabland.tab[index] just returns nil, and tabland.activetab[index] does the same.. :(/>
anonimo182 #27
Posted 08 January 2013 - 04:13 PM
Nice program!

But it likes to flash a lot, especially with programs that use a lot of term functions… :/
wilcomega #28
Posted 18 January 2013 - 06:31 AM
very amazing. i am supprised that not many people use multitasking in their os. once you get the hang of it its quite easy. and jan: please come online at skype, wanna ask u something :)/>
v3nw #29
Posted 18 January 2013 - 06:35 AM
COOL ;)/>
nutcase84 #30
Posted 26 February 2013 - 07:25 AM
Can I merge this with nut os? This will help me make a window system…
Prototypep #31
Posted 07 April 2013 - 09:52 AM
What an awesome program! :D/>