turnq 0.0.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- turnq-0.0.1/LICENSE +24 -0
- turnq-0.0.1/PKG-INFO +20 -0
- turnq-0.0.1/README.md +3 -0
- turnq-0.0.1/pyproject.toml +62 -0
- turnq-0.0.1/turnq/__init__.py +122 -0
- turnq-0.0.1/turnq/_version.py +34 -0
- turnq-0.0.1/turnq/py.typed +0 -0
turnq-0.0.1/LICENSE
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
This is free and unencumbered software released into the public domain.
|
|
2
|
+
|
|
3
|
+
Anyone is free to copy, modify, publish, use, compile, sell, or
|
|
4
|
+
distribute this software, either in source code form or as a compiled
|
|
5
|
+
binary, for any purpose, commercial or non-commercial, and by any
|
|
6
|
+
means.
|
|
7
|
+
|
|
8
|
+
In jurisdictions that recognize copyright laws, the author or authors
|
|
9
|
+
of this software dedicate any and all copyright interest in the
|
|
10
|
+
software to the public domain. We make this dedication for the benefit
|
|
11
|
+
of the public at large and to the detriment of our heirs and
|
|
12
|
+
successors. We intend this dedication to be an overt act of
|
|
13
|
+
relinquishment in perpetuity of all present and future rights to this
|
|
14
|
+
software under copyright law.
|
|
15
|
+
|
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
|
19
|
+
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
|
20
|
+
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
|
21
|
+
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
|
22
|
+
OTHER DEALINGS IN THE SOFTWARE.
|
|
23
|
+
|
|
24
|
+
For more information, please refer to <http://unlicense.org/>
|
turnq-0.0.1/PKG-INFO
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: turnq
|
|
3
|
+
Version: 0.0.1
|
|
4
|
+
Summary: A priority queue scheduler for use in game development.
|
|
5
|
+
Requires-Python: >=3.8
|
|
6
|
+
Description-Content-Type: text/markdown
|
|
7
|
+
License-Expression: Unlicense
|
|
8
|
+
Classifier: Development Status :: 3 - Alpha
|
|
9
|
+
Classifier: Intended Audience :: Developers
|
|
10
|
+
Classifier: Programming Language :: Python :: 3
|
|
11
|
+
Classifier: Typing :: Typed
|
|
12
|
+
License-File: LICENSE
|
|
13
|
+
Project-URL: Changelog, https://github.com/HexDecimal/tqueue/blob/main/CHANGELOG.md
|
|
14
|
+
Project-URL: Issues, https://github.com/HexDecimal/tqueue/issues
|
|
15
|
+
Project-URL: Repository, https://github.com/HexDecimal/tqueue
|
|
16
|
+
|
|
17
|
+
# turnq
|
|
18
|
+
|
|
19
|
+
A turn-based scheduler build on top of heapq.
|
|
20
|
+
|
turnq-0.0.1/README.md
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["flit_scm"]
|
|
3
|
+
build-backend = "flit_scm:buildapi"
|
|
4
|
+
|
|
5
|
+
[project] # https://packaging.python.org/en/latest/guides/writing-pyproject-toml/
|
|
6
|
+
name = "turnq"
|
|
7
|
+
readme = "README.md"
|
|
8
|
+
license = "Unlicense"
|
|
9
|
+
dynamic = ["version", "description"]
|
|
10
|
+
requires-python = ">=3.8"
|
|
11
|
+
classifiers = [ # https://pypi.org/classifiers/
|
|
12
|
+
"Development Status :: 3 - Alpha",
|
|
13
|
+
"Intended Audience :: Developers",
|
|
14
|
+
"Programming Language :: Python :: 3",
|
|
15
|
+
"Typing :: Typed",
|
|
16
|
+
]
|
|
17
|
+
|
|
18
|
+
[project.urls] # https://packaging.python.org/en/latest/guides/writing-pyproject-toml/#urls
|
|
19
|
+
Repository = "https://github.com/HexDecimal/tqueue"
|
|
20
|
+
Issues = "https://github.com/HexDecimal/tqueue/issues"
|
|
21
|
+
Changelog = "https://github.com/HexDecimal/tqueue/blob/main/CHANGELOG.md"
|
|
22
|
+
|
|
23
|
+
[tool.setuptools_scm]
|
|
24
|
+
write_to = "turnq/_version.py"
|
|
25
|
+
|
|
26
|
+
[tool.coverage.report] # https://coverage.readthedocs.io/en/latest/config.html
|
|
27
|
+
exclude_lines = ['^\s*\.\.\.', "if TYPE_CHECKING:", "# pragma: no cover"]
|
|
28
|
+
omit = ["_version.py"]
|
|
29
|
+
|
|
30
|
+
[tool.mypy] # https://mypy.readthedocs.io/en/stable/config_file.html
|
|
31
|
+
files = "."
|
|
32
|
+
exclude = ['^build/', '^\.']
|
|
33
|
+
explicit_package_bases = true
|
|
34
|
+
python_version = "3.8"
|
|
35
|
+
warn_unused_configs = true
|
|
36
|
+
disallow_any_generics = true
|
|
37
|
+
disallow_subclassing_any = true
|
|
38
|
+
disallow_untyped_calls = true
|
|
39
|
+
disallow_untyped_defs = true
|
|
40
|
+
disallow_incomplete_defs = true
|
|
41
|
+
check_untyped_defs = true
|
|
42
|
+
disallow_untyped_decorators = true
|
|
43
|
+
no_implicit_optional = true
|
|
44
|
+
warn_redundant_casts = true
|
|
45
|
+
warn_unused_ignores = true
|
|
46
|
+
warn_return_any = true
|
|
47
|
+
no_implicit_reexport = true
|
|
48
|
+
strict_equality = true
|
|
49
|
+
|
|
50
|
+
[tool.ruff]
|
|
51
|
+
line-length = 120
|
|
52
|
+
|
|
53
|
+
[tool.ruff.lint] # https://docs.astral.sh/ruff/rules/
|
|
54
|
+
select = ["ALL"]
|
|
55
|
+
ignore = [
|
|
56
|
+
"COM", # flake8-commas
|
|
57
|
+
"E501", # line-too-long
|
|
58
|
+
"S101", # assert
|
|
59
|
+
]
|
|
60
|
+
|
|
61
|
+
[tool.ruff.lint.pydocstyle]
|
|
62
|
+
convention = "google" # Use Google-style docstrings
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
# This is free and unencumbered software released into the public domain.
|
|
2
|
+
#
|
|
3
|
+
# Anyone is free to copy, modify, publish, use, compile, sell, or
|
|
4
|
+
# distribute this software, either in source code form or as a compiled
|
|
5
|
+
# binary, for any purpose, commercial or non-commercial, and by any
|
|
6
|
+
# means.
|
|
7
|
+
#
|
|
8
|
+
# In jurisdictions that recognize copyright laws, the author or authors
|
|
9
|
+
# of this software dedicate any and all copyright interest in the
|
|
10
|
+
# software to the public domain. We make this dedication for the benefit
|
|
11
|
+
# of the public at large and to the detriment of our heirs and
|
|
12
|
+
# successors. We intend this dedication to be an overt act of
|
|
13
|
+
# relinquishment in perpetuity of all present and future rights to this
|
|
14
|
+
# software under copyright law.
|
|
15
|
+
#
|
|
16
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
17
|
+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
18
|
+
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
|
19
|
+
# IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
|
20
|
+
# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
|
21
|
+
# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
|
22
|
+
# OTHER DEALINGS IN THE SOFTWARE.
|
|
23
|
+
#
|
|
24
|
+
# For more information, please refer to <http://unlicense.org/>
|
|
25
|
+
"""A priority queue scheduler for use in game development.
|
|
26
|
+
|
|
27
|
+
See the queued turns time system:
|
|
28
|
+
http://www.roguebasin.com/index.php?title=Time_Systems#Queued_turns
|
|
29
|
+
"""
|
|
30
|
+
|
|
31
|
+
from __future__ import annotations
|
|
32
|
+
|
|
33
|
+
__all__ = (
|
|
34
|
+
"Ticket",
|
|
35
|
+
"TurnQueue",
|
|
36
|
+
)
|
|
37
|
+
|
|
38
|
+
import dataclasses
|
|
39
|
+
import heapq
|
|
40
|
+
from typing import Generic, NamedTuple, TypeVar
|
|
41
|
+
|
|
42
|
+
try:
|
|
43
|
+
from ._version import __version__
|
|
44
|
+
except ImportError: # pragma: no cover
|
|
45
|
+
__version__ = ""
|
|
46
|
+
|
|
47
|
+
T = TypeVar("T")
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
class Ticket(NamedTuple, Generic[T]):
|
|
51
|
+
"""Describes a scheduled object."""
|
|
52
|
+
|
|
53
|
+
time: int
|
|
54
|
+
"""The time this Ticket will be returned from the scheduler."""
|
|
55
|
+
uid: int
|
|
56
|
+
"""A unique number which enforces FIFO ordering of tickets with the same `time`."""
|
|
57
|
+
value: T
|
|
58
|
+
"""The scheduled object."""
|
|
59
|
+
insert_time: int
|
|
60
|
+
"""The time this ticket was inserted into the scheduler.
|
|
61
|
+
|
|
62
|
+
This can be used to get the delta time of this Ticket with
|
|
63
|
+
`time - insert_time` or some equivalent.
|
|
64
|
+
"""
|
|
65
|
+
|
|
66
|
+
def get_time_passed(self, current_time: int) -> int:
|
|
67
|
+
"""Return the amount of time passed since this Ticket was initially scheduled."""
|
|
68
|
+
return current_time - self.insert_time
|
|
69
|
+
|
|
70
|
+
def get_time_left(self, current_time: int) -> int:
|
|
71
|
+
"""Return the amount of time until this Ticket is triggered."""
|
|
72
|
+
return self.time - current_time
|
|
73
|
+
|
|
74
|
+
def get_progress(self, current_time: int) -> float:
|
|
75
|
+
"""Return the current progress of this Ticket as a float from 0 to 1."""
|
|
76
|
+
return self.get_time_passed(current_time) / (self.time - self.insert_time)
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
@dataclasses.dataclass(eq=False)
|
|
80
|
+
class TurnQueue(Generic[T]):
|
|
81
|
+
"""Turned queue manager."""
|
|
82
|
+
|
|
83
|
+
time: int = 0
|
|
84
|
+
"""The current tick. Always the time of the most recently popped ticket."""
|
|
85
|
+
next_uid: int = 0
|
|
86
|
+
"""Incrementing unique id used to enforce FIFO order on tickets."""
|
|
87
|
+
heap: list[Ticket[T]] = dataclasses.field(default_factory=list)
|
|
88
|
+
"""A min-heap queue of events maintained by Python's `heapq` module."""
|
|
89
|
+
|
|
90
|
+
def __post_init__(self) -> None:
|
|
91
|
+
"""Ensure heap is sorted."""
|
|
92
|
+
heapq.heapify(self.heap)
|
|
93
|
+
|
|
94
|
+
def __bool__(self) -> bool:
|
|
95
|
+
"""Return True if a scheduled object exists in this scheduler."""
|
|
96
|
+
return bool(self.heap)
|
|
97
|
+
|
|
98
|
+
def peek(self) -> Ticket[T]:
|
|
99
|
+
"""Return the next scheduled ticket without removing it.
|
|
100
|
+
|
|
101
|
+
IndexError will be raised if the heap is empty.
|
|
102
|
+
"""
|
|
103
|
+
return self.heap[0]
|
|
104
|
+
|
|
105
|
+
def schedule(self, interval: int, value: T) -> Ticket[T]:
|
|
106
|
+
"""Schedule `value` to be returned after `internal` time passes.
|
|
107
|
+
|
|
108
|
+
Returns the new Ticket associated with the scheduled `value`.
|
|
109
|
+
"""
|
|
110
|
+
ticket = Ticket(self.time + interval, self.next_uid, value, self.time)
|
|
111
|
+
self.next_uid += 1
|
|
112
|
+
heapq.heappush(self.heap, ticket)
|
|
113
|
+
return ticket
|
|
114
|
+
|
|
115
|
+
def pop(self) -> Ticket[T]:
|
|
116
|
+
"""Pop and return the next scheduled Ticket from the queue.
|
|
117
|
+
|
|
118
|
+
This will set `TurnQueue.time` to the tickets current time.
|
|
119
|
+
"""
|
|
120
|
+
ticket = heapq.heappop(self.heap)
|
|
121
|
+
self.time = ticket.time
|
|
122
|
+
return ticket
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# file generated by setuptools-scm
|
|
2
|
+
# don't change, don't track in version control
|
|
3
|
+
|
|
4
|
+
__all__ = [
|
|
5
|
+
"__version__",
|
|
6
|
+
"__version_tuple__",
|
|
7
|
+
"version",
|
|
8
|
+
"version_tuple",
|
|
9
|
+
"__commit_id__",
|
|
10
|
+
"commit_id",
|
|
11
|
+
]
|
|
12
|
+
|
|
13
|
+
TYPE_CHECKING = False
|
|
14
|
+
if TYPE_CHECKING:
|
|
15
|
+
from typing import Tuple
|
|
16
|
+
from typing import Union
|
|
17
|
+
|
|
18
|
+
VERSION_TUPLE = Tuple[Union[int, str], ...]
|
|
19
|
+
COMMIT_ID = Union[str, None]
|
|
20
|
+
else:
|
|
21
|
+
VERSION_TUPLE = object
|
|
22
|
+
COMMIT_ID = object
|
|
23
|
+
|
|
24
|
+
version: str
|
|
25
|
+
__version__: str
|
|
26
|
+
__version_tuple__: VERSION_TUPLE
|
|
27
|
+
version_tuple: VERSION_TUPLE
|
|
28
|
+
commit_id: COMMIT_ID
|
|
29
|
+
__commit_id__: COMMIT_ID
|
|
30
|
+
|
|
31
|
+
__version__ = version = '0.0.1'
|
|
32
|
+
__version_tuple__ = version_tuple = (0, 0, 1)
|
|
33
|
+
|
|
34
|
+
__commit_id__ = commit_id = 'g534fb0315'
|
|
File without changes
|