Skip to content

Commit

Permalink
update
Browse files Browse the repository at this point in the history
  • Loading branch information
Ovizro committed Nov 22, 2021
1 parent 3aa9898 commit 4c0067e
Show file tree
Hide file tree
Showing 3 changed files with 87 additions and 51 deletions.
39 changes: 30 additions & 9 deletions mcdp/command.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from .config import get_config
from .typings import McdpBaseModel, McdpVar, McdpError
from .mcstring import MCString
from .context import Context, comment, insert, ContextEnv, newline
from .context import Context, McdpContextError, comment, insert, ContextEnv, newline
from .exceptions import *


Expand Down Expand Up @@ -196,25 +196,28 @@ def __str__(self) -> str:

class ContextInstructionEnv(ContextEnv):

__slots__ = ["instruction"]
__slots__ = ["instruction", "decorate"]

def __init__(self, instruction: "Instruction") -> None:
def __init__(self, instruction: "Instruction", *, decorate: bool = True) -> None:
self.instruction = instruction
self.decorate = decorate
super().__init__(instruction.__class__.__name__)

def init(self) -> None:
super().init()
comment(f"{repr(self.instruction)} file.")
comment(f"{repr(self.instruction.__class__.__name__)} file.")
newline(2)

def decorate_command(self, cmd: str) -> str:
if not self.decorate:
return cmd
exec = Execute(self.instruction)
return exec.command_prefix() + cmd


class Instruction(McdpBaseModel):

__slots__ = ["stream"]
stream: Optional[Context] = None

def __init__(self) -> None:
raise NotImplementedError
Expand All @@ -231,19 +234,21 @@ def __exit__(self, exc_type, exc_ins, traceback) -> None:
Context.pop_env()

async def __aenter__(self) -> "Instruction":
env = ContextInstructionEnv(self)
env = ContextInstructionEnv(self, decorate=False)
self.stream = env.creat_stream()
await self.stream.__aenter__()
return self

async def __aexit__(self, exc_type, exc_ins, traceback) -> None:
if not self.stream:
raise McdpContextError("No context provide.")
await self.stream.__aexit__(exc_type, exc_ins, traceback)

def __str__(self) -> str:
raise NotImplementedError

def __repr__(self) -> str:
return f"Instruction({self})"
return f"{self.__class__.__name__}({self})"


class AlignInstruction(Instruction):
Expand Down Expand Up @@ -696,6 +701,22 @@ def __str__(self) -> str:
def case(type: str, *args, **kwds) -> _Case:
return _case_register[type](*args, **kwds)


class ContextLibEnv(ContextEnv):

__slots__ = ["func"]

def __init__(self, func: Callable[[], Optional[Coroutine]]) -> None:
self.func = func
super().__init__("Library")

def init(self) -> None:
comment(
f"Library function {self.func.__name__} of Mcdp.",
)
newline()


