-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpytermrender.py
195 lines (160 loc) · 4.87 KB
/
pytermrender.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
import __main__, time, math, functools
from colorama import Style
## Definitions
printr = functools.partial(print, end="")
class RenderException(Exception):
pass
class TermScreen:
width: int
height: int
framerate: float
frame_no: int = 0
buffers: list = ["char", "color"]
tickers: dict
state: dict
def __init__(self, *, width: int = 80, height: int = 24, framerate: float = 30.0):
self.width=width
self.height=height
self.framerate=framerate
self.buffer_char = [[" "]*self.width for i in range(self.height)]
self.buffer_color = [[Style.RESET_ALL]*self.width for i in range(self.height)]
self.tickers = {}
self.state = {}
return
def reset_buffer(self, buffer="char"):
if buffer not in self.buffers:
raise RenderException("Buffer Does not exist")
match buffer:
case "char":
self.buffer_char = [[" "]*self.width for i in range(self.height)]
case "color":
self.buffer_color = [[Style.RESET_ALL]*self.width for i in range(self.height)]
return
def reset_buffer_line(self, line=0, buffer="char"):
if buffer not in self.buffers:
raise RenderException("Buffer Does not exist")
if line >= self.height:
raise RenderException("Line is out of range of height")
match buffer:
case "char":
self.buffer_char[line] = [" "]*self.width
case "color":
self.buffer_color[line] = [Style.RESET_ALL]*self.width
return
def put_buffer(self, x, y, val, buffer="char"):
if buffer not in self.buffers:
raise RenderException("Buffer Does not exist")
if x >= self.width or y >= self.height:
raise RenderException("Point is out of range of the buffer")
char=str(val)
match buffer:
case "char":
self.buffer_char[y][x] = char
case "color":
self.buffer_color[y][x] = char
return
def render(self):
for y in range(self.height):
for x in range(self.width):
printr(self.buffer_color[y][x])
printr(self.buffer_char[y][x])
print() #print \n
return
def framerateMaker(func, perSec):
interval = 1.0 / perSec
while True:
start_time = time.time()
func()
elapsed = time.time() - start_time
if elapsed < interval:
time.sleep(interval-elapsed)
return
def renderLoop():
global Screen
pro_tick()
pro_draw()
Screen.render()
return
################
## Library Functions
def clearScreen():
printr('\033[2J\r')
def clearBuffer(buffer=TermScreen.buffers[0]):
global Screen
Screen.reset_buffer(buffer)
return
def clearAllBuffers():
global Screen
for buf in Screen.buffers:
Screen.reset_buffer(buf)
return
def clearLine(y, buffer=TermScreen.buffers[0]):
global Screen
Screen.reset_buffer_line(y, buffer)
return
def putBuffer(x, y, val, *, buffer=TermScreen.buffers[0]):
global Screen
Screen.put_buffer(x, y, val, buffer)
return
def printBuffer(x, y, val):
""" Print a string into the char buffer """
global Screen
string=str(val)
if len(string) > Screen.width-x:
raise RenderException("Too Long to fit in screen")
for i, char in enumerate(string):
Screen.buffer_char[y][x+i]=char
return
def drawBox(x,y,width,height,char):
""" Draw a box in the char buffer """
global Screen
if x+width > Screen.width or y+height > Screen.height:
raise RenderException("Box too BIG")
for w_x in range(width):
for w_y in range(height):
if (w_x==0 or w_x==width-1) or (w_y==0 or w_y==height-1):
Screen.buffer_char[y+w_y][x+w_x] = char
return
####################
def tick():
global Screen
Screen.frame_no+=1
def setup():
print("Default Setup")
clearScreen()
clearAllBuffers()
return
def teardown():
print("Default Teardown")
return
def draw():
return
def run():
global Screen
global pro_tick, pro_draw
if hasattr(__main__, "Screen"):
Screen = __main__.Screen
else:
raise RenderException("Screen Not defined")
if hasattr(__main__, "setup"):
pro_setup = __main__.setup
else:
pro_setup = setup
if hasattr(__main__, "teardown"):
pro_teardown = __main__.teardown
else:
pro_teardown = teardown
if hasattr(__main__, "tick"):
pro_tick = __main__.tick
else:
pro_tick = tick
if hasattr(__main__, "draw"):
pro_draw = __main__.draw
else:
pro_draw = draw
pro_setup()
try:
framerateMaker(renderLoop, Screen.framerate)
except KeyboardInterrupt:
pass
pro_teardown()