Skip to content

Commit 480b840

Browse files
committed
Moved some functions from modgame to modast
1 parent 473fcab commit 480b840

File tree

2 files changed

+175
-181
lines changed

2 files changed

+175
-181
lines changed

modloader/modast.py

Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -366,3 +366,162 @@ def call_func(hook):
366366
hook.chain(rv)
367367

368368
hook.hook_func = call_func
369+
370+
371+
def hook_opcode(node, func):
372+
"""Hook ``func`` to ``node``
373+
374+
Args:
375+
node (Node): The node object for the function to hook
376+
func (function): The function to be executed when the node is executed
377+
378+
Todo:
379+
Check if a hook already exists and make the code more cohesive
380+
381+
Returns:
382+
An :class:`ASTHook` object
383+
"""
384+
# Keep a copy of the node's original next node
385+
next_statement = node.next
386+
387+
# Make a new ASTHook and hook it to the node
388+
# The tuple is in the format (filename, filenumber)
389+
# This is used by the renpy stacktrace
390+
hook = ASTHook(("AWSWMod", 1), func, node)
391+
node.next = hook
392+
393+
# Put the original next node to the hook node
394+
# Also keep a copy of the original next node in the hook node, allowing us to unhook it
395+
hook.chain(next_statement)
396+
hook.old_next = next_statement
397+
398+
return hook
399+
400+
401+
def call_hook(node, dest_node, func=None):
402+
"""Hook ``func`` to ``node`` and once executed, redirect execution to
403+
``dest_node``
404+
405+
Args:
406+
node (Node): The node to hook
407+
dest_node (Node): the node to go after ``node`` is executed
408+
func (function): The function to call
409+
410+
Returns:
411+
An :class:`ASTHook` object
412+
"""
413+
hook = hook_opcode(node, None)
414+
415+
def call_function(hook):
416+
if func:
417+
func(hook)
418+
419+
#TODO: Better understand this line
420+
label = renpy.game.context().call(dest_node.name, return_site=hook.old_next.name)
421+
hook.chain(label)
422+
423+
hook.hook_func = call_function
424+
return hook
425+
426+
427+
def unhook_label(label):
428+
"""Unhook a hook from a lbel
429+
430+
Args:
431+
label (str): The label's name
432+
"""
433+
#TODO: Test this
434+
found_node = find_label(label)
435+
if isinstance(found_node, ASTHook):
436+
found_node.from_op.next = found_node.next
437+
438+
439+
def disable_slast_cache():
440+
"""Disable SLAst's load cache"""
441+
renpy.sl2.slast.load_cache = lambda *_: None
442+
443+
444+
def disable_bytecode_cache():
445+
"""Disable bytecode cache"""
446+
renpy.game.script.init_bytecode = lambda *_: None
447+
448+
449+
def get_node_after_nodes(node, location):
450+
"""Get the ``location``th node after ``node``
451+
452+
Note:
453+
This skips :class:`ASTHook` nodes
454+
455+
Args:
456+
node (Node): The starting search node
457+
location (int): The number of nodes to skip
458+
459+
Returns:
460+
A :class:`renpy.ast.Node` object
461+
"""
462+
for _ in range(0, location):
463+
node = node.next
464+
465+
# Effectively skip the ASTHook nodes by continuing on
466+
while node and isinstance(node, ASTHook):
467+
node = node.next
468+
return node
469+
470+
471+
def get_renpy_global(key):
472+
"""Get a Ren'Py global
473+
474+
Args:
475+
key (str): The dictionary key
476+
477+
Returns:
478+
The value put into the key or None if it doesn't exist
479+
"""
480+
store = renpy.python.store_dicts["store"]
481+
if key in store:
482+
return store[key]
483+
484+
485+
def set_renpy_global(key, val):
486+
"""Set a Ren'Py glboal
487+
488+
Ren'Py globals can be used during execution of rpy.
489+
490+
Args:
491+
key (str): The dictionary key
492+
val (str): The value of the dictionary object
493+
"""
494+
renpy.python.store_dicts["store"][key] = val
495+
496+
497+
def jump_ret(node, dest_node, return_node, func=None):
498+
"""Hook ``func`` to ``node`` and once executed, redirect execution to
499+
``dest_node`` and allow ``return_node`` to be executed after
500+
``dest_node`` returns
501+
502+
Args:
503+
node (Node): The node to hook
504+
dest_node (Node): The node to go after ``node`` is executed
505+
return_node (Node): The node that is executed after ``dest_node`` returns
506+
func (function): The function hook
507+
508+
Returns:
509+
An :class:`ASTHook` object
510+
"""
511+
hook = call_hook(node, dest_node, func)
512+
hook.next = return_node
513+
return hook
514+
515+
516+
def hook_label(label, func):
517+
"""Hook a function to a label
518+
519+
Args:
520+
label (renpy.ast.Label): The label
521+
func (function): The function to be hooked
522+
523+
Returns:
524+
An :class:`ASTHook` object
525+
"""
526+
node_label = find_label(label)
527+
return hook_opcode(node_label, func)

0 commit comments

Comments
 (0)