|
1
|
|
|
import sys |
|
2
|
|
|
import argparse |
|
3
|
|
|
import time |
|
4
|
|
|
from os import path, getcwd |
|
5
|
|
|
|
|
6
|
|
|
from importlib import util as import_util |
|
7
|
|
|
|
|
8
|
|
|
from pypen.settings import settings |
|
9
|
|
|
import pygame |
|
10
|
|
|
|
|
11
|
|
|
_argument_parser = argparse.ArgumentParser() |
|
12
|
|
|
|
|
13
|
|
|
def space_print(msg=""): |
|
14
|
|
|
print() |
|
15
|
|
|
print(msg) |
|
16
|
|
|
print() |
|
17
|
|
|
|
|
18
|
|
|
def print_help(msg=""): |
|
19
|
|
|
if msg: |
|
20
|
|
|
space_print(msg) |
|
21
|
|
|
|
|
22
|
|
|
_argument_parser.print_help(sys.stderr) |
|
23
|
|
|
sys.exit(0) |
|
24
|
|
|
|
|
25
|
|
|
def cli(): |
|
26
|
|
|
global _argument_parser |
|
27
|
|
|
try: |
|
28
|
|
|
_argument_parser = argparse.ArgumentParser(description="The PyPen CLI for managing PyPen Sketches", prog="pypen") |
|
29
|
|
|
_argument_parser.add_argument( |
|
30
|
|
|
"-i", |
|
31
|
|
|
"--init", |
|
32
|
|
|
action="store_true", |
|
33
|
|
|
help="Flag to create a new PyPen sketch which imports pypen and contains default functions.") |
|
34
|
|
|
|
|
35
|
|
|
_argument_parser.add_argument("filename", nargs="?", help="The name/path of your PyPen Sketch.", default="") |
|
36
|
|
|
_argument_parser.add_argument("-f", "--fullscreen", action="store_true") |
|
37
|
|
|
_argument_parser.add_argument("--timeout", help="Timeout in seconds. Window will close once done.", type=float, required=False, default=0.0) |
|
38
|
|
|
|
|
39
|
|
|
arguments = _argument_parser.parse_args() |
|
40
|
|
|
|
|
41
|
|
|
if len(sys.argv) == 1: |
|
42
|
|
|
print_help("It seems like you are running the pypen command without any arguments.\nHere is some help:") |
|
43
|
|
|
|
|
44
|
|
|
if not arguments.init and not arguments.filename: |
|
45
|
|
|
print_help("PyPen needs a path to a sketch in order to run it!\nPlease provide a path with 'pypen <path_to_sketch>'\nor run 'pypen --init <path_to_new_sketch>' to create a new one!") |
|
46
|
|
|
|
|
47
|
|
|
if arguments.init: |
|
48
|
|
|
path_to_new_sketch = arguments.filename if arguments.filename else settings.default_pypen_name |
|
49
|
|
|
init(path_to_new_sketch) |
|
50
|
|
|
|
|
51
|
|
|
main(arguments) |
|
52
|
|
|
except argparse.ArgumentError as error: |
|
53
|
|
|
print(str(error)) |
|
54
|
|
|
sys.exit(1) |
|
55
|
|
|
|
|
56
|
|
|
|
|
57
|
|
|
def init(path_to_new_file): |
|
58
|
|
|
if path.splitext(path_to_new_file)[1] != ".py": |
|
59
|
|
|
path_to_new_file += ".py" |
|
60
|
|
|
|
|
61
|
|
|
pypen_path = path.join(getcwd(), path_to_new_file) |
|
62
|
|
|
template = "" |
|
63
|
|
|
|
|
64
|
|
|
try: |
|
65
|
|
|
with open(path.join(path.realpath(__file__), "..", "pypen_template.py"), "r") as template_file: |
|
66
|
|
|
template = template_file.read() |
|
67
|
|
|
except EnvironmentError: |
|
68
|
|
|
# In case PyPen is installed in a directory that doesn't have read access, |
|
69
|
|
|
# it uses the below template instead of reading the template file |
|
70
|
|
|
template = """from pypen import * |
|
71
|
|
|
|
|
72
|
|
|
|
|
73
|
|
|
def start(): |
|
74
|
|
|
settings.fps = 60 |
|
75
|
|
|
|
|
76
|
|
|
|
|
77
|
|
|
def update(): |
|
78
|
|
|
clear() |
|
79
|
|
|
rectangle(20, 20, 300, 400, "red") |
|
80
|
|
|
""" |
|
81
|
|
|
|
|
82
|
|
|
try: |
|
83
|
|
|
with open(pypen_path, "w") as new_file: |
|
84
|
|
|
new_file.writelines(template) |
|
85
|
|
|
except EnvironmentError: |
|
86
|
|
|
space_print("Could not create file {}\nDo you have the right permissions?".format(pypen_path)) |
|
87
|
|
|
sys.exit(1) |
|
88
|
|
|
|
|
89
|
|
|
space_print("'{0}' has been created!\nRun it using 'pypen {0}'".format(path_to_new_file)) |
|
90
|
|
|
sys.exit(0) |
|
91
|
|
|
|
|
92
|
|
|
|
|
93
|
|
|
def main(arguments): |
|
94
|
|
|
if not arguments.init: |
|
95
|
|
|
try: |
|
96
|
|
|
file_path = path.join(getcwd(), arguments.filename) |
|
97
|
|
|
spec = import_util.spec_from_file_location("", file_path) |
|
98
|
|
|
user_sketch = import_util.module_from_spec(spec) |
|
99
|
|
|
spec.loader.exec_module(user_sketch) |
|
100
|
|
|
except FileNotFoundError: |
|
101
|
|
|
print() |
|
102
|
|
|
print(f"Hmm, PyPen can't find '{arguments.filename}'.") |
|
103
|
|
|
print("Are you sure that's the right path?") |
|
104
|
|
|
print() |
|
105
|
|
|
sys.exit(1) |
|
106
|
|
|
|
|
107
|
|
|
try: |
|
108
|
|
|
user_sketch.TIME |
|
|
|
|
|
|
109
|
|
|
user_sketch.T |
|
110
|
|
|
user_sketch.rectangle |
|
111
|
|
|
user_sketch.PI |
|
112
|
|
|
except AttributeError: |
|
113
|
|
|
print() |
|
114
|
|
|
print(f"It seems like you're not importing PyPen to your sketch '{arguments.filename}'") |
|
115
|
|
|
print("Import it by writing 'from pypen import *' at the very top!") |
|
116
|
|
|
print() |
|
117
|
|
|
sys.exit(1) |
|
118
|
|
|
|
|
119
|
|
|
try: |
|
120
|
|
|
user_sketch.start |
|
121
|
|
|
except AttributeError: |
|
122
|
|
|
settings._user_has_start = False |
|
123
|
|
|
|
|
124
|
|
|
try: |
|
125
|
|
|
user_sketch.update |
|
126
|
|
|
except AttributeError: |
|
127
|
|
|
settings._user_has_update = False |
|
128
|
|
|
|
|
129
|
|
|
if not settings._user_has_start and not settings._user_has_update: |
|
130
|
|
|
print() |
|
131
|
|
|
print( |
|
132
|
|
|
f"Your PyPen sketch '{arguments.filename}' appears to have neither a start() nor an update() function.") |
|
133
|
|
|
print("Try to add at least one of those and run again!") |
|
134
|
|
|
print() |
|
135
|
|
|
sys.exit(1) |
|
136
|
|
|
|
|
137
|
|
|
def start(): |
|
138
|
|
|
user_sketch.start() |
|
|
|
|
|
|
139
|
|
|
if settings._user_has_update: |
|
140
|
|
|
update() |
|
141
|
|
|
|
|
142
|
|
|
def update(passed_time=0, delta_time=0, frame_count=0): |
|
143
|
|
|
if not settings._user_has_update: |
|
144
|
|
|
return |
|
145
|
|
|
user_sketch.TIME = user_sketch.T = passed_time |
|
|
|
|
|
|
146
|
|
|
user_sketch.DELTA_TIME = user_sketch.DT = delta_time |
|
147
|
|
|
user_sketch.FRAME = user_sketch.F = frame_count |
|
148
|
|
|
|
|
149
|
|
|
user_sketch.update() |
|
150
|
|
|
|
|
151
|
|
|
pygame.init() |
|
152
|
|
|
pygame.display.set_caption(f"PyPen | {arguments.filename}") |
|
153
|
|
|
|
|
154
|
|
|
pygame.display.set_mode((settings.width, settings.height), pygame.SRCALPHA) |
|
155
|
|
|
|
|
156
|
|
|
if settings._user_has_start: |
|
157
|
|
|
initial_settings = settings |
|
158
|
|
|
start() |
|
159
|
|
|
|
|
160
|
|
|
if settings.width != initial_settings.width or settings.height != initial_settings.height: |
|
161
|
|
|
pygame.display.set_mode((settings.width, settings.height), pygame.SRCALPHA) |
|
162
|
|
|
|
|
163
|
|
|
pygame.display.flip() |
|
164
|
|
|
clock = pygame.time.Clock() |
|
165
|
|
|
|
|
166
|
|
|
is_running = True |
|
167
|
|
|
passed_time = frame_count = 0 |
|
168
|
|
|
|
|
169
|
|
|
while is_running: |
|
170
|
|
|
# Handle events |
|
171
|
|
|
for event in pygame.event.get(): |
|
172
|
|
|
if event.type == pygame.QUIT: |
|
173
|
|
|
is_running = False |
|
174
|
|
|
|
|
175
|
|
|
if event.type == pygame.KEYDOWN: |
|
176
|
|
|
if event.key == pygame.K_ESCAPE: |
|
177
|
|
|
is_running = False |
|
178
|
|
|
|
|
179
|
|
|
delta_time = clock.tick(settings.fps if settings.fps > 0 else 1)/1000 |
|
180
|
|
|
passed_time += delta_time |
|
181
|
|
|
frame_count += 1 |
|
182
|
|
|
|
|
183
|
|
|
if arguments.timeout > 0: |
|
184
|
|
|
if passed_time > arguments.timeout: |
|
185
|
|
|
is_running = False |
|
186
|
|
|
|
|
187
|
|
|
if settings._user_has_update: |
|
188
|
|
|
update(passed_time, delta_time, frame_count) |
|
189
|
|
|
|
|
190
|
|
|
pygame.display.flip() |
|
191
|
|
|
|
|
192
|
|
|
|
|
193
|
|
|
if __name__ == "__main__": |
|
194
|
|
|
cli() |
|
195
|
|
|
|