class Function(McdpVar):
"""
This class is only used to create library.
Expand All @@ -716,15 +737,15 @@ def __call__(self, namespace: Optional[str] = None) -> None:
namespace = namespace or get_config().namespace

name = self.func.__name__
if not self.space:
if not self.space or self.space == '.':
insert(f"function {namespace}:{name}")
else:
insert(f"function {namespace}:{self.space}/{name}")

async def apply(self) -> None:
if self.space:
Context.enter_space(self.space)
async with Context(self.func.__name__):
async with Context(self.func.__name__, envs=[ContextLibEnv(self.func)]):
if iscoroutinefunction(self.func):
await self.func()
else:
Expand Down
14 changes: 7 additions & 7 deletions mcdp/context.py
Original file line number Diff line number Diff line change
Expand Up @@ -120,8 +120,8 @@ class ContextMeta(type):

stack: StackCache
environments: list
enter: EnvMethod
leave: EnvMethod
enter: staticmethod
leave: staticmethod

def init(self, path: T_Path) -> None:
self.path = Path(path, "functions").resolve()
Expand All @@ -137,16 +137,16 @@ async def __aenter__(self) -> "ContextMeta":
"""
Init the datapack.
"""
default_env = self("__init__", root_path=self.path)
default_env = self("__init__", root_path=self.path, envs=ContextEnv("__init__"))
await self.stack.append(default_env)
comment(
"This is the initize function."
)
comment("This is the initize function.")
newline(2)

self.enter()
insert("tag @e[tag=Mcdp_stack] add Mcdp_home")
TagManager("functions", namespace="minecraft")
TagManager("functions", namespace=get_namespace())
insert(f"function {get_namespace()}:__init_score__")
self.enter()
return self

async def __aexit__(self, exc_type, exc_ins, traceback) -> None:
Expand Down
85 changes: 50 additions & 35 deletions mcdp/mcfunc.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import time
import warnings
from asyncio import iscoroutinefunction, run
from inspect import signature, Parameter
Expand All @@ -8,8 +9,8 @@
from .file_struct import build_dirs_from_config
from .typings import McdpVar, Variable
from .config import get_config, MCFuncConfig
from .context import Context, TagManager, add_tag, insert, comment, newline, leave_stack_ops, enter_stack_ops
from .command import Function, Selector, lib_func
from .context import Context, ContextEnv, TagManager, add_tag, insert, comment, newline, leave_stack_ops, enter_stack_ops
from .command import AsInstruction, Function, Selector, lib_func
from .entities import McdpStack, get_tag
from .variable import Score, Scoreboard, dp_int, dp_score, global_var, init_global
from .exceptions import *
Expand Down Expand Up @@ -37,13 +38,25 @@ def _get_arguments(name: str, param: Mapping[str, Parameter]) -> Tuple[list, dic
return args, kwds


def add_comment(func: Callable) -> None:
sig = signature(func)
comment(f"Function '{func.__name__}'", f"\nSignature:\n{sig}")
if func.__doc__:
comment("\nDoc:", func.__doc__)
newline(2)
class ContextFunctionEnv(ContextEnv):

__slots__ = ["func"]

def __init__(self, func: Callable) -> None:
self.func = func
super().__init__("mcfunction")

def init(self) -> None:
sig = signature(self.func)

comment(f"Function '{self.func.__name__}'")
newline()
comment(f"Signature:\n{sig}")
if self.func.__doc__:
newline()
comment("Doc:", self.func.__doc__)
newline(2)


class MCFunction(Function):

Expand All @@ -64,7 +77,7 @@ def __init__(self, name: str, *, namespace: Optional[str] = None, config: MCFunc
self.__name__ = name
self.namespace = namespace
self.config = config
self.overload: List = []
self.overload: List[Callable] = []
self.overload_counter: List[Counter] = []
self.__class__.collection[name] = self

Expand All @@ -84,6 +97,8 @@ def register(self, func: Callable) -> None:
if not func.__name__ == self.__name__:
warnings.warn(
f"unsuit function name. Maybe you are deliberate?", RuntimeWarning)
if self.overload:
func.__name__ += str(len(self.overload))
self.overload.append(func)

if len(self.overload) > 1 and not self.config.allow_overload:
Expand All @@ -98,25 +113,19 @@ async def apply(self) -> None:
f = self.overload[i]

if not (len(self.overload) == 1 or self.overload_counter[i]):
print(Context.get_relative_path())
continue

if i == 0:
name = self.__name__
else:
name = self.__name__ + str(i)

async with Context(name):
async with Context(f.__name__, envs=ContextFunctionEnv(f)):
for t in self.config.tag:
add_tag(t)

if get_config().pydp.add_comments:
add_comment(f)

sig = signature(f).parameters
args, kwds = _get_arguments(self.__name__, sig)

ans = f(*args, **kwds)
if iscoroutinefunction(f):
ans = await f(*args, **kwds)
else:
ans = f(*args, **kwds)
if isinstance(ans, Score):
if ans.name != "dpc_return":
dp_score("dpc_return", ans, stack_id=-2,
Expand All @@ -141,7 +150,6 @@ def __call__(self, *args: Any, **kwds: Any) -> Any:
except:
continue
else:
ind = i
+self.overload_counter[i]
break
else:
Expand All @@ -152,15 +160,12 @@ def __call__(self, *args: Any, **kwds: Any) -> Any:
dp_score("mcfarg_{0}_{1}".format(self.__name__, k), v,
display={"text": f"Mcdp function {self.__name__} arguments", "color": "dark_blue"})

path = Context.get_relative_path() / self.__name__
Context.enter()
self.namespace = self.namespace or get_config().namespace
file = f"{self.namespace}:{path}"
if ind != 0:
insert(f"execute as @e[tag=stack_top] run function {file}{ind}")
else:
insert(f"execute as @e[tag=stack_top] run function {file}")
self.space = str(Context.get_relative_path())
self.func = self.overload[i]

Context.enter()
with AsInstruction(Selector("@e", "tag=stack_top", tag=get_tag())):
super().__call__()
T_ret = sig.return_annotation
if not T_ret is None:
return dp_score("dpc_return", init=False, simulation=T_ret,
Expand Down Expand Up @@ -199,25 +204,38 @@ def mcfunc_main(*flags: str, **kw: Any) -> Callable[[Callable], None]:
def mcfunc_main(func: Optional[Union[Callable, str]] = None, *flags, **kw):
async def mf_main(func: Callable[[], Any], cfg: MCFuncConfig) -> None:
#config = get_config()
start = time.process_time_ns()
await build_dirs_from_config()
async with Context:
add_tag("minecraft:load")
init_global()

async with Context("__main__"):
async with Context("__main__", envs=ContextEnv("__main__")):
comment("This is the main function of the datapack.")
newline(2)

for t in cfg.tag:
add_tag(t)
Context.enter()
if iscoroutinefunction(func):
await func()
else:
func()
Context.leave()

async with Context('__init_score__', envs=ContextEnv("__init_score__")):
comment("Init the scoreborad.")
newline(2)

async with Context('__init_score__'):
Scoreboard.apply_all()

await MCFunction.apply_all()
await TagManager.apply_all()


end = time.process_time_ns()
process = end - start
process *= 1e-8
print(f"Complite completed in {process} ms")
get_counter().print_out()

cfg = MCFuncConfig(**kw)
Expand Down Expand Up @@ -275,9 +293,6 @@ def enter_stack() -> None:
top.remove_tag("stack_top")

stack = McdpStack()

with mcdp_stack_id == 0:
stack.add_tag("Mcdp_home")
mcdp_stack_id += 1


Expand Down

0 comments on commit 4c0067e

Please sign in to comment.