Merge remote-tracking branch 'upstream/master'
This commit is contained in:
commit
c7ebf71634
|
|
@ -40,7 +40,7 @@ jobs:
|
|||
eigen: NO
|
||||
|
||||
- profile: macos-eigen-coverage-unity-xcode
|
||||
os: macOS-10.15
|
||||
os: macOS-11
|
||||
config: Coverage
|
||||
unity: YES
|
||||
generator: Xcode
|
||||
|
|
@ -50,7 +50,7 @@ jobs:
|
|||
eigen: YES
|
||||
|
||||
- profile: macos-nometa-standard-makefile
|
||||
os: macOS-10.15
|
||||
os: macOS-11
|
||||
config: Standard
|
||||
unity: NO
|
||||
generator: Unix Makefiles
|
||||
|
|
@ -87,7 +87,7 @@ jobs:
|
|||
fetch-depth: 10
|
||||
|
||||
- name: Self-destruct makepanda
|
||||
run: python makepanda/selfdestruct.py --yes
|
||||
run: python3 makepanda/selfdestruct.py --yes
|
||||
|
||||
- name: Install dependencies (macOS)
|
||||
if: runner.os == 'macOS'
|
||||
|
|
@ -113,7 +113,7 @@ jobs:
|
|||
libeigen3-dev libfreetype6-dev libgl1-mesa-dev libjpeg-dev libode-dev
|
||||
libopenal-dev libpng-dev libssl-dev libvorbis-dev libx11-dev
|
||||
libxcursor-dev libxrandr-dev nvidia-cg-toolkit zlib1g-dev
|
||||
python3-setuptools
|
||||
python3-setuptools python3-tk
|
||||
|
||||
- name: Cache dependencies (Windows)
|
||||
if: runner.os == 'Windows'
|
||||
|
|
@ -180,38 +180,6 @@ jobs:
|
|||
run: cmake --build . --config ${{ matrix.config }} --parallel 4
|
||||
# END A
|
||||
|
||||
- name: Setup Python (Python 3.7)
|
||||
if: contains(matrix.python, 'YES')
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: '3.7'
|
||||
- name: Configure (Python 3.7)
|
||||
if: contains(matrix.python, 'YES')
|
||||
working-directory: build
|
||||
shell: bash
|
||||
run: >
|
||||
cmake -DWANT_PYTHON_VERSION=3.7 -DHAVE_PYTHON=YES
|
||||
-DPython_FIND_REGISTRY=NEVER -DPython_ROOT="$pythonLocation" .
|
||||
- name: Build (Python 3.7)
|
||||
if: contains(matrix.python, 'YES')
|
||||
# BEGIN A
|
||||
working-directory: build
|
||||
run: cmake --build . --config ${{ matrix.config }} --parallel 4
|
||||
# END A
|
||||
- name: Test (Python 3.7)
|
||||
# BEGIN B
|
||||
if: contains(matrix.python, 'YES')
|
||||
working-directory: build
|
||||
shell: bash
|
||||
env:
|
||||
PYTHONPATH: ${{ matrix.config }}
|
||||
run: |
|
||||
PYTHON_EXECUTABLE=$(grep 'Python_EXECUTABLE:' CMakeCache.txt | sed 's/.*=//')
|
||||
$PYTHON_EXECUTABLE -m pip install pytest pytest-cov
|
||||
export COVERAGE_FILE=.coverage.$RANDOM LLVM_PROFILE_FILE=$PWD/pid-%p.profraw
|
||||
$PYTHON_EXECUTABLE -m pytest ../tests --cov=.
|
||||
# END B
|
||||
|
||||
- name: Setup Python (Python 3.8)
|
||||
if: contains(matrix.python, 'YES')
|
||||
uses: actions/setup-python@v4
|
||||
|
|
@ -239,7 +207,7 @@ jobs:
|
|||
PYTHONPATH: ${{ matrix.config }}
|
||||
run: |
|
||||
PYTHON_EXECUTABLE=$(grep 'Python_EXECUTABLE:' CMakeCache.txt | sed 's/.*=//')
|
||||
$PYTHON_EXECUTABLE -m pip install pytest pytest-cov
|
||||
$PYTHON_EXECUTABLE -m pip install -r ../requirements-test.txt
|
||||
export COVERAGE_FILE=.coverage.$RANDOM LLVM_PROFILE_FILE=$PWD/pid-%p.profraw
|
||||
$PYTHON_EXECUTABLE -m pytest ../tests --cov=.
|
||||
# END B
|
||||
|
|
@ -271,7 +239,7 @@ jobs:
|
|||
PYTHONPATH: ${{ matrix.config }}
|
||||
run: |
|
||||
PYTHON_EXECUTABLE=$(grep 'Python_EXECUTABLE:' CMakeCache.txt | sed 's/.*=//')
|
||||
$PYTHON_EXECUTABLE -m pip install pytest pytest-cov
|
||||
$PYTHON_EXECUTABLE -m pip install -r ../requirements-test.txt
|
||||
export COVERAGE_FILE=.coverage.$RANDOM LLVM_PROFILE_FILE=$PWD/pid-%p.profraw
|
||||
$PYTHON_EXECUTABLE -m pytest ../tests --cov=.
|
||||
# END B
|
||||
|
|
@ -303,7 +271,7 @@ jobs:
|
|||
PYTHONPATH: ${{ matrix.config }}
|
||||
run: |
|
||||
PYTHON_EXECUTABLE=$(grep 'Python_EXECUTABLE:' CMakeCache.txt | sed 's/.*=//')
|
||||
$PYTHON_EXECUTABLE -m pip install pytest pytest-cov
|
||||
$PYTHON_EXECUTABLE -m pip install -r ../requirements-test.txt
|
||||
export COVERAGE_FILE=.coverage.$RANDOM LLVM_PROFILE_FILE=$PWD/pid-%p.profraw
|
||||
$PYTHON_EXECUTABLE -m pytest ../tests --cov=.
|
||||
# END B
|
||||
|
|
@ -335,7 +303,7 @@ jobs:
|
|||
PYTHONPATH: ${{ matrix.config }}
|
||||
run: |
|
||||
PYTHON_EXECUTABLE=$(grep 'Python_EXECUTABLE:' CMakeCache.txt | sed 's/.*=//')
|
||||
$PYTHON_EXECUTABLE -m pip install pytest pytest-cov
|
||||
$PYTHON_EXECUTABLE -m pip install -r ../requirements-test.txt
|
||||
export COVERAGE_FILE=.coverage.$RANDOM LLVM_PROFILE_FILE=$PWD/pid-%p.profraw
|
||||
$PYTHON_EXECUTABLE -m pytest ../tests --cov=.
|
||||
# END B
|
||||
|
|
@ -398,7 +366,7 @@ jobs:
|
|||
- name: Test Python 3.11
|
||||
shell: bash
|
||||
run: |
|
||||
python -m pip install pytest
|
||||
python -m pip install -r requirements-test.txt
|
||||
PYTHONPATH=built LD_LIBRARY_PATH=built/lib DYLD_LIBRARY_PATH=built/lib python -m pytest
|
||||
|
||||
- name: Set up Python 3.10
|
||||
|
|
@ -412,7 +380,7 @@ jobs:
|
|||
- name: Test Python 3.10
|
||||
shell: bash
|
||||
run: |
|
||||
python -m pip install pytest
|
||||
python -m pip install -r requirements-test.txt
|
||||
PYTHONPATH=built LD_LIBRARY_PATH=built/lib DYLD_LIBRARY_PATH=built/lib python -m pytest
|
||||
|
||||
- name: Set up Python 3.9
|
||||
|
|
@ -426,7 +394,7 @@ jobs:
|
|||
- name: Test Python 3.9
|
||||
shell: bash
|
||||
run: |
|
||||
python -m pip install pytest
|
||||
python -m pip install -r requirements-test.txt
|
||||
PYTHONPATH=built LD_LIBRARY_PATH=built/lib DYLD_LIBRARY_PATH=built/lib python -m pytest
|
||||
|
||||
- name: Set up Python 3.8
|
||||
|
|
@ -440,21 +408,7 @@ jobs:
|
|||
- name: Test Python 3.8
|
||||
shell: bash
|
||||
run: |
|
||||
python -m pip install pytest
|
||||
PYTHONPATH=built LD_LIBRARY_PATH=built/lib DYLD_LIBRARY_PATH=built/lib python -m pytest
|
||||
|
||||
- name: Set up Python 3.7
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: '3.7'
|
||||
- name: Build Python 3.7
|
||||
shell: bash
|
||||
run: |
|
||||
python makepanda/makepanda.py --git-commit=${{github.sha}} --outputdir=built --everything --no-eigen --python-incdir="$pythonLocation/include" --python-libdir="$pythonLocation/lib" --verbose --threads=4 --windows-sdk=10
|
||||
- name: Test Python 3.7
|
||||
shell: bash
|
||||
run: |
|
||||
python -m pip install pytest
|
||||
python -m pip install -r requirements-test.txt
|
||||
PYTHONPATH=built LD_LIBRARY_PATH=built/lib DYLD_LIBRARY_PATH=built/lib python -m pytest
|
||||
|
||||
- name: Make installer
|
||||
|
|
|
|||
|
|
@ -0,0 +1,23 @@
|
|||
name: Run Mypy
|
||||
on: [push, pull_request]
|
||||
|
||||
jobs:
|
||||
mypy:
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-latest, macos-latest, windows-latest]
|
||||
python-version: ['3.8', '3.11']
|
||||
fail-fast: false
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Set up Python ${{ matrix.python-version }}
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
python -m pip install --upgrade pip
|
||||
pip install mypy==1.4.0
|
||||
- name: Run mypy on direct
|
||||
run: python tests/run_mypy.py
|
||||
|
|
@ -17,6 +17,7 @@ vgcore.*
|
|||
*.save.1
|
||||
*.sublime-workspace
|
||||
.vscode/
|
||||
.idea/
|
||||
|
||||
# Temporary build files
|
||||
/_vfsimporter.*
|
||||
|
|
@ -51,9 +52,10 @@ cmake_install.cmake
|
|||
install_manifest.txt
|
||||
CTestTestfile.cmake
|
||||
|
||||
# Windows
|
||||
# Operating system
|
||||
Thumbs.db
|
||||
ehthumbs.db
|
||||
.DS_Store
|
||||
|
||||
# macOS
|
||||
.DS_Store
|
||||
|
|
|
|||
|
|
@ -17,6 +17,8 @@ This is a list of all the people who are contributing financially to Panda3D. I
|
|||
* Max Voss
|
||||
* Hawkheart
|
||||
* Veronica
|
||||
* Cody Sevier
|
||||
* Marek Alexa
|
||||
|
||||
## Enthusiasts
|
||||
|
||||
|
|
@ -28,6 +30,8 @@ This is a list of all the people who are contributing financially to Panda3D. I
|
|||
* SureBet
|
||||
* Gyedo Jeon
|
||||
* GameDev JONI
|
||||
* Max Rodriguez
|
||||
* Jethro Schoppenhorst
|
||||
|
||||
## Backers
|
||||
|
||||
|
|
|
|||
|
|
@ -24,6 +24,9 @@ endif()
|
|||
|
||||
# Set defaults for macOS, must be before project().
|
||||
if(APPLE)
|
||||
# Needed for enable_language(OBJCXX)
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
|
||||
set(CMAKE_OSX_DEPLOYMENT_TARGET "10.9" CACHE STRING "Minimum macOS version to target")
|
||||
set(CMAKE_XCODE_ATTRIBUTE_CLANG_CXX_LIBRARY "libc++")
|
||||
|
||||
|
|
@ -46,6 +49,11 @@ project(Panda3D VERSION ${_version})
|
|||
unset(_version)
|
||||
unset(_s)
|
||||
|
||||
if(APPLE)
|
||||
# Allows separating out C++ flags from ObjC++ flags
|
||||
enable_language(OBJCXX)
|
||||
endif()
|
||||
|
||||
# Determine the possible build types. Must be *after* calling project().
|
||||
set(_configs Standard Release RelWithDebInfo Debug MinSizeRel)
|
||||
if(CMAKE_CXX_COMPILER_ID MATCHES "(AppleClang|Clang|GCC)")
|
||||
|
|
|
|||
|
|
@ -1905,7 +1905,7 @@ class main(wx.Frame):
|
|||
self.txaExtraLines.append(line)
|
||||
txafile.close()
|
||||
except:
|
||||
print "Error opening .txa file!"
|
||||
print("Error opening .txa file!")
|
||||
self.palettize_saveTxaTxt.SetValue(os.path.join(dirname + os.sep , filename))
|
||||
dlg.Destroy()
|
||||
|
||||
|
|
@ -2705,7 +2705,7 @@ class main(wx.Frame):
|
|||
selectedItemIndex = int(self.batchTree.GetItemText(selectedItemId).split()[0])-1
|
||||
batchItem = self.batchList[selectedItemIndex]
|
||||
|
||||
print '\n'+self.BuildCommand(batchItem)
|
||||
print('\n'+self.BuildCommand(batchItem))
|
||||
|
||||
if (batchItem['cmd'].count('maya2egg')):
|
||||
# Display Maya2Egg Tool Panel
|
||||
|
|
@ -2840,7 +2840,7 @@ class main(wx.Frame):
|
|||
self.txaExtraLines.append(line)
|
||||
txafile.close()
|
||||
except:
|
||||
print "Error opening .txa file!"
|
||||
print("Error opening .txa file!")
|
||||
|
||||
self.batchItemNameTxt.SetValue(batchItem['label'])
|
||||
|
||||
|
|
|
|||
|
|
@ -280,9 +280,7 @@ class Actor(DirectObject, NodePath):
|
|||
self.setLODNode(node = lodNode)
|
||||
# preserve numerical order for lod's
|
||||
# this will make it easier to set ranges
|
||||
sortedKeys = list(models.keys())
|
||||
sortedKeys.sort()
|
||||
for lodName in sortedKeys:
|
||||
for lodName in sorted(models):
|
||||
# make a node under the LOD switch
|
||||
# for each lod (just because!)
|
||||
self.addLOD(str(lodName))
|
||||
|
|
@ -302,9 +300,7 @@ class Actor(DirectObject, NodePath):
|
|||
# it is a single part actor w/LOD
|
||||
self.setLODNode(node = lodNode)
|
||||
# preserve order of LOD's
|
||||
sortedKeys = list(models.keys())
|
||||
sortedKeys.sort()
|
||||
for lodName in sortedKeys:
|
||||
for lodName in sorted(models):
|
||||
self.addLOD(str(lodName))
|
||||
# pass in dictionary of parts
|
||||
self.loadModel(models[lodName], lodName=lodName,
|
||||
|
|
@ -323,9 +319,7 @@ class Actor(DirectObject, NodePath):
|
|||
if isinstance(models, dict):
|
||||
if isinstance(models[next(iter(models))], dict):
|
||||
# then we have a multi-part w/ LOD
|
||||
sortedKeys = list(models.keys())
|
||||
sortedKeys.sort()
|
||||
for lodName in sortedKeys:
|
||||
for lodName in sorted(models):
|
||||
# iterate over both dicts
|
||||
for partName in anims:
|
||||
self.loadAnims(
|
||||
|
|
@ -336,9 +330,7 @@ class Actor(DirectObject, NodePath):
|
|||
self.loadAnims(anims[partName], partName)
|
||||
elif isinstance(models, dict):
|
||||
# then we have single-part w/ LOD
|
||||
sortedKeys = list(models.keys())
|
||||
sortedKeys.sort()
|
||||
for lodName in sortedKeys:
|
||||
for lodName in sorted(models):
|
||||
self.loadAnims(anims, lodName=lodName)
|
||||
else:
|
||||
# else it is single-part w/o LOD
|
||||
|
|
@ -603,9 +595,6 @@ class Actor(DirectObject, NodePath):
|
|||
return bundles
|
||||
|
||||
def __updateSortedLODNames(self):
|
||||
# Cache the sorted LOD names so we don't have to grab them
|
||||
# and sort them every time somebody asks for the list
|
||||
self.__sortedLODNames = list(self.__partBundleDict.keys())
|
||||
# Reverse sort the doing a string->int
|
||||
def sortKey(x):
|
||||
if not str(x).isdigit():
|
||||
|
|
@ -622,7 +611,9 @@ class Actor(DirectObject, NodePath):
|
|||
else:
|
||||
return int(x)
|
||||
|
||||
self.__sortedLODNames.sort(key=sortKey, reverse=True)
|
||||
# Cache the sorted LOD names so we don't have to grab them
|
||||
# and sort them every time somebody asks for the list
|
||||
self.__sortedLODNames = sorted(self.__partBundleDict, key=sortKey, reverse=True)
|
||||
|
||||
def getLODNames(self):
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -169,12 +169,9 @@ class ClusterClient(DirectObject.DirectObject):
|
|||
self.serverList[server].sendNamedMovementDone()
|
||||
|
||||
def redoSortedPriorities(self):
|
||||
self.sortedControlMappings = []
|
||||
for key in self.controlMappings:
|
||||
self.sortedControlMappings.append([self.controlPriorities[key],
|
||||
key])
|
||||
|
||||
self.sortedControlMappings.sort()
|
||||
self.sortedControlMappings = sorted(
|
||||
[self.controlPriorities[key], key] for key in self.controlMappings
|
||||
)
|
||||
|
||||
def moveObject(self, nodePath, object, serverList, offset, hasColor = True):
|
||||
self.notify.debug('moving object '+object)
|
||||
|
|
|
|||
|
|
@ -137,13 +137,9 @@ class ClusterServer(DirectObject.DirectObject):
|
|||
self.objectMappings.pop(name)
|
||||
|
||||
def redoSortedPriorities(self):
|
||||
|
||||
self.sortedControlMappings = []
|
||||
for key in self.objectMappings:
|
||||
self.sortedControlMappings.append([self.controlPriorities[key],
|
||||
key])
|
||||
|
||||
self.sortedControlMappings.sort()
|
||||
self.sortedControlMappings = sorted(
|
||||
[self.controlPriorities[key], key] for key in self.objectMappings
|
||||
)
|
||||
|
||||
def addControlMapping(self, objectName, controlledName, offset = None,
|
||||
priority = 0):
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -1,8 +1,9 @@
|
|||
/* A Bison parser, made by GNU Bison 3.1. */
|
||||
/* A Bison parser, made by GNU Bison 3.8.2. */
|
||||
|
||||
/* Bison interface for Yacc-like parsers in C
|
||||
|
||||
Copyright (C) 1984, 1989-1990, 2000-2015, 2018 Free Software Foundation, Inc.
|
||||
Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2021 Free Software Foundation,
|
||||
Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
|
@ -15,7 +16,7 @@
|
|||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
/* As a special exception, you may create a larger work that contains
|
||||
part or all of the Bison parser skeleton and distribute that work
|
||||
|
|
@ -30,6 +31,10 @@
|
|||
This special exception was added by the Free Software Foundation in
|
||||
version 2.2 of Bison. */
|
||||
|
||||
/* DO NOT RELY ON FEATURES THAT ARE NOT DOCUMENTED in the manual,
|
||||
especially those whose name start with YY_ or yy_. They are
|
||||
private implementation details that can be changed or removed. */
|
||||
|
||||
#ifndef YY_DCYY_BUILT_TMP_DCPARSER_YXX_H_INCLUDED
|
||||
# define YY_DCYY_BUILT_TMP_DCPARSER_YXX_H_INCLUDED
|
||||
/* Debug traces. */
|
||||
|
|
@ -40,54 +45,63 @@
|
|||
extern int dcyydebug;
|
||||
#endif
|
||||
|
||||
/* Token type. */
|
||||
/* Token kinds. */
|
||||
#ifndef YYTOKENTYPE
|
||||
# define YYTOKENTYPE
|
||||
enum yytokentype
|
||||
{
|
||||
UNSIGNED_INTEGER = 258,
|
||||
SIGNED_INTEGER = 259,
|
||||
REAL = 260,
|
||||
STRING = 261,
|
||||
IDENTIFIER = 262,
|
||||
HEX_STRING = 263,
|
||||
KEYWORD = 264,
|
||||
KW_DCLASS = 265,
|
||||
KW_STRUCT = 266,
|
||||
KW_FROM = 267,
|
||||
KW_IMPORT = 268,
|
||||
KW_TYPEDEF = 269,
|
||||
KW_KEYWORD = 270,
|
||||
KW_SWITCH = 271,
|
||||
KW_CASE = 272,
|
||||
KW_DEFAULT = 273,
|
||||
KW_BREAK = 274,
|
||||
KW_INT8 = 275,
|
||||
KW_INT16 = 276,
|
||||
KW_INT32 = 277,
|
||||
KW_INT64 = 278,
|
||||
KW_UINT8 = 279,
|
||||
KW_UINT16 = 280,
|
||||
KW_UINT32 = 281,
|
||||
KW_UINT64 = 282,
|
||||
KW_FLOAT64 = 283,
|
||||
KW_STRING = 284,
|
||||
KW_BLOB = 285,
|
||||
KW_BLOB32 = 286,
|
||||
KW_INT8ARRAY = 287,
|
||||
KW_INT16ARRAY = 288,
|
||||
KW_INT32ARRAY = 289,
|
||||
KW_UINT8ARRAY = 290,
|
||||
KW_UINT16ARRAY = 291,
|
||||
KW_UINT32ARRAY = 292,
|
||||
KW_UINT32UINT8ARRAY = 293,
|
||||
KW_CHAR = 294,
|
||||
START_DC = 295,
|
||||
START_PARAMETER_VALUE = 296,
|
||||
START_PARAMETER_DESCRIPTION = 297
|
||||
YYEMPTY = -2,
|
||||
YYEOF = 0, /* "end of file" */
|
||||
YYerror = 256, /* error */
|
||||
YYUNDEF = 257, /* "invalid token" */
|
||||
UNSIGNED_INTEGER = 258, /* UNSIGNED_INTEGER */
|
||||
SIGNED_INTEGER = 259, /* SIGNED_INTEGER */
|
||||
REAL = 260, /* REAL */
|
||||
STRING = 261, /* STRING */
|
||||
IDENTIFIER = 262, /* IDENTIFIER */
|
||||
HEX_STRING = 263, /* HEX_STRING */
|
||||
KEYWORD = 264, /* KEYWORD */
|
||||
KW_DCLASS = 265, /* KW_DCLASS */
|
||||
KW_STRUCT = 266, /* KW_STRUCT */
|
||||
KW_FROM = 267, /* KW_FROM */
|
||||
KW_IMPORT = 268, /* KW_IMPORT */
|
||||
KW_TYPEDEF = 269, /* KW_TYPEDEF */
|
||||
KW_KEYWORD = 270, /* KW_KEYWORD */
|
||||
KW_SWITCH = 271, /* KW_SWITCH */
|
||||
KW_CASE = 272, /* KW_CASE */
|
||||
KW_DEFAULT = 273, /* KW_DEFAULT */
|
||||
KW_BREAK = 274, /* KW_BREAK */
|
||||
KW_INT8 = 275, /* KW_INT8 */
|
||||
KW_INT16 = 276, /* KW_INT16 */
|
||||
KW_INT32 = 277, /* KW_INT32 */
|
||||
KW_INT64 = 278, /* KW_INT64 */
|
||||
KW_UINT8 = 279, /* KW_UINT8 */
|
||||
KW_UINT16 = 280, /* KW_UINT16 */
|
||||
KW_UINT32 = 281, /* KW_UINT32 */
|
||||
KW_UINT64 = 282, /* KW_UINT64 */
|
||||
KW_FLOAT64 = 283, /* KW_FLOAT64 */
|
||||
KW_STRING = 284, /* KW_STRING */
|
||||
KW_BLOB = 285, /* KW_BLOB */
|
||||
KW_BLOB32 = 286, /* KW_BLOB32 */
|
||||
KW_INT8ARRAY = 287, /* KW_INT8ARRAY */
|
||||
KW_INT16ARRAY = 288, /* KW_INT16ARRAY */
|
||||
KW_INT32ARRAY = 289, /* KW_INT32ARRAY */
|
||||
KW_UINT8ARRAY = 290, /* KW_UINT8ARRAY */
|
||||
KW_UINT16ARRAY = 291, /* KW_UINT16ARRAY */
|
||||
KW_UINT32ARRAY = 292, /* KW_UINT32ARRAY */
|
||||
KW_UINT32UINT8ARRAY = 293, /* KW_UINT32UINT8ARRAY */
|
||||
KW_CHAR = 294, /* KW_CHAR */
|
||||
START_DC = 295, /* START_DC */
|
||||
START_PARAMETER_VALUE = 296, /* START_PARAMETER_VALUE */
|
||||
START_PARAMETER_DESCRIPTION = 297 /* START_PARAMETER_DESCRIPTION */
|
||||
};
|
||||
typedef enum yytokentype yytoken_kind_t;
|
||||
#endif
|
||||
/* Tokens. */
|
||||
/* Token kinds. */
|
||||
#define YYEMPTY -2
|
||||
#define YYEOF 0
|
||||
#define YYerror 256
|
||||
#define YYUNDEF 257
|
||||
#define UNSIGNED_INTEGER 258
|
||||
#define SIGNED_INTEGER 259
|
||||
#define REAL 260
|
||||
|
|
@ -134,6 +148,8 @@ extern int dcyydebug;
|
|||
|
||||
extern YYSTYPE dcyylval;
|
||||
|
||||
|
||||
int dcyyparse (void);
|
||||
|
||||
|
||||
#endif /* !YY_DCYY_BUILT_TMP_DCPARSER_YXX_H_INCLUDED */
|
||||
|
|
|
|||
|
|
@ -297,6 +297,7 @@ dclass_or_struct:
|
|||
dclass:
|
||||
KW_DCLASS optional_name
|
||||
{
|
||||
$<u.dclass>$ = current_class;
|
||||
current_class = new DCClass(dc_file, $2, false, false);
|
||||
}
|
||||
dclass_derivation '{' dclass_fields '}'
|
||||
|
|
@ -401,6 +402,7 @@ dclass_field:
|
|||
struct:
|
||||
KW_STRUCT optional_name
|
||||
{
|
||||
$<u.dclass>$ = current_class;
|
||||
current_class = new DCClass(dc_file, $2, true, false);
|
||||
}
|
||||
struct_derivation '{' struct_fields '}'
|
||||
|
|
@ -488,6 +490,7 @@ struct_field:
|
|||
atomic_field:
|
||||
optional_name '('
|
||||
{
|
||||
$<u.atomic>$ = current_atomic;
|
||||
if (current_class == nullptr) {
|
||||
yyerror("Cannot define a method outside of a struct or class.");
|
||||
DCClass *temp_class = new DCClass(dc_file, "temp", false, false); // memory leak.
|
||||
|
|
@ -1243,12 +1246,13 @@ optional_name:
|
|||
switch:
|
||||
KW_SWITCH optional_name '(' parameter_or_atomic ')' '{'
|
||||
{
|
||||
$<u.dswitch>$ = current_switch;
|
||||
current_switch = new DCSwitch($2, $4);
|
||||
}
|
||||
switch_fields '}'
|
||||
{
|
||||
$$ = current_switch;
|
||||
current_switch = (DCSwitch *)$<u.parameter>7;
|
||||
current_switch = $<u.dswitch>7;
|
||||
}
|
||||
;
|
||||
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ to and may be replaced by the following code:
|
|||
base = ShowBase()
|
||||
"""
|
||||
|
||||
__all__ = []
|
||||
__all__ = ()
|
||||
|
||||
if __debug__:
|
||||
print('Using deprecated DirectStart interface.')
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ from direct.showbase import ShowBase
|
|||
base = ShowBase.ShowBase()
|
||||
|
||||
# Put an axis in the world:
|
||||
base.loader.loadModel("models/misc/xyzAxis").reparentTo(render)
|
||||
base.loader.loadModel("models/misc/xyzAxis").reparentTo(base.render)
|
||||
|
||||
base.camera.setPosHpr(0, -10.0, 0, 0, 0, 0)
|
||||
base.camLens.setFov(52.0)
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ from direct.showbase import ThreeUpShow
|
|||
base = ThreeUpShow.ThreeUpShow()
|
||||
|
||||
# Put an axis in the world:
|
||||
base.loader.loadModel("models/misc/xyzAxis").reparentTo(render)
|
||||
base.loader.loadModel("models/misc/xyzAxis").reparentTo(base.render)
|
||||
|
||||
base.camera.setPosHpr(0, -10.0, 0, 0, 0, 0)
|
||||
base.camLens.setFov(52.0)
|
||||
|
|
|
|||
|
|
@ -41,8 +41,12 @@ class DirectJoybox(DirectObject):
|
|||
xyzMultiplier = 1.0
|
||||
hprMultiplier = 1.0
|
||||
|
||||
def __init__(self, device = 'CerealBox', nodePath = base.direct.camera,
|
||||
headingNP = base.direct.camera):
|
||||
def __init__(self, device = 'CerealBox', nodePath = None, headingNP = None):
|
||||
from direct.showbase.ShowBaseGlobal import base
|
||||
if nodePath is None:
|
||||
nodePath = base.direct.camera
|
||||
if headingNP is None:
|
||||
headingNP = base.direct.camera
|
||||
# See if device manager has been initialized
|
||||
if base.direct.deviceManager is None:
|
||||
base.direct.deviceManager = DirectDeviceManager()
|
||||
|
|
|
|||
|
|
@ -55,10 +55,11 @@ class RotatingLog:
|
|||
return 0
|
||||
|
||||
def filePath(self):
|
||||
dateString=time.strftime("%Y_%m_%d_%H", time.localtime())
|
||||
dateString = time.strftime("%Y_%m_%d_%H", time.localtime())
|
||||
for i in range(26):
|
||||
path="%s_%s_%s.log"%(self.path, dateString, chr(i+97))
|
||||
if not os.path.exists(path) or os.stat(path)[6] < self.sizeLimit:
|
||||
limit = self.sizeLimit
|
||||
path = "%s_%s_%s.log" % (self.path, dateString, chr(i+97))
|
||||
if limit is None or not os.path.exists(path) or os.stat(path)[6] < limit:
|
||||
return path
|
||||
# Hmm, 26 files are full? throw the rest in z:
|
||||
# Maybe we should clear the self.sizeLimit here... maybe.
|
||||
|
|
@ -83,7 +84,6 @@ class RotatingLog:
|
|||
self.closed = self.file.closed
|
||||
self.mode = self.file.mode
|
||||
self.name = self.file.name
|
||||
self.softspace = self.file.softspace
|
||||
#self.encoding = self.file.encoding # Python 2.3
|
||||
#self.newlines = self.file.newlines # Python 2.3, maybe
|
||||
|
||||
|
|
|
|||
|
|
@ -66,9 +66,7 @@ class DirectLights(NodePath):
|
|||
|
||||
def getNameList(self):
|
||||
# Return a sorted list of all lights in the light dict
|
||||
nameList = [x.getName() for x in self.lightDict.values()]
|
||||
nameList.sort()
|
||||
return nameList
|
||||
return sorted(x.getName() for x in self.lightDict.values())
|
||||
|
||||
def create(self, ltype):
|
||||
ltype = ltype.lower()
|
||||
|
|
|
|||
|
|
@ -90,6 +90,7 @@ defaultHiddenImports = {
|
|||
'scipy.special._ufuncs': ['scipy.special._ufuncs_cxx'],
|
||||
'scipy.stats._stats': ['scipy.special.cython_special'],
|
||||
'setuptools.monkey': ['setuptools.msvc'],
|
||||
'shapely._geometry_helpers': ['shapely._geos'],
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1145,15 +1146,12 @@ class Freezer:
|
|||
|
||||
# Walk through the list in sorted order, so we reach parents
|
||||
# before children.
|
||||
names = list(self.modules.items())
|
||||
names.sort()
|
||||
|
||||
excludeDict = {}
|
||||
implicitParentDict = {}
|
||||
includes = []
|
||||
autoIncludes = []
|
||||
origToNewName = {}
|
||||
for newName, mdef in names:
|
||||
for newName, mdef in sorted(self.modules.items()):
|
||||
moduleName = mdef.moduleName
|
||||
origToNewName[moduleName] = newName
|
||||
if mdef.implicit and '.' in newName:
|
||||
|
|
@ -2583,6 +2581,21 @@ class PandaModuleFinder(modulefinder.ModuleFinder):
|
|||
else:
|
||||
code = fp.read()
|
||||
|
||||
# Strip out delvewheel patch (see GitHub issue #1492)
|
||||
if isinstance(code, bytes):
|
||||
# Don't look for \n at the end, it may also be \r\n
|
||||
start_marker = b'# start delvewheel patch'
|
||||
end_marker = b'# end delvewheel patch'
|
||||
else:
|
||||
start_marker = '# start delvewheel patch'
|
||||
end_marker = '# end delvewheel patch'
|
||||
|
||||
start = code.find(start_marker)
|
||||
while start >= 0:
|
||||
end = code.find(end_marker, start) + len(end_marker)
|
||||
code = code[:start] + code[end:]
|
||||
start = code.find(start_marker)
|
||||
|
||||
code += b'\n' if isinstance(code, bytes) else '\n'
|
||||
co = compile(code, pathname, 'exec', optimize=self.optimize)
|
||||
elif type == imp.PY_COMPILED:
|
||||
|
|
|
|||
|
|
@ -634,7 +634,20 @@ class build_apps(setuptools.Command):
|
|||
for index in self.pypi_extra_indexes:
|
||||
pip_args += ['--extra-index-url', index]
|
||||
|
||||
subprocess.check_call([sys.executable, '-m', 'pip'] + pip_args)
|
||||
try:
|
||||
subprocess.check_call([sys.executable, '-m', 'pip'] + pip_args)
|
||||
except:
|
||||
# Display a more helpful message for these common issues.
|
||||
if platform.startswith('manylinux2010_') and sys.version_info >= (3, 11):
|
||||
new_platform = platform.replace('manylinux2010_', 'manylinux2014_')
|
||||
self.announce('This error likely occurs because {} is not a supported target as of Python 3.11.\nChange the target platform to {} instead.'.format(platform, new_platform), distutils.log.ERROR)
|
||||
elif platform.startswith('manylinux1_') and sys.version_info >= (3, 10):
|
||||
new_platform = platform.replace('manylinux1_', 'manylinux2014_')
|
||||
self.announce('This error likely occurs because {} is not a supported target as of Python 3.10.\nChange the target platform to {} instead.'.format(platform, new_platform), distutils.log.ERROR)
|
||||
elif platform.startswith('macosx_10_6_') and sys.version_info >= (3, 8):
|
||||
new_platform = platform.replace('macosx_10_6_', 'macosx_10_9_')
|
||||
self.announce('This error likely occurs because {} is not a supported target as of Python 3.8.\nChange the target platform to {} instead.'.format(platform, new_platform), distutils.log.ERROR)
|
||||
raise
|
||||
|
||||
# Return a list of paths to the downloaded whls
|
||||
return [
|
||||
|
|
@ -846,16 +859,12 @@ class build_apps(setuptools.Command):
|
|||
libdir = os.path.dirname(dtool_fn.to_os_specific())
|
||||
etcdir = os.path.join(libdir, '..', 'etc')
|
||||
|
||||
etcfiles = os.listdir(etcdir)
|
||||
etcfiles.sort(reverse=True)
|
||||
for fn in etcfiles:
|
||||
for fn in sorted(os.listdir(etcdir), reverse=True):
|
||||
if fn.lower().endswith('.prc'):
|
||||
with open(os.path.join(etcdir, fn)) as f:
|
||||
prcstring += f.read()
|
||||
else:
|
||||
etcfiles = [i for i in p3dwhl.namelist() if i.endswith('.prc')]
|
||||
etcfiles.sort(reverse=True)
|
||||
for fn in etcfiles:
|
||||
for fn in sorted((i for i in p3dwhl.namelist() if i.endswith('.prc')), reverse=True):
|
||||
with p3dwhl.open(fn) as f:
|
||||
prcstring += f.read().decode('utf8')
|
||||
|
||||
|
|
@ -1689,6 +1698,8 @@ class bdist_apps(setuptools.Command):
|
|||
setattr(self, opt, None)
|
||||
|
||||
def finalize_options(self):
|
||||
import pkg_resources
|
||||
|
||||
# We need to massage the inputs a bit in case they came from a
|
||||
# setup.cfg file.
|
||||
self.installers = {
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
from __future__ import annotations
|
||||
|
||||
#from otp.ai.AIBaseGlobal import *
|
||||
from direct.directnotify import DirectNotifyGlobal
|
||||
from direct.showbase.DirectObject import DirectObject
|
||||
|
|
@ -39,7 +41,7 @@ class AsyncRequest(DirectObject):
|
|||
will be called again when the new self.neededObjects is complete. You
|
||||
may repeat this as necessary.
|
||||
"""
|
||||
_asyncRequests = {}
|
||||
_asyncRequests: dict[int, AsyncRequest] = {}
|
||||
|
||||
notify = DirectNotifyGlobal.directNotify.newCategory('AsyncRequest')
|
||||
|
||||
|
|
|
|||
|
|
@ -76,41 +76,3 @@ if __debug__:
|
|||
def flush(self):
|
||||
CachedDOData.flush(self)
|
||||
self._flushed = True
|
||||
|
||||
dc = CRDataCache()
|
||||
dc._startMemLeakCheck()
|
||||
|
||||
cd = CachedDOData()
|
||||
cd.foo = 34
|
||||
dc.setCachedData(1, 'testCachedData', cd)
|
||||
del cd
|
||||
cd = CachedDOData()
|
||||
cd.bar = 45
|
||||
dc.setCachedData(1, 'testCachedData2', cd)
|
||||
del cd
|
||||
assert dc.hasCachedData(1)
|
||||
assert dc.hasCachedData(1)
|
||||
assert not dc.hasCachedData(2)
|
||||
# data is dict of dataName->data
|
||||
data = dc.popCachedData(1)
|
||||
assert len(data) == 2
|
||||
assert 'testCachedData' in data
|
||||
assert 'testCachedData2' in data
|
||||
assert data['testCachedData'].foo == 34
|
||||
assert data['testCachedData2'].bar == 45
|
||||
for cd in data.values():
|
||||
cd.flush()
|
||||
del data
|
||||
dc._checkMemLeaks()
|
||||
|
||||
cd = CachedDOData()
|
||||
cd.bar = 1234
|
||||
dc.setCachedData(43, 'testCachedData2', cd)
|
||||
del cd
|
||||
assert dc.hasCachedData(43)
|
||||
dc.flush()
|
||||
dc._checkMemLeaks()
|
||||
|
||||
dc._stopMemLeakCheck()
|
||||
dc.destroy()
|
||||
del dc
|
||||
|
|
|
|||
|
|
@ -20,3 +20,10 @@ class CachedDOData:
|
|||
# override and destroy the cached data
|
||||
# cached data is typically created by the DistributedObject and destroyed here
|
||||
pass
|
||||
|
||||
# These next two methods tell mypy to allow arbitrary attributes.
|
||||
def __getattribute__(self, name: str):
|
||||
return object.__getattribute__(self, name)
|
||||
|
||||
def __setattr__(self, name: str, value) -> None:
|
||||
object.__setattr__(self, name, value)
|
||||
|
|
|
|||
|
|
@ -478,6 +478,9 @@ class ClientRepositoryBase(ConnectionRepository):
|
|||
f"Asked to update non-existent DistObj {doId} and failed to find it")
|
||||
|
||||
def __doUpdateOwner(self, doId, di):
|
||||
if not self.hasOwnerView():
|
||||
return False
|
||||
|
||||
ovObj = self.doId2ownerView.get(doId)
|
||||
if ovObj:
|
||||
odg = Datagram(di.getDatagram())
|
||||
|
|
|
|||
|
|
@ -317,7 +317,7 @@ class DistributedObjectAI(DistributedObjectBase):
|
|||
# setLocation destroys self._zoneData if we move away to
|
||||
# a different zone
|
||||
if self._zoneData is None:
|
||||
from otp.ai.AIZoneData import AIZoneData
|
||||
from otp.ai.AIZoneData import AIZoneData # type: ignore[import]
|
||||
self._zoneData = AIZoneData(self.air, self.parentId, self.zoneId)
|
||||
return self._zoneData
|
||||
|
||||
|
|
@ -515,7 +515,7 @@ class DistributedObjectAI(DistributedObjectBase):
|
|||
# simultaneously on different lists of avatars, although they
|
||||
# should have different names.
|
||||
|
||||
from otp.ai import Barrier
|
||||
from otp.ai import Barrier # type: ignore[import]
|
||||
context = self.__nextBarrierContext
|
||||
# We assume the context number is passed as a uint16.
|
||||
self.__nextBarrierContext = (self.__nextBarrierContext + 1) & 0xffff
|
||||
|
|
|
|||
|
|
@ -432,7 +432,7 @@ class DistributedObjectUD(DistributedObjectBase):
|
|||
# simultaneously on different lists of avatars, although they
|
||||
# should have different names.
|
||||
|
||||
from otp.ai import Barrier
|
||||
from otp.ai import Barrier # type: ignore[import]
|
||||
context = self.__nextBarrierContext
|
||||
# We assume the context number is passed as a uint16.
|
||||
self.__nextBarrierContext = (self.__nextBarrierContext + 1) & 0xffff
|
||||
|
|
|
|||
|
|
@ -149,10 +149,7 @@ class DoCollectionManager:
|
|||
class2count.setdefault(className, 0)
|
||||
class2count[className] += 1
|
||||
count2classes = invertDictLossless(class2count)
|
||||
counts = list(count2classes.keys())
|
||||
counts.sort()
|
||||
counts.reverse()
|
||||
for count in counts:
|
||||
for count in sorted(count2classes, reverse=True):
|
||||
count2classes[count].sort()
|
||||
for name in count2classes[count]:
|
||||
print('%s %s' % (count, name))
|
||||
|
|
@ -166,10 +163,7 @@ class DoCollectionManager:
|
|||
class2count.setdefault(className, 0)
|
||||
class2count[className] += 1
|
||||
count2classes = invertDictLossless(class2count)
|
||||
counts = list(count2classes.keys())
|
||||
counts.sort()
|
||||
counts.reverse()
|
||||
for count in counts:
|
||||
for count in sorted(count2classes, reverse=True):
|
||||
count2classes[count].sort()
|
||||
for name in count2classes[count]:
|
||||
# print '%s %s' % (count, name)
|
||||
|
|
|
|||
|
|
@ -7,6 +7,8 @@ zone, remove interest in that zone.
|
|||
p.s. A great deal of this code is just code moved from ClientRepository.py.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from panda3d.core import ConfigVariableBool
|
||||
from .MsgTypes import CLIENT_ADD_INTEREST, CLIENT_REMOVE_INTEREST
|
||||
if ConfigVariableBool('astron-support', True):
|
||||
|
|
@ -101,9 +103,9 @@ class DoInterestManager(DirectObject.DirectObject):
|
|||
_ContextIdSerialNum = 100
|
||||
_ContextIdMask = 0x3FFFFFFF # avoid making Python create a long
|
||||
|
||||
_interests = {}
|
||||
_interests: dict[int, InterestState] = {}
|
||||
if __debug__:
|
||||
_debug_interestHistory = []
|
||||
_debug_interestHistory: list[tuple] = []
|
||||
_debug_maxDescriptionLen = 40
|
||||
|
||||
_SerialGen = SerialNumGen()
|
||||
|
|
@ -516,8 +518,7 @@ class DoInterestManager(DirectObject.DirectObject):
|
|||
# Add message type
|
||||
if ConfigVariableBool('astron-support', True):
|
||||
if isinstance(zoneIdList, list):
|
||||
vzl = list(zoneIdList)
|
||||
vzl.sort()
|
||||
vzl = sorted(zoneIdList)
|
||||
uniqueElements(vzl)
|
||||
datagram.addUint16(CLIENT_ADD_INTEREST_MULTIPLE)
|
||||
datagram.addUint32(contextId)
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
from __future__ import annotations
|
||||
|
||||
from panda3d.core import NodePath
|
||||
|
||||
#
|
||||
|
|
@ -15,8 +17,8 @@ from panda3d.core import NodePath
|
|||
class GridParent:
|
||||
|
||||
# this lets GridParents share CellOrigins
|
||||
GridZone2CellOrigin = {}
|
||||
GridZone2count = {}
|
||||
GridZone2CellOrigin: dict[tuple, NodePath] = {}
|
||||
GridZone2count: dict[tuple, int] = {}
|
||||
@staticmethod
|
||||
def getCellOrigin(grid, zoneId):
|
||||
tup = (grid, zoneId)
|
||||
|
|
|
|||
|
|
@ -1,247 +1,247 @@
|
|||
"""MsgTypes module: contains distributed object message types"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from panda3d.core import ConfigVariableBool
|
||||
|
||||
from direct.showbase.PythonUtil import invertDictLossless
|
||||
|
||||
if ConfigVariableBool('astron-support', True):
|
||||
MsgName2Id = {
|
||||
'CLIENT_HELLO': 1,
|
||||
'CLIENT_HELLO_RESP': 2,
|
||||
CLIENT_HELLO = 1
|
||||
CLIENT_HELLO_RESP = 2
|
||||
|
||||
# Sent by the client when it's leaving.
|
||||
'CLIENT_DISCONNECT': 3,
|
||||
# Sent by the client when it's leaving.
|
||||
CLIENT_DISCONNECT = 3
|
||||
|
||||
# Sent by the server when it is dropping the connection deliberately.
|
||||
'CLIENT_EJECT': 4,
|
||||
# Sent by the server when it is dropping the connection deliberately.
|
||||
CLIENT_EJECT = 4
|
||||
|
||||
'CLIENT_HEARTBEAT': 5,
|
||||
CLIENT_HEARTBEAT = 5
|
||||
|
||||
'CLIENT_OBJECT_SET_FIELD': 120,
|
||||
'CLIENT_OBJECT_SET_FIELDS': 121,
|
||||
'CLIENT_OBJECT_LEAVING': 132,
|
||||
'CLIENT_OBJECT_LEAVING_OWNER': 161,
|
||||
'CLIENT_ENTER_OBJECT_REQUIRED': 142,
|
||||
'CLIENT_ENTER_OBJECT_REQUIRED_OTHER': 143,
|
||||
'CLIENT_ENTER_OBJECT_REQUIRED_OWNER': 172,
|
||||
'CLIENT_ENTER_OBJECT_REQUIRED_OTHER_OWNER': 173,
|
||||
CLIENT_OBJECT_SET_FIELD = 120
|
||||
CLIENT_OBJECT_SET_FIELDS = 121
|
||||
CLIENT_OBJECT_LEAVING = 132
|
||||
CLIENT_OBJECT_LEAVING_OWNER = 161
|
||||
CLIENT_ENTER_OBJECT_REQUIRED = 142
|
||||
CLIENT_ENTER_OBJECT_REQUIRED_OTHER = 143
|
||||
CLIENT_ENTER_OBJECT_REQUIRED_OWNER = 172
|
||||
CLIENT_ENTER_OBJECT_REQUIRED_OTHER_OWNER = 173
|
||||
|
||||
'CLIENT_DONE_INTEREST_RESP': 204,
|
||||
CLIENT_DONE_INTEREST_RESP = 204
|
||||
|
||||
'CLIENT_ADD_INTEREST': 200,
|
||||
'CLIENT_ADD_INTEREST_MULTIPLE': 201,
|
||||
'CLIENT_REMOVE_INTEREST': 203,
|
||||
'CLIENT_OBJECT_LOCATION': 140,
|
||||
CLIENT_ADD_INTEREST = 200
|
||||
CLIENT_ADD_INTEREST_MULTIPLE = 201
|
||||
CLIENT_REMOVE_INTEREST = 203
|
||||
CLIENT_OBJECT_LOCATION = 140
|
||||
|
||||
|
||||
# These are sent internally inside the Astron cluster.
|
||||
# These are sent internally inside the Astron cluster.
|
||||
|
||||
# Message Director control messages:
|
||||
'CONTROL_CHANNEL': 1,
|
||||
'CONTROL_ADD_CHANNEL': 9000,
|
||||
'CONTROL_REMOVE_CHANNEL': 9001,
|
||||
'CONTROL_ADD_RANGE': 9002,
|
||||
'CONTROL_REMOVE_RANGE': 9003,
|
||||
'CONTROL_ADD_POST_REMOVE': 9010,
|
||||
'CONTROL_CLEAR_POST_REMOVES': 9011,
|
||||
# Message Director control messages:
|
||||
CONTROL_CHANNEL = 1
|
||||
CONTROL_ADD_CHANNEL = 9000
|
||||
CONTROL_REMOVE_CHANNEL = 9001
|
||||
CONTROL_ADD_RANGE = 9002
|
||||
CONTROL_REMOVE_RANGE = 9003
|
||||
CONTROL_ADD_POST_REMOVE = 9010
|
||||
CONTROL_CLEAR_POST_REMOVES = 9011
|
||||
|
||||
# State Server control messages:
|
||||
'STATESERVER_CREATE_OBJECT_WITH_REQUIRED': 2000,
|
||||
'STATESERVER_CREATE_OBJECT_WITH_REQUIRED_OTHER': 2001,
|
||||
'STATESERVER_DELETE_AI_OBJECTS': 2009,
|
||||
'STATESERVER_OBJECT_GET_FIELD': 2010,
|
||||
'STATESERVER_OBJECT_GET_FIELD_RESP': 2011,
|
||||
'STATESERVER_OBJECT_GET_FIELDS': 2012,
|
||||
'STATESERVER_OBJECT_GET_FIELDS_RESP': 2013,
|
||||
'STATESERVER_OBJECT_GET_ALL': 2014,
|
||||
'STATESERVER_OBJECT_GET_ALL_RESP': 2015,
|
||||
'STATESERVER_OBJECT_SET_FIELD': 2020,
|
||||
'STATESERVER_OBJECT_SET_FIELDS': 2021,
|
||||
'STATESERVER_OBJECT_DELETE_FIELD_RAM': 2030,
|
||||
'STATESERVER_OBJECT_DELETE_FIELDS_RAM': 2031,
|
||||
'STATESERVER_OBJECT_DELETE_RAM': 2032,
|
||||
'STATESERVER_OBJECT_SET_LOCATION': 2040,
|
||||
'STATESERVER_OBJECT_CHANGING_LOCATION': 2041,
|
||||
'STATESERVER_OBJECT_ENTER_LOCATION_WITH_REQUIRED': 2042,
|
||||
'STATESERVER_OBJECT_ENTER_LOCATION_WITH_REQUIRED_OTHER': 2043,
|
||||
'STATESERVER_OBJECT_GET_LOCATION': 2044,
|
||||
'STATESERVER_OBJECT_GET_LOCATION_RESP': 2045,
|
||||
'STATESERVER_OBJECT_SET_AI': 2050,
|
||||
'STATESERVER_OBJECT_CHANGING_AI': 2051,
|
||||
'STATESERVER_OBJECT_ENTER_AI_WITH_REQUIRED': 2052,
|
||||
'STATESERVER_OBJECT_ENTER_AI_WITH_REQUIRED_OTHER': 2053,
|
||||
'STATESERVER_OBJECT_GET_AI': 2054,
|
||||
'STATESERVER_OBJECT_GET_AI_RESP': 2055,
|
||||
'STATESERVER_OBJECT_SET_OWNER': 2060,
|
||||
'STATESERVER_OBJECT_CHANGING_OWNER': 2061,
|
||||
'STATESERVER_OBJECT_ENTER_OWNER_WITH_REQUIRED': 2062,
|
||||
'STATESERVER_OBJECT_ENTER_OWNER_WITH_REQUIRED_OTHER': 2063,
|
||||
'STATESERVER_OBJECT_GET_OWNER': 2064,
|
||||
'STATESERVER_OBJECT_GET_OWNER_RESP': 2065,
|
||||
'STATESERVER_OBJECT_GET_ZONE_OBJECTS': 2100,
|
||||
'STATESERVER_OBJECT_GET_ZONES_OBJECTS': 2102,
|
||||
'STATESERVER_OBJECT_GET_CHILDREN': 2104,
|
||||
'STATESERVER_OBJECT_GET_ZONE_COUNT': 2110,
|
||||
'STATESERVER_OBJECT_GET_ZONE_COUNT_RESP': 2111,
|
||||
'STATESERVER_OBJECT_GET_ZONES_COUNT': 2112,
|
||||
'STATESERVER_OBJECT_GET_ZONES_COUNT_RESP': 2113,
|
||||
'STATESERVER_OBJECT_GET_CHILD_COUNT': 2114,
|
||||
'STATESERVER_OBJECT_GET_CHILD_COUNT_RESP': 2115,
|
||||
'STATESERVER_OBJECT_DELETE_ZONE': 2120,
|
||||
'STATESERVER_OBJECT_DELETE_ZONES': 2122,
|
||||
'STATESERVER_OBJECT_DELETE_CHILDREN': 2124,
|
||||
# DBSS-backed-object messages:
|
||||
'DBSS_OBJECT_ACTIVATE_WITH_DEFAULTS': 2200,
|
||||
'DBSS_OBJECT_ACTIVATE_WITH_DEFAULTS_OTHER': 2201,
|
||||
'DBSS_OBJECT_GET_ACTIVATED': 2207,
|
||||
'DBSS_OBJECT_GET_ACTIVATED_RESP': 2208,
|
||||
'DBSS_OBJECT_DELETE_FIELD_DISK': 2230,
|
||||
'DBSS_OBJECT_DELETE_FIELDS_DISK': 2231,
|
||||
'DBSS_OBJECT_DELETE_DISK': 2232,
|
||||
# State Server control messages:
|
||||
STATESERVER_CREATE_OBJECT_WITH_REQUIRED = 2000
|
||||
STATESERVER_CREATE_OBJECT_WITH_REQUIRED_OTHER = 2001
|
||||
STATESERVER_DELETE_AI_OBJECTS = 2009
|
||||
STATESERVER_OBJECT_GET_FIELD = 2010
|
||||
STATESERVER_OBJECT_GET_FIELD_RESP = 2011
|
||||
STATESERVER_OBJECT_GET_FIELDS = 2012
|
||||
STATESERVER_OBJECT_GET_FIELDS_RESP = 2013
|
||||
STATESERVER_OBJECT_GET_ALL = 2014
|
||||
STATESERVER_OBJECT_GET_ALL_RESP = 2015
|
||||
STATESERVER_OBJECT_SET_FIELD = 2020
|
||||
STATESERVER_OBJECT_SET_FIELDS = 2021
|
||||
STATESERVER_OBJECT_DELETE_FIELD_RAM = 2030
|
||||
STATESERVER_OBJECT_DELETE_FIELDS_RAM = 2031
|
||||
STATESERVER_OBJECT_DELETE_RAM = 2032
|
||||
STATESERVER_OBJECT_SET_LOCATION = 2040
|
||||
STATESERVER_OBJECT_CHANGING_LOCATION = 2041
|
||||
STATESERVER_OBJECT_ENTER_LOCATION_WITH_REQUIRED = 2042
|
||||
STATESERVER_OBJECT_ENTER_LOCATION_WITH_REQUIRED_OTHER = 2043
|
||||
STATESERVER_OBJECT_GET_LOCATION = 2044
|
||||
STATESERVER_OBJECT_GET_LOCATION_RESP = 2045
|
||||
STATESERVER_OBJECT_SET_AI = 2050
|
||||
STATESERVER_OBJECT_CHANGING_AI = 2051
|
||||
STATESERVER_OBJECT_ENTER_AI_WITH_REQUIRED = 2052
|
||||
STATESERVER_OBJECT_ENTER_AI_WITH_REQUIRED_OTHER = 2053
|
||||
STATESERVER_OBJECT_GET_AI = 2054
|
||||
STATESERVER_OBJECT_GET_AI_RESP = 2055
|
||||
STATESERVER_OBJECT_SET_OWNER = 2060
|
||||
STATESERVER_OBJECT_CHANGING_OWNER = 2061
|
||||
STATESERVER_OBJECT_ENTER_OWNER_WITH_REQUIRED = 2062
|
||||
STATESERVER_OBJECT_ENTER_OWNER_WITH_REQUIRED_OTHER = 2063
|
||||
STATESERVER_OBJECT_GET_OWNER = 2064
|
||||
STATESERVER_OBJECT_GET_OWNER_RESP = 2065
|
||||
STATESERVER_OBJECT_GET_ZONE_OBJECTS = 2100
|
||||
STATESERVER_OBJECT_GET_ZONES_OBJECTS = 2102
|
||||
STATESERVER_OBJECT_GET_CHILDREN = 2104
|
||||
STATESERVER_OBJECT_GET_ZONE_COUNT = 2110
|
||||
STATESERVER_OBJECT_GET_ZONE_COUNT_RESP = 2111
|
||||
STATESERVER_OBJECT_GET_ZONES_COUNT = 2112
|
||||
STATESERVER_OBJECT_GET_ZONES_COUNT_RESP = 2113
|
||||
STATESERVER_OBJECT_GET_CHILD_COUNT = 2114
|
||||
STATESERVER_OBJECT_GET_CHILD_COUNT_RESP = 2115
|
||||
STATESERVER_OBJECT_DELETE_ZONE = 2120
|
||||
STATESERVER_OBJECT_DELETE_ZONES = 2122
|
||||
STATESERVER_OBJECT_DELETE_CHILDREN = 2124
|
||||
# DBSS-backed-object messages:
|
||||
DBSS_OBJECT_ACTIVATE_WITH_DEFAULTS = 2200
|
||||
DBSS_OBJECT_ACTIVATE_WITH_DEFAULTS_OTHER = 2201
|
||||
DBSS_OBJECT_GET_ACTIVATED = 2207
|
||||
DBSS_OBJECT_GET_ACTIVATED_RESP = 2208
|
||||
DBSS_OBJECT_DELETE_FIELD_DISK = 2230
|
||||
DBSS_OBJECT_DELETE_FIELDS_DISK = 2231
|
||||
DBSS_OBJECT_DELETE_DISK = 2232
|
||||
|
||||
# Database Server control messages:
|
||||
'DBSERVER_CREATE_OBJECT': 3000,
|
||||
'DBSERVER_CREATE_OBJECT_RESP': 3001,
|
||||
'DBSERVER_OBJECT_GET_FIELD': 3010,
|
||||
'DBSERVER_OBJECT_GET_FIELD_RESP': 3011,
|
||||
'DBSERVER_OBJECT_GET_FIELDS': 3012,
|
||||
'DBSERVER_OBJECT_GET_FIELDS_RESP': 3013,
|
||||
'DBSERVER_OBJECT_GET_ALL': 3014,
|
||||
'DBSERVER_OBJECT_GET_ALL_RESP': 3015,
|
||||
'DBSERVER_OBJECT_SET_FIELD': 3020,
|
||||
'DBSERVER_OBJECT_SET_FIELDS': 3021,
|
||||
'DBSERVER_OBJECT_SET_FIELD_IF_EQUALS': 3022,
|
||||
'DBSERVER_OBJECT_SET_FIELD_IF_EQUALS_RESP': 3023,
|
||||
'DBSERVER_OBJECT_SET_FIELDS_IF_EQUALS': 3024,
|
||||
'DBSERVER_OBJECT_SET_FIELDS_IF_EQUALS_RESP': 3025,
|
||||
'DBSERVER_OBJECT_SET_FIELD_IF_EMPTY': 3026,
|
||||
'DBSERVER_OBJECT_SET_FIELD_IF_EMPTY_RESP': 3027,
|
||||
'DBSERVER_OBJECT_DELETE_FIELD': 3030,
|
||||
'DBSERVER_OBJECT_DELETE_FIELDS': 3031,
|
||||
'DBSERVER_OBJECT_DELETE': 3032,
|
||||
# Database Server control messages:
|
||||
DBSERVER_CREATE_OBJECT = 3000
|
||||
DBSERVER_CREATE_OBJECT_RESP = 3001
|
||||
DBSERVER_OBJECT_GET_FIELD = 3010
|
||||
DBSERVER_OBJECT_GET_FIELD_RESP = 3011
|
||||
DBSERVER_OBJECT_GET_FIELDS = 3012
|
||||
DBSERVER_OBJECT_GET_FIELDS_RESP = 3013
|
||||
DBSERVER_OBJECT_GET_ALL = 3014
|
||||
DBSERVER_OBJECT_GET_ALL_RESP = 3015
|
||||
DBSERVER_OBJECT_SET_FIELD = 3020
|
||||
DBSERVER_OBJECT_SET_FIELDS = 3021
|
||||
DBSERVER_OBJECT_SET_FIELD_IF_EQUALS = 3022
|
||||
DBSERVER_OBJECT_SET_FIELD_IF_EQUALS_RESP = 3023
|
||||
DBSERVER_OBJECT_SET_FIELDS_IF_EQUALS = 3024
|
||||
DBSERVER_OBJECT_SET_FIELDS_IF_EQUALS_RESP = 3025
|
||||
DBSERVER_OBJECT_SET_FIELD_IF_EMPTY = 3026
|
||||
DBSERVER_OBJECT_SET_FIELD_IF_EMPTY_RESP = 3027
|
||||
DBSERVER_OBJECT_DELETE_FIELD = 3030
|
||||
DBSERVER_OBJECT_DELETE_FIELDS = 3031
|
||||
DBSERVER_OBJECT_DELETE = 3032
|
||||
|
||||
# Client Agent control messages:
|
||||
'CLIENTAGENT_SET_STATE': 1000,
|
||||
'CLIENTAGENT_SET_CLIENT_ID': 1001,
|
||||
'CLIENTAGENT_SEND_DATAGRAM': 1002,
|
||||
'CLIENTAGENT_EJECT': 1004,
|
||||
'CLIENTAGENT_DROP': 1005,
|
||||
'CLIENTAGENT_GET_NETWORK_ADDRESS': 1006,
|
||||
'CLIENTAGENT_GET_NETWORK_ADDRESS_RESP': 1007,
|
||||
'CLIENTAGENT_DECLARE_OBJECT': 1010,
|
||||
'CLIENTAGENT_UNDECLARE_OBJECT': 1011,
|
||||
'CLIENTAGENT_ADD_SESSION_OBJECT': 1012,
|
||||
'CLIENTAGENT_REMOVE_SESSION_OBJECT': 1013,
|
||||
'CLIENTAGENT_SET_FIELDS_SENDABLE': 1014,
|
||||
'CLIENTAGENT_OPEN_CHANNEL': 1100,
|
||||
'CLIENTAGENT_CLOSE_CHANNEL': 1101,
|
||||
'CLIENTAGENT_ADD_POST_REMOVE': 1110,
|
||||
'CLIENTAGENT_CLEAR_POST_REMOVES': 1111,
|
||||
'CLIENTAGENT_ADD_INTEREST': 1200,
|
||||
'CLIENTAGENT_ADD_INTEREST_MULTIPLE': 1201,
|
||||
'CLIENTAGENT_REMOVE_INTEREST': 1203,
|
||||
}
|
||||
# Client Agent control messages:
|
||||
CLIENTAGENT_SET_STATE = 1000
|
||||
CLIENTAGENT_SET_CLIENT_ID = 1001
|
||||
CLIENTAGENT_SEND_DATAGRAM = 1002
|
||||
CLIENTAGENT_EJECT = 1004
|
||||
CLIENTAGENT_DROP = 1005
|
||||
CLIENTAGENT_GET_NETWORK_ADDRESS = 1006
|
||||
CLIENTAGENT_GET_NETWORK_ADDRESS_RESP = 1007
|
||||
CLIENTAGENT_DECLARE_OBJECT = 1010
|
||||
CLIENTAGENT_UNDECLARE_OBJECT = 1011
|
||||
CLIENTAGENT_ADD_SESSION_OBJECT = 1012
|
||||
CLIENTAGENT_REMOVE_SESSION_OBJECT = 1013
|
||||
CLIENTAGENT_SET_FIELDS_SENDABLE = 1014
|
||||
CLIENTAGENT_OPEN_CHANNEL = 1100
|
||||
CLIENTAGENT_CLOSE_CHANNEL = 1101
|
||||
CLIENTAGENT_ADD_POST_REMOVE = 1110
|
||||
CLIENTAGENT_CLEAR_POST_REMOVES = 1111
|
||||
CLIENTAGENT_ADD_INTEREST = 1200
|
||||
CLIENTAGENT_ADD_INTEREST_MULTIPLE = 1201
|
||||
CLIENTAGENT_REMOVE_INTEREST = 1203
|
||||
else:
|
||||
MsgName2Id = {
|
||||
# 2 new params: passwd, char bool 0/1 1 = new account
|
||||
# 2 new return values: 129 = not found, 12 = bad passwd,
|
||||
'CLIENT_LOGIN': 1,
|
||||
'CLIENT_LOGIN_RESP': 2,
|
||||
'CLIENT_GET_AVATARS': 3,
|
||||
# Sent by the server when it is dropping the connection deliberately.
|
||||
'CLIENT_GO_GET_LOST': 4,
|
||||
'CLIENT_GET_AVATARS_RESP': 5,
|
||||
'CLIENT_CREATE_AVATAR': 6,
|
||||
'CLIENT_CREATE_AVATAR_RESP': 7,
|
||||
'CLIENT_GET_FRIEND_LIST': 10,
|
||||
'CLIENT_GET_FRIEND_LIST_RESP': 11,
|
||||
'CLIENT_GET_AVATAR_DETAILS': 14,
|
||||
'CLIENT_GET_AVATAR_DETAILS_RESP': 15,
|
||||
'CLIENT_LOGIN_2': 16,
|
||||
'CLIENT_LOGIN_2_RESP': 17,
|
||||
# 2 new params: passwd, char bool 0/1 1 = new account
|
||||
# 2 new return values: 129 = not found, 12 = bad passwd,
|
||||
CLIENT_LOGIN = 1
|
||||
CLIENT_LOGIN_RESP = 2
|
||||
CLIENT_GET_AVATARS = 3
|
||||
# Sent by the server when it is dropping the connection deliberately.
|
||||
CLIENT_GO_GET_LOST = 4
|
||||
CLIENT_GET_AVATARS_RESP = 5
|
||||
CLIENT_CREATE_AVATAR = 6
|
||||
CLIENT_CREATE_AVATAR_RESP = 7
|
||||
CLIENT_GET_FRIEND_LIST = 10
|
||||
CLIENT_GET_FRIEND_LIST_RESP = 11
|
||||
CLIENT_GET_AVATAR_DETAILS = 14
|
||||
CLIENT_GET_AVATAR_DETAILS_RESP = 15
|
||||
CLIENT_LOGIN_2 = 16
|
||||
CLIENT_LOGIN_2_RESP = 17
|
||||
|
||||
'CLIENT_OBJECT_UPDATE_FIELD': 24,
|
||||
'CLIENT_OBJECT_UPDATE_FIELD_RESP': 24,
|
||||
'CLIENT_OBJECT_DISABLE': 25,
|
||||
'CLIENT_OBJECT_DISABLE_RESP': 25,
|
||||
'CLIENT_OBJECT_DISABLE_OWNER': 26,
|
||||
'CLIENT_OBJECT_DISABLE_OWNER_RESP': 26,
|
||||
'CLIENT_OBJECT_DELETE': 27,
|
||||
'CLIENT_OBJECT_DELETE_RESP': 27,
|
||||
'CLIENT_SET_ZONE_CMU': 29,
|
||||
'CLIENT_REMOVE_ZONE': 30,
|
||||
'CLIENT_SET_AVATAR': 32,
|
||||
'CLIENT_CREATE_OBJECT_REQUIRED': 34,
|
||||
'CLIENT_CREATE_OBJECT_REQUIRED_RESP': 34,
|
||||
'CLIENT_CREATE_OBJECT_REQUIRED_OTHER': 35,
|
||||
'CLIENT_CREATE_OBJECT_REQUIRED_OTHER_RESP': 35,
|
||||
'CLIENT_CREATE_OBJECT_REQUIRED_OTHER_OWNER': 36,
|
||||
'CLIENT_CREATE_OBJECT_REQUIRED_OTHER_OWNER_RESP':36,
|
||||
CLIENT_OBJECT_UPDATE_FIELD = 24
|
||||
CLIENT_OBJECT_UPDATE_FIELD_RESP = 24
|
||||
CLIENT_OBJECT_DISABLE = 25
|
||||
CLIENT_OBJECT_DISABLE_RESP = 25
|
||||
CLIENT_OBJECT_DISABLE_OWNER = 26
|
||||
CLIENT_OBJECT_DISABLE_OWNER_RESP = 26
|
||||
CLIENT_OBJECT_DELETE = 27
|
||||
CLIENT_OBJECT_DELETE_RESP = 27
|
||||
CLIENT_SET_ZONE_CMU = 29
|
||||
CLIENT_REMOVE_ZONE = 30
|
||||
CLIENT_SET_AVATAR = 32
|
||||
CLIENT_CREATE_OBJECT_REQUIRED = 34
|
||||
CLIENT_CREATE_OBJECT_REQUIRED_RESP = 34
|
||||
CLIENT_CREATE_OBJECT_REQUIRED_OTHER = 35
|
||||
CLIENT_CREATE_OBJECT_REQUIRED_OTHER_RESP = 35
|
||||
CLIENT_CREATE_OBJECT_REQUIRED_OTHER_OWNER = 36
|
||||
CLIENT_CREATE_OBJECT_REQUIRED_OTHER_OWNER_RESP = 36
|
||||
|
||||
'CLIENT_REQUEST_GENERATES': 36,
|
||||
CLIENT_REQUEST_GENERATES = 36
|
||||
|
||||
'CLIENT_DISCONNECT': 37,
|
||||
CLIENT_DISCONNECT = 37
|
||||
|
||||
'CLIENT_GET_STATE_RESP': 47,
|
||||
'CLIENT_DONE_INTEREST_RESP': 48,
|
||||
CLIENT_GET_STATE_RESP = 47
|
||||
CLIENT_DONE_INTEREST_RESP = 48
|
||||
|
||||
'CLIENT_DELETE_AVATAR': 49,
|
||||
CLIENT_DELETE_AVATAR = 49
|
||||
|
||||
'CLIENT_DELETE_AVATAR_RESP': 5,
|
||||
CLIENT_DELETE_AVATAR_RESP = 5
|
||||
|
||||
'CLIENT_HEARTBEAT': 52,
|
||||
'CLIENT_FRIEND_ONLINE': 53,
|
||||
'CLIENT_FRIEND_OFFLINE': 54,
|
||||
'CLIENT_REMOVE_FRIEND': 56,
|
||||
CLIENT_HEARTBEAT = 52
|
||||
CLIENT_FRIEND_ONLINE = 53
|
||||
CLIENT_FRIEND_OFFLINE = 54
|
||||
CLIENT_REMOVE_FRIEND = 56
|
||||
|
||||
'CLIENT_CHANGE_PASSWORD': 65,
|
||||
CLIENT_CHANGE_PASSWORD = 65
|
||||
|
||||
'CLIENT_SET_NAME_PATTERN': 67,
|
||||
'CLIENT_SET_NAME_PATTERN_ANSWER': 68,
|
||||
CLIENT_SET_NAME_PATTERN = 67
|
||||
CLIENT_SET_NAME_PATTERN_ANSWER = 68
|
||||
|
||||
'CLIENT_SET_WISHNAME': 70,
|
||||
'CLIENT_SET_WISHNAME_RESP': 71,
|
||||
'CLIENT_SET_WISHNAME_CLEAR': 72,
|
||||
'CLIENT_SET_SECURITY': 73,
|
||||
CLIENT_SET_WISHNAME = 70
|
||||
CLIENT_SET_WISHNAME_RESP = 71
|
||||
CLIENT_SET_WISHNAME_CLEAR = 72
|
||||
CLIENT_SET_SECURITY = 73
|
||||
|
||||
'CLIENT_SET_DOID_RANGE': 74,
|
||||
CLIENT_SET_DOID_RANGE = 74
|
||||
|
||||
'CLIENT_GET_AVATARS_RESP2': 75,
|
||||
'CLIENT_CREATE_AVATAR2': 76,
|
||||
'CLIENT_SYSTEM_MESSAGE': 78,
|
||||
'CLIENT_SET_AVTYPE': 80,
|
||||
CLIENT_GET_AVATARS_RESP2 = 75
|
||||
CLIENT_CREATE_AVATAR2 = 76
|
||||
CLIENT_SYSTEM_MESSAGE = 78
|
||||
CLIENT_SET_AVTYPE = 80
|
||||
|
||||
'CLIENT_GET_PET_DETAILS': 81,
|
||||
'CLIENT_GET_PET_DETAILS_RESP': 82,
|
||||
CLIENT_GET_PET_DETAILS = 81
|
||||
CLIENT_GET_PET_DETAILS_RESP = 82
|
||||
|
||||
'CLIENT_ADD_INTEREST': 97,
|
||||
'CLIENT_REMOVE_INTEREST': 99,
|
||||
'CLIENT_OBJECT_LOCATION': 102,
|
||||
CLIENT_ADD_INTEREST = 97
|
||||
CLIENT_REMOVE_INTEREST = 99
|
||||
CLIENT_OBJECT_LOCATION = 102
|
||||
|
||||
'CLIENT_LOGIN_3': 111,
|
||||
'CLIENT_LOGIN_3_RESP': 110,
|
||||
CLIENT_LOGIN_3 = 111
|
||||
CLIENT_LOGIN_3_RESP = 110
|
||||
|
||||
'CLIENT_GET_FRIEND_LIST_EXTENDED': 115,
|
||||
'CLIENT_GET_FRIEND_LIST_EXTENDED_RESP': 116,
|
||||
CLIENT_GET_FRIEND_LIST_EXTENDED = 115
|
||||
CLIENT_GET_FRIEND_LIST_EXTENDED_RESP = 116
|
||||
|
||||
'CLIENT_SET_FIELD_SENDABLE': 120,
|
||||
CLIENT_SET_FIELD_SENDABLE = 120
|
||||
|
||||
'CLIENT_SYSTEMMESSAGE_AKNOWLEDGE': 123,
|
||||
'CLIENT_CHANGE_GENERATE_ORDER': 124,
|
||||
CLIENT_SYSTEMMESSAGE_AKNOWLEDGE = 123
|
||||
CLIENT_CHANGE_GENERATE_ORDER = 124
|
||||
|
||||
# new toontown specific login message, adds last logged in, and if child account has parent acount
|
||||
'CLIENT_LOGIN_TOONTOWN': 125,
|
||||
'CLIENT_LOGIN_TOONTOWN_RESP': 126,
|
||||
# new toontown specific login message, adds last logged in, and if child account has parent acount
|
||||
CLIENT_LOGIN_TOONTOWN = 125
|
||||
CLIENT_LOGIN_TOONTOWN_RESP = 126
|
||||
|
||||
|
||||
|
||||
'STATESERVER_OBJECT_GENERATE_WITH_REQUIRED': 2001,
|
||||
'STATESERVER_OBJECT_GENERATE_WITH_REQUIRED_OTHER': 2003,
|
||||
'STATESERVER_OBJECT_UPDATE_FIELD': 2004,
|
||||
'STATESERVER_OBJECT_CREATE_WITH_REQUIRED_CONTEXT': 2050,
|
||||
'STATESERVER_OBJECT_CREATE_WITH_REQUIR_OTHER_CONTEXT': 2051,
|
||||
'STATESERVER_BOUNCE_MESSAGE': 2086,
|
||||
}
|
||||
STATESERVER_OBJECT_GENERATE_WITH_REQUIRED = 2001
|
||||
STATESERVER_OBJECT_GENERATE_WITH_REQUIRED_OTHER = 2003
|
||||
STATESERVER_OBJECT_UPDATE_FIELD = 2004
|
||||
STATESERVER_OBJECT_CREATE_WITH_REQUIRED_CONTEXT = 2050
|
||||
STATESERVER_OBJECT_CREATE_WITH_REQUIR_OTHER_CONTEXT = 2051
|
||||
STATESERVER_BOUNCE_MESSAGE = 2086
|
||||
|
||||
MsgName2Id = {name: value for name, value in globals().items() if isinstance(value, int)}
|
||||
|
||||
# create id->name table for debugging
|
||||
MsgId2Names = invertDictLossless(MsgName2Id)
|
||||
|
|
@ -250,7 +250,7 @@ MsgId2Names = invertDictLossless(MsgName2Id)
|
|||
globals().update(MsgName2Id)
|
||||
|
||||
# These messages are ignored when the client is headed to the quiet zone
|
||||
QUIET_ZONE_IGNORED_LIST = [
|
||||
QUIET_ZONE_IGNORED_LIST: list[int] = [
|
||||
|
||||
# We mustn't ignore updates, because some updates for localToon
|
||||
# are always important.
|
||||
|
|
|
|||
|
|
@ -7,28 +7,25 @@ from panda3d.core import ConfigVariableBool
|
|||
|
||||
from direct.showbase.PythonUtil import invertDictLossless
|
||||
|
||||
MsgName2Id = {
|
||||
'SET_DOID_RANGE_CMU' : 9001,
|
||||
'CLIENT_OBJECT_GENERATE_CMU' : 9002,
|
||||
'OBJECT_GENERATE_CMU' : 9003,
|
||||
'OBJECT_UPDATE_FIELD_CMU' : 9004,
|
||||
'OBJECT_DISABLE_CMU' : 9005,
|
||||
'OBJECT_DELETE_CMU' : 9006,
|
||||
'REQUEST_GENERATES_CMU' : 9007,
|
||||
'CLIENT_DISCONNECT_CMU' : 9008,
|
||||
'CLIENT_SET_INTEREST_CMU' : 9009,
|
||||
'OBJECT_SET_ZONE_CMU' : 9010,
|
||||
'CLIENT_HEARTBEAT_CMU' : 9011,
|
||||
'CLIENT_OBJECT_UPDATE_FIELD_TARGETED_CMU' : 9011,
|
||||
}
|
||||
SET_DOID_RANGE_CMU = 9001
|
||||
CLIENT_OBJECT_GENERATE_CMU = 9002
|
||||
OBJECT_GENERATE_CMU = 9003
|
||||
OBJECT_UPDATE_FIELD_CMU = 9004
|
||||
OBJECT_DISABLE_CMU = 9005
|
||||
OBJECT_DELETE_CMU = 9006
|
||||
REQUEST_GENERATES_CMU = 9007
|
||||
CLIENT_DISCONNECT_CMU = 9008
|
||||
CLIENT_SET_INTEREST_CMU = 9009
|
||||
OBJECT_SET_ZONE_CMU = 9010
|
||||
CLIENT_HEARTBEAT_CMU = 9011
|
||||
CLIENT_OBJECT_UPDATE_FIELD_TARGETED_CMU = 9011
|
||||
|
||||
if ConfigVariableBool('astron-support', True):
|
||||
MsgName2Id['CLIENT_OBJECT_UPDATE_FIELD'] = 120 # Matches MsgTypes.CLIENT_OBJECT_SET_FIELD
|
||||
CLIENT_OBJECT_UPDATE_FIELD = 120 # Matches MsgTypes.CLIENT_OBJECT_SET_FIELD
|
||||
else:
|
||||
MsgName2Id['CLIENT_OBJECT_UPDATE_FIELD'] = 24 # Matches MsgTypes.CLIENT_OBJECT_UPDATE_FIELD
|
||||
CLIENT_OBJECT_UPDATE_FIELD = 24 # Matches MsgTypes.CLIENT_OBJECT_UPDATE_FIELD
|
||||
|
||||
MsgName2Id = {name: value for name, value in globals().items() if isinstance(value, int)}
|
||||
|
||||
# create id->name table for debugging
|
||||
MsgId2Names = invertDictLossless(MsgName2Id)
|
||||
|
||||
# put msg names in module scope, assigned to msg value
|
||||
globals().update(MsgName2Id)
|
||||
|
|
|
|||
|
|
@ -5,6 +5,8 @@ Note:
|
|||
existing code. New code should use the :mod:`.FSM` module instead.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
__all__ = ['ClassicFSM']
|
||||
|
||||
from direct.directnotify.DirectNotifyGlobal import directNotify
|
||||
|
|
@ -13,7 +15,7 @@ from direct.showbase.MessengerGlobal import messenger
|
|||
import weakref
|
||||
|
||||
if __debug__:
|
||||
_debugFsms = {}
|
||||
_debugFsms: dict[str, weakref.ref] = {}
|
||||
|
||||
def printDebugFsmList():
|
||||
for k in sorted(_debugFsms.keys()):
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
"""State module: contains State class"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
__all__ = ['State']
|
||||
|
||||
from direct.directnotify.DirectNotifyGlobal import directNotify
|
||||
|
|
@ -18,7 +20,7 @@ class State(DirectObject):
|
|||
# should not cause any leaks.
|
||||
if __debug__:
|
||||
import weakref
|
||||
States = weakref.WeakKeyDictionary()
|
||||
States: weakref.WeakKeyDictionary[State, int] = weakref.WeakKeyDictionary()
|
||||
|
||||
@classmethod
|
||||
def replaceMethod(cls, oldFunction, newFunction):
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
# classes for event-driven programming
|
||||
# http://en.wikipedia.org/wiki/Event-driven_programming
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
__all__ = ['StateVar', 'FunctionCall', 'EnterExit', 'Pulse', 'EventPulse',
|
||||
'EventArgument', ]
|
||||
|
||||
|
|
@ -46,11 +48,6 @@ class PushesStateChanges:
|
|||
for subscriber in self._subscribers:
|
||||
subscriber._recvStatePush(self)
|
||||
|
||||
if __debug__:
|
||||
psc = PushesStateChanges(0)
|
||||
assert psc.getState() == 0
|
||||
psc.destroy()
|
||||
del psc
|
||||
|
||||
class ReceivesStateChanges:
|
||||
# base class for objects that subscribe to state changes from PushesStateChanges objects
|
||||
|
|
@ -83,10 +80,6 @@ class ReceivesStateChanges:
|
|||
def _recvStatePush(self, source):
|
||||
pass
|
||||
|
||||
if __debug__:
|
||||
rsc = ReceivesStateChanges(None)
|
||||
rsc.destroy()
|
||||
del rsc
|
||||
|
||||
class StateVar(PushesStateChanges):
|
||||
# coder-friendly object that allows values to be set on it and pushes those values
|
||||
|
|
@ -97,13 +90,6 @@ class StateVar(PushesStateChanges):
|
|||
def get(self):
|
||||
return PushesStateChanges.getState(self)
|
||||
|
||||
if __debug__:
|
||||
sv = StateVar(0)
|
||||
assert sv.get() == 0
|
||||
sv.set(1)
|
||||
assert sv.get() == 1
|
||||
sv.destroy()
|
||||
del sv
|
||||
|
||||
class StateChangeNode(PushesStateChanges, ReceivesStateChanges):
|
||||
# base class that can be used to create a state-change notification chain
|
||||
|
|
@ -120,31 +106,6 @@ class StateChangeNode(PushesStateChanges, ReceivesStateChanges):
|
|||
# got a state push, apply new state to self
|
||||
self._handlePotentialStateChange(source._value)
|
||||
|
||||
if __debug__:
|
||||
sv = StateVar(0)
|
||||
assert sv.get() == 0
|
||||
scn = StateChangeNode(sv)
|
||||
assert scn.getState() == 0
|
||||
sv.set(1)
|
||||
assert sv.get() == 1
|
||||
assert scn.getState() == 1
|
||||
scn2 = StateChangeNode(scn)
|
||||
assert scn2.getState() == 1
|
||||
sv.set(2)
|
||||
assert scn2.getState() == 2
|
||||
scn3 = StateChangeNode(scn)
|
||||
assert scn3.getState() == 2
|
||||
sv.set(3)
|
||||
assert scn2.getState() == 3
|
||||
assert scn3.getState() == 3
|
||||
scn3.destroy()
|
||||
scn2.destroy()
|
||||
scn.destroy()
|
||||
sv.destroy()
|
||||
del scn3
|
||||
del scn2
|
||||
del scn
|
||||
del sv
|
||||
|
||||
class ReceivesMultipleStateChanges:
|
||||
# base class for objects that subscribe to state changes from multiple PushesStateChanges
|
||||
|
|
@ -179,15 +140,6 @@ class ReceivesMultipleStateChanges:
|
|||
def _recvMultiStatePush(self, key, source):
|
||||
pass
|
||||
|
||||
if __debug__:
|
||||
rsc = ReceivesMultipleStateChanges()
|
||||
sv = StateVar(0)
|
||||
sv2 = StateVar('b')
|
||||
rsc._subscribeTo(sv, 'a')
|
||||
rsc._subscribeTo(sv2, 2)
|
||||
rsc._unsubscribe('a')
|
||||
rsc.destroy()
|
||||
del rsc
|
||||
|
||||
class FunctionCall(ReceivesMultipleStateChanges, PushesStateChanges):
|
||||
# calls func with provided args whenever arguments' state changes
|
||||
|
|
@ -249,47 +201,6 @@ class FunctionCall(ReceivesMultipleStateChanges, PushesStateChanges):
|
|||
self._func(*self._bakedArgs, **self._bakedKargs)
|
||||
PushesStateChanges._handleStateChange(self)
|
||||
|
||||
if __debug__:
|
||||
l = []
|
||||
def handler1(value, l=l):
|
||||
l.append(value)
|
||||
assert not l
|
||||
sv = StateVar(0)
|
||||
fc = FunctionCall(handler1, sv)
|
||||
assert not l
|
||||
fc.pushCurrentState()
|
||||
assert l == [0,]
|
||||
sv.set(1)
|
||||
assert l == [0,1,]
|
||||
sv.set(2)
|
||||
assert l == [0,1,2,]
|
||||
fc.destroy()
|
||||
sv.destroy()
|
||||
del fc
|
||||
del sv
|
||||
del handler1
|
||||
del l
|
||||
|
||||
l = []
|
||||
def handler2(value, kDummy=None, kValue=None, l=l):
|
||||
l.append((value, kValue))
|
||||
assert not l
|
||||
sv = StateVar(0)
|
||||
ksv = StateVar('a')
|
||||
fc = FunctionCall(handler2, sv, kValue=ksv)
|
||||
assert not l
|
||||
fc.pushCurrentState()
|
||||
assert l == [(0,'a',),]
|
||||
sv.set(1)
|
||||
assert l == [(0,'a'),(1,'a'),]
|
||||
ksv.set('b')
|
||||
assert l == [(0,'a'),(1,'a'),(1,'b'),]
|
||||
fc.destroy()
|
||||
sv.destroy()
|
||||
del fc
|
||||
del sv
|
||||
del handler2
|
||||
del l
|
||||
|
||||
class EnterExit(StateChangeNode):
|
||||
# call enterFunc when our state becomes true, exitFunc when it becomes false
|
||||
|
|
@ -314,33 +225,6 @@ class EnterExit(StateChangeNode):
|
|||
self._exitFunc()
|
||||
StateChangeNode._handleStateChange(self)
|
||||
|
||||
if __debug__:
|
||||
l = []
|
||||
def enter(l=l):
|
||||
l.append(1)
|
||||
def exit(l=l):
|
||||
l.append(0)
|
||||
sv = StateVar(0)
|
||||
ee = EnterExit(sv, enter, exit)
|
||||
sv.set(0)
|
||||
assert not l
|
||||
sv.set(1)
|
||||
assert l == [1,]
|
||||
sv.set(2)
|
||||
assert l == [1,]
|
||||
sv.set(0)
|
||||
assert l == [1,0,]
|
||||
sv.set(True)
|
||||
assert l == [1,0,1,]
|
||||
sv.set(False)
|
||||
assert l == [1,0,1,0,]
|
||||
ee.destroy()
|
||||
sv.destroy()
|
||||
del ee
|
||||
del sv
|
||||
del enter
|
||||
del exit
|
||||
del l
|
||||
|
||||
class Pulse(PushesStateChanges):
|
||||
# changes state to True then immediately to False whenever sendPulse is called
|
||||
|
|
@ -351,25 +235,6 @@ class Pulse(PushesStateChanges):
|
|||
self._handlePotentialStateChange(True)
|
||||
self._handlePotentialStateChange(False)
|
||||
|
||||
if __debug__:
|
||||
l = []
|
||||
def handler(value, l=l):
|
||||
l.append(value)
|
||||
p = Pulse()
|
||||
fc = FunctionCall(handler, p)
|
||||
assert not l
|
||||
fc.pushCurrentState()
|
||||
assert l == [False, ]
|
||||
p.sendPulse()
|
||||
assert l == [False, True, False, ]
|
||||
p.sendPulse()
|
||||
assert l == [False, True, False, True, False, ]
|
||||
fc.destroy()
|
||||
p.destroy()
|
||||
del fc
|
||||
del p
|
||||
del l
|
||||
del handler
|
||||
|
||||
class EventPulse(Pulse, DirectObject):
|
||||
# sends a True-False "pulse" whenever a specific messenger message is sent
|
||||
|
|
@ -381,6 +246,7 @@ class EventPulse(Pulse, DirectObject):
|
|||
self.ignoreAll()
|
||||
Pulse.destroy(self)
|
||||
|
||||
|
||||
class EventArgument(PushesStateChanges, DirectObject):
|
||||
# tracks a particular argument to a particular messenger event
|
||||
def __init__(self, event, index=0):
|
||||
|
|
@ -396,6 +262,7 @@ class EventArgument(PushesStateChanges, DirectObject):
|
|||
def _handleEvent(self, *args):
|
||||
self._handlePotentialStateChange(args[self._index])
|
||||
|
||||
|
||||
class AttrSetter(StateChangeNode):
|
||||
def __init__(self, source, object, attrName):
|
||||
self._object = object
|
||||
|
|
@ -406,19 +273,3 @@ class AttrSetter(StateChangeNode):
|
|||
def _handleStateChange(self):
|
||||
setattr(self._object, self._attrName, self._value)
|
||||
StateChangeNode._handleStateChange(self)
|
||||
|
||||
if __debug__:
|
||||
from direct.showbase.PythonUtil import ScratchPad
|
||||
o = ScratchPad()
|
||||
svar = StateVar(0)
|
||||
aset = AttrSetter(svar, o, 'testAttr')
|
||||
assert hasattr(o, 'testAttr')
|
||||
assert o.testAttr == 0
|
||||
svar.set('red')
|
||||
assert o.testAttr == 'red'
|
||||
aset.destroy()
|
||||
svar.destroy()
|
||||
o.destroy()
|
||||
del aset
|
||||
del svar
|
||||
del o
|
||||
|
|
|
|||
|
|
@ -4,6 +4,8 @@ See the :ref:`directdialog` page in the programming manual for a more
|
|||
in-depth explanation and an example of how to use this class.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
__all__ = [
|
||||
'findDialog', 'cleanupDialog', 'DirectDialog', 'OkDialog',
|
||||
'OkCancelDialog', 'YesNoDialog', 'YesNoCancelDialog', 'RetryCancelDialog',
|
||||
|
|
@ -45,7 +47,7 @@ def cleanupDialog(uniqueName):
|
|||
|
||||
class DirectDialog(DirectFrame):
|
||||
|
||||
AllDialogs = {}
|
||||
AllDialogs: dict[str, DirectDialog] = {}
|
||||
PanelIndex = 0
|
||||
|
||||
def __init__(self, parent=None, **kw):
|
||||
|
|
|
|||
|
|
@ -84,6 +84,8 @@ Code overview:
|
|||
see if any keywords are left unused. If so, an error is raised.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
__all__ = ['DirectGuiBase', 'DirectGuiWidget']
|
||||
|
||||
|
||||
|
|
@ -616,9 +618,7 @@ class DirectGuiBase(DirectObject.DirectObject):
|
|||
|
||||
def components(self):
|
||||
# Return a list of all components.
|
||||
names = list(self.__componentInfo.keys())
|
||||
names.sort()
|
||||
return names
|
||||
return sorted(self.__componentInfo)
|
||||
|
||||
def hascomponent(self, component):
|
||||
return component in self.__componentInfo
|
||||
|
|
@ -682,7 +682,7 @@ class DirectGuiWidget(DirectGuiBase, NodePath):
|
|||
else:
|
||||
inactiveInitState = DGG.DISABLED
|
||||
|
||||
guiDict = {}
|
||||
guiDict: dict[str, DirectGuiWidget] = {}
|
||||
|
||||
def __init__(self, parent = None, **kw):
|
||||
# Direct gui widgets are node paths
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ Global definitions used by Direct Gui Classes and handy constants
|
|||
that can be used during widget construction
|
||||
"""
|
||||
|
||||
__all__ = []
|
||||
__all__ = ()
|
||||
|
||||
from panda3d.core import (
|
||||
KeyboardButton,
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
"""FunctionInterval module: contains the FunctionInterval class"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
__all__ = ['FunctionInterval', 'EventInterval', 'AcceptInterval', 'IgnoreInterval', 'ParentInterval', 'WrtParentInterval', 'PosInterval', 'HprInterval', 'ScaleInterval', 'PosHprInterval', 'HprScaleInterval', 'PosHprScaleInterval', 'Func', 'Wait']
|
||||
|
||||
from panda3d.direct import WaitInterval
|
||||
|
|
@ -23,7 +25,7 @@ class FunctionInterval(Interval.Interval):
|
|||
# should not cause any leaks.
|
||||
if __debug__:
|
||||
import weakref
|
||||
FunctionIntervals = weakref.WeakKeyDictionary()
|
||||
FunctionIntervals: weakref.WeakKeyDictionary[FunctionInterval, int] = weakref.WeakKeyDictionary()
|
||||
|
||||
@classmethod
|
||||
def replaceMethod(cls, oldFunction, newFunction):
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
"""Undocumented Module"""
|
||||
|
||||
__all__ = []
|
||||
__all__ = ()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
|
@ -26,7 +26,7 @@ if __name__ == "__main__":
|
|||
base = ShowBase()
|
||||
|
||||
boat = base.loader.loadModel('models/misc/smiley')
|
||||
boat.reparentTo(render)
|
||||
boat.reparentTo(base.render)
|
||||
|
||||
donald = Actor()
|
||||
donald.loadModel("phase_6/models/char/donald-wheel-1000")
|
||||
|
|
@ -34,7 +34,7 @@ if __name__ == "__main__":
|
|||
donald.reparentTo(boat)
|
||||
|
||||
dock = base.loader.loadModel('models/misc/smiley')
|
||||
dock.reparentTo(render)
|
||||
dock.reparentTo(base.render)
|
||||
|
||||
sound = base.loader.loadSfx('phase_6/audio/sfx/SZ_DD_waterlap.mp3')
|
||||
foghorn = base.loader.loadSfx('phase_6/audio/sfx/SZ_DD_foghorn.mp3')
|
||||
|
|
@ -93,7 +93,7 @@ if __name__ == "__main__":
|
|||
foghornSound = SoundInterval(foghorn, name='foghorn')
|
||||
soundTrack2 = Track([(foghornStartTime, foghornSound)], 'soundtrack2')
|
||||
|
||||
mtrack = MultiTrack([boatTrack, dockTrack, soundTrack, soundTrack2, waterEventTrack,
|
||||
mtrack = MultiTrack([boatTrack, dockTrack, soundTrack, soundTrack2, waterEventTrack, # type: ignore[name-defined]
|
||||
donaldSteerTrack])
|
||||
# Print out MultiTrack parameters
|
||||
print(mtrack)
|
||||
|
|
@ -175,11 +175,11 @@ if __name__ == "__main__":
|
|||
# Just to take time
|
||||
i2 = LerpPosInterval(base.camera, 2.0, Point3(0, 10, 5))
|
||||
# This will be relative to end of camera move
|
||||
i3 = FunctionInterval(printPreviousEnd)
|
||||
i3 = FunctionInterval(printPreviousEnd) # type: ignore[assignment]
|
||||
# Just to take time
|
||||
i4 = LerpPosInterval(base.camera, 2.0, Point3(0, 0, 5))
|
||||
# This will be relative to the start of the camera move
|
||||
i5 = FunctionInterval(printPreviousStart)
|
||||
i5 = FunctionInterval(printPreviousStart) # type: ignore[assignment]
|
||||
# This will be relative to track start
|
||||
i6 = FunctionInterval(printTrackStart)
|
||||
# This will print some arguments
|
||||
|
|
|
|||
|
|
@ -116,9 +116,7 @@ class HotKeyPanel(ScrolledPanel):
|
|||
|
||||
def updateUI(self):
|
||||
vbox = wx.BoxSizer(wx.VERTICAL)
|
||||
keys = list(base.direct.hotKeyMap.keys())
|
||||
keys.sort()
|
||||
for key in keys:
|
||||
for key in sorted(base.direct.hotKeyMap):
|
||||
keyDesc = base.direct.hotKeyMap[key]
|
||||
itemPanel = wx.Panel(self)
|
||||
sizer = wx.BoxSizer(wx.HORIZONTAL)
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ if __name__ == '__main__':
|
|||
from direct.showbase.ShowBase import ShowBase
|
||||
base = ShowBase()
|
||||
|
||||
base.le = LevelEditor.LevelEditor()
|
||||
base.le = LevelEditor.LevelEditor() # type: ignore[attr-defined]
|
||||
# You should define LevelEditor instance as
|
||||
# base.le so it can be reached in global scope
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
from panda3d.core import Point3, VBase3
|
||||
from direct.showbase.ShowBaseGlobal import base
|
||||
|
||||
if hasattr(base, 'le'):
|
||||
objectMgr = base.le.objectMgr
|
||||
|
|
@ -6,7 +7,7 @@ if hasattr(base, 'le'):
|
|||
ui.sceneGraphUI.reset()
|
||||
|
||||
else:
|
||||
objectMgr = base.objectMgr
|
||||
objectMgr = base.objectMgr # type: ignore[attr-defined]
|
||||
# temporary place holder for nodepath
|
||||
objects = {}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
from __future__ import annotations
|
||||
|
||||
from panda3d.core import (
|
||||
BoundingVolume,
|
||||
ColorBlendAttrib,
|
||||
|
|
@ -92,7 +94,7 @@ class MotionTrail(NodePath, DirectObject):
|
|||
notify = directNotify.newCategory("MotionTrail")
|
||||
|
||||
task_added = False
|
||||
motion_trail_list = []
|
||||
motion_trail_list: list[MotionTrail] = []
|
||||
motion_trail_task_name = "motion_trail_task"
|
||||
|
||||
global_enable = True
|
||||
|
|
|
|||
|
|
@ -55,8 +55,6 @@ class BulletinBoard:
|
|||
def __repr__(self):
|
||||
str = 'Bulletin Board Contents\n'
|
||||
str += '======================='
|
||||
keys = list(self._dict.keys())
|
||||
keys.sort()
|
||||
for postName in keys:
|
||||
for postName in sorted(self._dict):
|
||||
str += '\n%s: %s' % (postName, self._dict[postName])
|
||||
return str
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
from __future__ import annotations
|
||||
|
||||
from direct.directnotify.DirectNotifyGlobal import directNotify
|
||||
import direct.showbase.DConfig as config
|
||||
from direct.showbase.PythonUtil import makeFlywheelGen, flywheel
|
||||
|
|
@ -11,7 +13,6 @@ import types
|
|||
import weakref
|
||||
import random
|
||||
import builtins
|
||||
import sys
|
||||
|
||||
|
||||
deadEndTypes = frozenset((
|
||||
|
|
@ -566,7 +567,7 @@ class FindContainers(Job):
|
|||
curObjRef = None
|
||||
|
||||
# types.CellType was added in Python 3.8
|
||||
if sys.version_info >= (3, 8) and type(curObj) is types.CellType:
|
||||
if type(curObj) is types.CellType:
|
||||
child = curObj.cell_contents
|
||||
hasLength = self._hasLength(child)
|
||||
notDeadEnd = not self._isDeadEnd(child)
|
||||
|
|
@ -983,7 +984,7 @@ class ContainerLeakDetector(Job):
|
|||
"""
|
||||
notify = directNotify.newCategory("ContainerLeakDetector")
|
||||
# set of containers that should not be examined
|
||||
PrivateIds = set()
|
||||
PrivateIds: set[int] = set()
|
||||
|
||||
def __init__(self, name, firstCheckDelay = None):
|
||||
Job.__init__(self, name)
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
from __future__ import annotations
|
||||
|
||||
from direct.directnotify.DirectNotifyGlobal import directNotify
|
||||
from direct.showbase.PythonUtil import Queue, invertDictLossless
|
||||
from direct.showbase.PythonUtil import safeRepr
|
||||
|
|
@ -5,14 +7,13 @@ from direct.showbase.Job import Job
|
|||
from direct.showbase.JobManagerGlobal import jobMgr
|
||||
from direct.showbase.ContainerLeakDetector import deadEndTypes
|
||||
import types
|
||||
import sys
|
||||
import io
|
||||
|
||||
|
||||
class ContainerReport(Job):
|
||||
notify = directNotify.newCategory("ContainerReport")
|
||||
# set of containers that should not be included in the report
|
||||
PrivateIds = set()
|
||||
PrivateIds: set[int] = set()
|
||||
|
||||
def __init__(self, name, log=False, limit=None, threaded=False):
|
||||
Job.__init__(self, name)
|
||||
|
|
@ -122,7 +123,7 @@ class ContainerReport(Job):
|
|||
continue
|
||||
|
||||
# types.CellType was added in Python 3.8
|
||||
if sys.version_info >= (3, 8) and type(parentObj) is types.CellType:
|
||||
if type(parentObj) is types.CellType:
|
||||
child = parentObj.cell_contents
|
||||
if self._examine(child):
|
||||
assert (self._queue.back() is child)
|
||||
|
|
@ -228,14 +229,11 @@ class ContainerReport(Job):
|
|||
if type not in self._type2id2len:
|
||||
return
|
||||
len2ids = invertDictLossless(self._type2id2len[type])
|
||||
lengths = list(len2ids.keys())
|
||||
lengths.sort()
|
||||
lengths.reverse()
|
||||
print('=====')
|
||||
print('===== %s' % type)
|
||||
count = 0
|
||||
stop = False
|
||||
for l in lengths:
|
||||
for l in sorted(len2ids, reverse=True):
|
||||
#len2ids[l].sort()
|
||||
pathStrList = list()
|
||||
for id in len2ids[l]:
|
||||
|
|
@ -257,9 +255,8 @@ class ContainerReport(Job):
|
|||
for type in initialTypes:
|
||||
for i in self._outputType(type, **kArgs):
|
||||
yield None
|
||||
otherTypes = list(set(self._type2id2len.keys()).difference(set(initialTypes)))
|
||||
otherTypes.sort(key=lambda obj: obj.__name__)
|
||||
for type in otherTypes:
|
||||
otherTypes = set(self._type2id2len).difference(initialTypes)
|
||||
for type in sorted(otherTypes, key=lambda obj: obj.__name__):
|
||||
for i in self._outputType(type, **kArgs):
|
||||
yield None
|
||||
|
||||
|
|
|
|||
|
|
@ -81,147 +81,3 @@ class CountedResource(object):
|
|||
|
||||
def __del__(self):
|
||||
self.decrementCounter()
|
||||
|
||||
|
||||
if __debug__ and __name__ == '__main__':
|
||||
class MouseResource(CountedResource):
|
||||
"""
|
||||
A simple class to demonstrate the acquisition of a resource.
|
||||
"""
|
||||
@classmethod
|
||||
def acquire(cls):
|
||||
# The call to the super-class's acquire() is
|
||||
# not necessary at the moment, but may be in
|
||||
# the future, so do it now for good measure.
|
||||
super(MouseResource, cls).acquire()
|
||||
|
||||
# Now acquire the resource this class is
|
||||
# managing.
|
||||
print('-- Acquire Mouse')
|
||||
|
||||
@classmethod
|
||||
def release(cls):
|
||||
# First, release the resource this class is
|
||||
# managing.
|
||||
print('-- Release Mouse')
|
||||
|
||||
# The call to the super-class's release() is
|
||||
# not necessary at the moment, but may be in
|
||||
# the future, so do it now for good measure.
|
||||
super(MouseResource, cls).release()
|
||||
|
||||
|
||||
def __init__(self):
|
||||
super(MouseResource, self).__init__()
|
||||
|
||||
def __del__(self):
|
||||
super(MouseResource, self).__del__()
|
||||
|
||||
class CursorResource(CountedResource):
|
||||
"""
|
||||
A class to demonstrate how to implement a dependent
|
||||
resource. Notice how this class also inherits from
|
||||
CountedResource. Instead of subclassing MouseCounter,
|
||||
we will just acquire it in our __init__() and release
|
||||
it in our __del__().
|
||||
"""
|
||||
@classmethod
|
||||
def acquire(cls):
|
||||
super(CursorResource, cls).acquire()
|
||||
print('-- Acquire Cursor')
|
||||
|
||||
@classmethod
|
||||
def release(cls):
|
||||
print('-- Release Cursor')
|
||||
|
||||
super(CursorResource, cls).release()
|
||||
|
||||
def __init__(self):
|
||||
# The required resource references should
|
||||
# be stored on 'self' since we want to
|
||||
# release it when the object is deleted.
|
||||
self.__mouseResource = MouseResource()
|
||||
|
||||
# Call the super-classes __init__()
|
||||
# after all required resources are
|
||||
# referenced.
|
||||
super(CursorResource, self).__init__()
|
||||
|
||||
def __del__(self):
|
||||
# Free up the most dependent resource
|
||||
# first, the one this class is managing.
|
||||
super(CursorResource, self).__del__()
|
||||
|
||||
# Now unlink any required resources.
|
||||
del self.__mouseResource
|
||||
|
||||
class InvalidResource(MouseResource):
|
||||
@classmethod
|
||||
def acquire(cls):
|
||||
super(InvalidResource, cls).acquire()
|
||||
print('-- Acquire Invalid')
|
||||
|
||||
@classmethod
|
||||
def release(cls):
|
||||
print('-- Release Invalid')
|
||||
super(InvalidResource, cls).release()
|
||||
|
||||
print('\nAllocate Mouse')
|
||||
m = MouseResource()
|
||||
print('Free up Mouse')
|
||||
del m
|
||||
|
||||
print('\nAllocate Cursor')
|
||||
c = CursorResource()
|
||||
print('Free up Cursor')
|
||||
del c
|
||||
|
||||
print('\nAllocate Mouse then Cursor')
|
||||
m = MouseResource()
|
||||
c = CursorResource()
|
||||
print('Free up Cursor')
|
||||
del c
|
||||
print('Free up Mouse')
|
||||
del m
|
||||
|
||||
print('\nAllocate Mouse then Cursor')
|
||||
m = MouseResource()
|
||||
c = CursorResource()
|
||||
print('Free up Mouse')
|
||||
del m
|
||||
print('Free up Cursor')
|
||||
del c
|
||||
|
||||
print('\nAllocate Cursor then Mouse')
|
||||
c = CursorResource()
|
||||
m = MouseResource()
|
||||
print('Free up Mouse')
|
||||
del m
|
||||
print('Free up Cursor')
|
||||
del c
|
||||
|
||||
print('\nAllocate Cursor then Mouse')
|
||||
c = CursorResource()
|
||||
m = MouseResource()
|
||||
print('Free up Cursor')
|
||||
del c
|
||||
|
||||
# example of an invalid subclass
|
||||
try:
|
||||
print('\nAllocate Invalid')
|
||||
i = InvalidResource()
|
||||
print('Free up Invalid')
|
||||
except AssertionError as e:
|
||||
print(e)
|
||||
print('')
|
||||
|
||||
print('Free up Mouse')
|
||||
del m
|
||||
|
||||
def demoFunc():
|
||||
print('\nAllocate Cursor within function')
|
||||
c = CursorResource()
|
||||
|
||||
print('Cursor will be freed on function exit')
|
||||
|
||||
demoFunc()
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
"This module contains a deprecated shim emulating the old DConfig API."
|
||||
|
||||
__all__ = []
|
||||
__all__ = ()
|
||||
|
||||
from panda3d.core import (ConfigFlags, ConfigVariableBool, ConfigVariableInt,
|
||||
ConfigVariableDouble, ConfigVariableString)
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
from __future__ import annotations
|
||||
|
||||
from direct.showbase.DirectObject import DirectObject
|
||||
from direct.directnotify.DirectNotifyGlobal import directNotify
|
||||
from panda3d.core import (
|
||||
|
|
@ -62,7 +64,7 @@ class DistancePhasedNode(PhasedObject, DirectObject, NodePath):
|
|||
|
||||
notify = directNotify.newCategory("DistancePhasedObject")
|
||||
__InstanceSequence = 0
|
||||
__InstanceDeque = []
|
||||
__InstanceDeque: list[int] = []
|
||||
|
||||
@staticmethod
|
||||
def __allocateId():
|
||||
|
|
@ -327,31 +329,3 @@ class BufferedDistancePhasedNode(DistancePhasedNode):
|
|||
for x,sphere in enumerate(self._colSpheres[phase+1:]):
|
||||
sphere.node().modifySolid(0).setRadius(self.bufferParamList[x+phase+1][1][0])
|
||||
sphere.node().markInternalBoundsStale()
|
||||
|
||||
|
||||
if __debug__ and 0:
|
||||
cSphere = CollisionSphere(0, 0, 0, 0.1)
|
||||
cNode = CollisionNode('camCol')
|
||||
cNode.addSolid(cSphere)
|
||||
cNodePath = NodePath(cNode)
|
||||
cNodePath.reparentTo(base.cam)
|
||||
# cNodePath.show()
|
||||
# cNodePath.setPos(25,0,0)
|
||||
|
||||
base.cTrav = CollisionTraverser()
|
||||
|
||||
eventHandler = CollisionHandlerEvent()
|
||||
eventHandler.addInPattern('enter%in')
|
||||
eventHandler.addOutPattern('exit%in')
|
||||
|
||||
# messenger.toggleVerbose()
|
||||
base.cTrav.addCollider(cNodePath, eventHandler)
|
||||
|
||||
p = BufferedDistancePhasedNode('p', {'At': (10, 20), 'Near': (100, 200), 'Far': (1000, 1020)},
|
||||
autoCleanup=False,
|
||||
fromCollideNode=cNodePath,
|
||||
)
|
||||
|
||||
p.reparentTo(render)
|
||||
p._DistancePhasedNode__oneTimeCollide()
|
||||
base.eventMgr.doEvents()
|
||||
|
|
|
|||
|
|
@ -69,7 +69,7 @@ oldExcepthook = None
|
|||
# from its main exception handler
|
||||
wantStackDumpLog = False
|
||||
wantStackDumpUpload = False
|
||||
variableDumpReasons = []
|
||||
variableDumpReasons: list = []
|
||||
dumpOnExceptionInit = False
|
||||
|
||||
|
||||
|
|
@ -116,15 +116,10 @@ def _excepthookDumpVars(eType, eValue, tb):
|
|||
for name, obj in frame.f_locals.items():
|
||||
if name in codeNames:
|
||||
name2obj[name] = obj
|
||||
# show them in alphabetical order
|
||||
names = list(name2obj.keys())
|
||||
names.sort()
|
||||
# push them in reverse order so they'll be popped in the correct order
|
||||
names.reverse()
|
||||
|
||||
traversedIds = set()
|
||||
|
||||
for name in names:
|
||||
# push them in reverse alphabetical order so they'll be popped in the correct order
|
||||
for name in sorted(name2obj, reverse=True):
|
||||
stateStack.push([name, name2obj[name], traversedIds])
|
||||
|
||||
while len(stateStack) > 0:
|
||||
|
|
@ -150,14 +145,10 @@ def _excepthookDumpVars(eType, eValue, tb):
|
|||
continue
|
||||
attrName2obj[attrName] = attr
|
||||
if len(attrName2obj) > 0:
|
||||
# show them in alphabetical order
|
||||
attrNames = list(attrName2obj.keys())
|
||||
attrNames.sort()
|
||||
# push them in reverse order so they'll be popped in the correct order
|
||||
attrNames.reverse()
|
||||
ids = set(traversedIds)
|
||||
ids.add(id(obj))
|
||||
for attrName in attrNames:
|
||||
# push them in reverse alphabetical order so they'll be popped in the correct order
|
||||
for attrName in sorted(attrName2obj, reverse=True):
|
||||
obj = attrName2obj[attrName]
|
||||
stateStack.push(['%s.%s' % (name, attrName), obj, ids])
|
||||
|
||||
|
|
|
|||
|
|
@ -294,8 +294,7 @@ class GarbageReport(Job):
|
|||
if self._args.fullReport:
|
||||
garbageIndices = range(self.numGarbage)
|
||||
else:
|
||||
garbageIndices = list(self.cycleIds)
|
||||
garbageIndices.sort()
|
||||
garbageIndices = sorted(self.cycleIds)
|
||||
numGarbage = len(garbageIndices)
|
||||
|
||||
# log each individual item with a number in front of it
|
||||
|
|
|
|||
|
|
@ -141,9 +141,7 @@ class JobManager:
|
|||
|
||||
def _getSortedPriorities(self):
|
||||
# returns all job priorities in ascending order
|
||||
priorities = list(self._pri2jobId2job.keys())
|
||||
priorities.sort()
|
||||
return priorities
|
||||
return sorted(self._pri2jobId2job)
|
||||
|
||||
def _process(self, task=None):
|
||||
if self._useOverflowTime is None:
|
||||
|
|
|
|||
|
|
@ -540,9 +540,7 @@ class Messenger:
|
|||
return a matching event (needle) if found (in haystack).
|
||||
This is primarily a debugging tool.
|
||||
"""
|
||||
keys = list(self.__callbacks.keys())
|
||||
keys.sort()
|
||||
for event in keys:
|
||||
for event in sorted(self.__callbacks):
|
||||
if repr(event).find(needle) >= 0:
|
||||
return {event: self.__callbacks[event]}
|
||||
|
||||
|
|
@ -553,9 +551,7 @@ class Messenger:
|
|||
This is primarily a debugging tool.
|
||||
"""
|
||||
matches = {}
|
||||
keys = list(self.__callbacks.keys())
|
||||
keys.sort()
|
||||
for event in keys:
|
||||
for event in sorted(self.__callbacks):
|
||||
if repr(event).find(needle) >= 0:
|
||||
matches[event] = self.__callbacks[event]
|
||||
# if the limit is not None, decrement and
|
||||
|
|
@ -596,9 +592,7 @@ class Messenger:
|
|||
Compact version of event, acceptor pairs
|
||||
"""
|
||||
str = "The messenger is currently handling:\n" + "="*64 + "\n"
|
||||
keys = list(self.__callbacks.keys())
|
||||
keys.sort()
|
||||
for event in keys:
|
||||
for event in sorted(self.__callbacks):
|
||||
str += self.__eventRepr(event)
|
||||
# Print out the object: event dictionary too
|
||||
str += "="*64 + "\n"
|
||||
|
|
@ -617,9 +611,7 @@ class Messenger:
|
|||
"""
|
||||
str = 'Messenger\n'
|
||||
str = str + '='*50 + '\n'
|
||||
keys = list(self.__callbacks.keys())
|
||||
keys.sort()
|
||||
for event in keys:
|
||||
for event in sorted(self.__callbacks):
|
||||
acceptorDict = self.__callbacks[event]
|
||||
str = str + 'Event: ' + event + '\n'
|
||||
for key in list(acceptorDict.keys()):
|
||||
|
|
|
|||
|
|
@ -90,10 +90,7 @@ class ObjectPool:
|
|||
def typeFreqStr(self):
|
||||
s = 'Object Pool: Type Frequencies'
|
||||
s += '\n============================='
|
||||
counts = list(set(self._count2types.keys()))
|
||||
counts.sort()
|
||||
counts.reverse()
|
||||
for count in counts:
|
||||
for count in sorted(self._count2types, reverse=True):
|
||||
types = makeList(self._count2types[count])
|
||||
for typ in types:
|
||||
s += '\n%s\t%s' % (count, typ)
|
||||
|
|
@ -102,12 +99,10 @@ class ObjectPool:
|
|||
def printObjsByType(self):
|
||||
print('Object Pool: Objects By Type')
|
||||
print('\n============================')
|
||||
counts = list(set(self._count2types.keys()))
|
||||
counts.sort()
|
||||
# print types with the smallest number of instances first, in case
|
||||
# there's a large group that waits a long time before printing
|
||||
#counts.reverse()
|
||||
for count in counts:
|
||||
for count in sorted(self._count2types):
|
||||
types = makeList(self._count2types[count])
|
||||
for typ in types:
|
||||
print('TYPE: %s, %s objects' % (repr(typ), len(self._type2objs[typ])))
|
||||
|
|
@ -115,10 +110,7 @@ class ObjectPool:
|
|||
|
||||
def printReferrers(self, numEach=3):
|
||||
"""referrers of the first few of each type of object"""
|
||||
counts = list(set(self._count2types.keys()))
|
||||
counts.sort()
|
||||
counts.reverse()
|
||||
for count in counts:
|
||||
for count in sorted(self._count2types, reverse=True):
|
||||
types = makeList(self._count2types[count])
|
||||
for typ in types:
|
||||
print('\n\nTYPE: %s' % repr(typ))
|
||||
|
|
|
|||
|
|
@ -11,6 +11,8 @@
|
|||
>>> o.diff(o2)
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
__all__ = ['ExclusiveObjectPool', 'ObjectReport']
|
||||
|
||||
from direct.directnotify.DirectNotifyGlobal import directNotify
|
||||
|
|
@ -26,8 +28,8 @@ import builtins
|
|||
class ExclusiveObjectPool(DirectObject):
|
||||
# ObjectPool specialization that excludes particular objects
|
||||
# IDs of objects to globally exclude from reporting
|
||||
_ExclObjs = []
|
||||
_ExclObjIds = {}
|
||||
_ExclObjs: list[object] = []
|
||||
_ExclObjIds: dict[int, int] = {}
|
||||
_SyncMaster = Sync('ExclusiveObjectPool.ExcludedObjectList')
|
||||
_SerialNumGen = SerialNumGen()
|
||||
|
||||
|
|
|
|||
|
|
@ -57,9 +57,7 @@ class OnScreenDebug:
|
|||
if not self.onScreenText:
|
||||
self.load()
|
||||
self.onScreenText.clearText()
|
||||
entries = list(self.data.items())
|
||||
entries.sort()
|
||||
for k, v in entries:
|
||||
for k, v in sorted(self.data.items()):
|
||||
if v[0] == self.frame:
|
||||
# It was updated this frame (key equals value):
|
||||
#isNew = " is"
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
"""Contains miscellaneous utility functions and classes."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
__all__ = [
|
||||
|
||||
'indent', 'doc', 'adjust', 'difference', 'intersection', 'union',
|
||||
|
|
@ -11,7 +13,7 @@ __all__ = [
|
|||
'boolEqual', 'lineupPos', 'formatElapsedSeconds', 'solveQuadratic',
|
||||
'findPythonModule', 'mostDerivedLast', 'clampScalar', 'weightedChoice',
|
||||
'randFloat', 'normalDistrib', 'weightedRand', 'randUint31', 'randInt32',
|
||||
'SerialNumGen', 'serialNum', 'uniqueName', 'Singleton',
|
||||
'SerialNumGen', 'SerialMaskedGen', 'serialNum', 'uniqueName', 'Singleton',
|
||||
'SingletonError', 'printListEnum', 'safeRepr', 'fastRepr',
|
||||
'isDefaultValue', 'ScratchPad', 'Sync', 'itype', 'getNumberedTypedString',
|
||||
'getNumberedTypedSortedString', 'printNumberedTyped', 'DelayedCall',
|
||||
|
|
@ -39,6 +41,7 @@ import time
|
|||
import builtins
|
||||
import importlib
|
||||
import functools
|
||||
from typing import Callable
|
||||
|
||||
__report_indent = 3
|
||||
|
||||
|
|
@ -699,9 +702,9 @@ if __debug__:
|
|||
return profileDecorator
|
||||
|
||||
# intercept profile-related file operations to avoid disk access
|
||||
movedOpenFuncs = []
|
||||
movedDumpFuncs = []
|
||||
movedLoadFuncs = []
|
||||
movedOpenFuncs: list[Callable] = []
|
||||
movedDumpFuncs: list[Callable] = []
|
||||
movedLoadFuncs: list[Callable] = []
|
||||
profileFilenames = set()
|
||||
profileFilenameList = Stack()
|
||||
profileFilename2file = {}
|
||||
|
|
@ -1899,7 +1902,7 @@ class SubframeCall:
|
|||
|
||||
|
||||
class PStatScope:
|
||||
collectors = {}
|
||||
collectors: dict = {}
|
||||
|
||||
def __init__(self, level = None):
|
||||
self.levels = []
|
||||
|
|
@ -2458,18 +2461,6 @@ def formatTimeCompact(seconds):
|
|||
return result
|
||||
|
||||
|
||||
if __debug__ and __name__ == '__main__':
|
||||
ftc = formatTimeCompact
|
||||
assert ftc(0) == '0s'
|
||||
assert ftc(1) == '1s'
|
||||
assert ftc(60) == '1m0s'
|
||||
assert ftc(64) == '1m4s'
|
||||
assert ftc(60*60) == '1h0m0s'
|
||||
assert ftc(24*60*60) == '1d0h0m0s'
|
||||
assert ftc(24*60*60 + 2*60*60 + 34*60 + 12) == '1d2h34m12s'
|
||||
del ftc
|
||||
|
||||
|
||||
def formatTimeExact(seconds):
|
||||
# like formatTimeCompact but leaves off '0 seconds', '0 minutes' etc. for
|
||||
# times that are e.g. 1 hour, 3 days etc.
|
||||
|
|
@ -2496,19 +2487,6 @@ def formatTimeExact(seconds):
|
|||
return result
|
||||
|
||||
|
||||
if __debug__ and __name__ == '__main__':
|
||||
fte = formatTimeExact
|
||||
assert fte(0) == '0s'
|
||||
assert fte(1) == '1s'
|
||||
assert fte(2) == '2s'
|
||||
assert fte(61) == '1m1s'
|
||||
assert fte(60) == '1m'
|
||||
assert fte(60*60) == '1h'
|
||||
assert fte(24*60*60) == '1d'
|
||||
assert fte((24*60*60) + (2 * 60)) == '1d0h2m'
|
||||
del fte
|
||||
|
||||
|
||||
class AlphabetCounter:
|
||||
# object that produces 'A', 'B', 'C', ... 'AA', 'AB', etc.
|
||||
def __init__(self):
|
||||
|
|
@ -2540,28 +2518,6 @@ class AlphabetCounter:
|
|||
__next__ = next
|
||||
|
||||
|
||||
if __debug__ and __name__ == '__main__':
|
||||
def testAlphabetCounter():
|
||||
tempList = []
|
||||
ac = AlphabetCounter()
|
||||
for i in range(26*3):
|
||||
tempList.append(ac.next())
|
||||
assert tempList == [ 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
|
||||
'AA','AB','AC','AD','AE','AF','AG','AH','AI','AJ','AK','AL','AM','AN','AO','AP','AQ','AR','AS','AT','AU','AV','AW','AX','AY','AZ',
|
||||
'BA','BB','BC','BD','BE','BF','BG','BH','BI','BJ','BK','BL','BM','BN','BO','BP','BQ','BR','BS','BT','BU','BV','BW','BX','BY','BZ',]
|
||||
ac = AlphabetCounter()
|
||||
num = 26 # A-Z
|
||||
num += (26*26) # AA-ZZ
|
||||
num += 26 # AAZ
|
||||
num += 1 # ABA
|
||||
num += 2 # ABC
|
||||
for i in range(num):
|
||||
x = ac.next()
|
||||
assert x == 'ABC'
|
||||
testAlphabetCounter()
|
||||
del testAlphabetCounter
|
||||
|
||||
|
||||
class Default:
|
||||
# represents 'use the default value'
|
||||
# useful for keyword arguments to virtual methods
|
||||
|
|
@ -2665,52 +2621,52 @@ class PriorityCallbacks:
|
|||
callback()
|
||||
|
||||
|
||||
builtins.Functor = Functor
|
||||
builtins.Stack = Stack
|
||||
builtins.Queue = Queue
|
||||
builtins.SerialNumGen = SerialNumGen
|
||||
builtins.SerialMaskedGen = SerialMaskedGen
|
||||
builtins.ScratchPad = ScratchPad
|
||||
builtins.uniqueName = uniqueName
|
||||
builtins.serialNum = serialNum
|
||||
builtins.Functor = Functor # type: ignore[attr-defined]
|
||||
builtins.Stack = Stack # type: ignore[attr-defined]
|
||||
builtins.Queue = Queue # type: ignore[attr-defined]
|
||||
builtins.SerialNumGen = SerialNumGen # type: ignore[attr-defined]
|
||||
builtins.SerialMaskedGen = SerialMaskedGen # type: ignore[attr-defined]
|
||||
builtins.ScratchPad = ScratchPad # type: ignore[attr-defined]
|
||||
builtins.uniqueName = uniqueName # type: ignore[attr-defined]
|
||||
builtins.serialNum = serialNum # type: ignore[attr-defined]
|
||||
if __debug__:
|
||||
builtins.profiled = profiled
|
||||
builtins.exceptionLogged = exceptionLogged
|
||||
builtins.itype = itype
|
||||
builtins.appendStr = appendStr
|
||||
builtins.bound = bound
|
||||
builtins.clamp = clamp
|
||||
builtins.lerp = lerp
|
||||
builtins.makeList = makeList
|
||||
builtins.makeTuple = makeTuple
|
||||
builtins.profiled = profiled # type: ignore[attr-defined]
|
||||
builtins.exceptionLogged = exceptionLogged # type: ignore[attr-defined]
|
||||
builtins.itype = itype # type: ignore[attr-defined]
|
||||
builtins.appendStr = appendStr # type: ignore[attr-defined]
|
||||
builtins.bound = bound # type: ignore[attr-defined]
|
||||
builtins.clamp = clamp # type: ignore[attr-defined]
|
||||
builtins.lerp = lerp # type: ignore[attr-defined]
|
||||
builtins.makeList = makeList # type: ignore[attr-defined]
|
||||
builtins.makeTuple = makeTuple # type: ignore[attr-defined]
|
||||
if __debug__:
|
||||
builtins.printStack = printStack
|
||||
builtins.printReverseStack = printReverseStack
|
||||
builtins.printVerboseStack = printVerboseStack
|
||||
builtins.DelayedCall = DelayedCall
|
||||
builtins.DelayedFunctor = DelayedFunctor
|
||||
builtins.FrameDelayedCall = FrameDelayedCall
|
||||
builtins.SubframeCall = SubframeCall
|
||||
builtins.invertDict = invertDict
|
||||
builtins.invertDictLossless = invertDictLossless
|
||||
builtins.getBase = getBase
|
||||
builtins.getRepository = getRepository
|
||||
builtins.safeRepr = safeRepr
|
||||
builtins.fastRepr = fastRepr
|
||||
builtins.nullGen = nullGen
|
||||
builtins.flywheel = flywheel
|
||||
builtins.loopGen = loopGen
|
||||
builtins.printStack = printStack # type: ignore[attr-defined]
|
||||
builtins.printReverseStack = printReverseStack # type: ignore[attr-defined]
|
||||
builtins.printVerboseStack = printVerboseStack # type: ignore[attr-defined]
|
||||
builtins.DelayedCall = DelayedCall # type: ignore[attr-defined]
|
||||
builtins.DelayedFunctor = DelayedFunctor # type: ignore[attr-defined]
|
||||
builtins.FrameDelayedCall = FrameDelayedCall # type: ignore[attr-defined]
|
||||
builtins.SubframeCall = SubframeCall # type: ignore[attr-defined]
|
||||
builtins.invertDict = invertDict # type: ignore[attr-defined]
|
||||
builtins.invertDictLossless = invertDictLossless # type: ignore[attr-defined]
|
||||
builtins.getBase = getBase # type: ignore[attr-defined]
|
||||
builtins.getRepository = getRepository # type: ignore[attr-defined]
|
||||
builtins.safeRepr = safeRepr # type: ignore[attr-defined]
|
||||
builtins.fastRepr = fastRepr # type: ignore[attr-defined]
|
||||
builtins.nullGen = nullGen # type: ignore[attr-defined]
|
||||
builtins.flywheel = flywheel # type: ignore[attr-defined]
|
||||
builtins.loopGen = loopGen # type: ignore[attr-defined]
|
||||
if __debug__:
|
||||
builtins.StackTrace = StackTrace
|
||||
builtins.report = report
|
||||
builtins.pstatcollect = pstatcollect
|
||||
builtins.MiniLog = MiniLog
|
||||
builtins.MiniLogSentry = MiniLogSentry
|
||||
builtins.logBlock = logBlock
|
||||
builtins.HierarchyException = HierarchyException
|
||||
builtins.deeptype = deeptype
|
||||
builtins.Default = Default
|
||||
builtins.configIsToday = configIsToday
|
||||
builtins.typeName = typeName
|
||||
builtins.safeTypeName = safeTypeName
|
||||
builtins.histogramDict = histogramDict
|
||||
builtins.StackTrace = StackTrace # type: ignore[attr-defined]
|
||||
builtins.report = report # type: ignore[attr-defined]
|
||||
builtins.pstatcollect = pstatcollect # type: ignore[attr-defined]
|
||||
builtins.MiniLog = MiniLog # type: ignore[attr-defined]
|
||||
builtins.MiniLogSentry = MiniLogSentry # type: ignore[attr-defined]
|
||||
builtins.logBlock = logBlock # type: ignore[attr-defined]
|
||||
builtins.HierarchyException = HierarchyException # type: ignore[attr-defined]
|
||||
builtins.deeptype = deeptype # type: ignore[attr-defined]
|
||||
builtins.Default = Default # type: ignore[attr-defined]
|
||||
builtins.configIsToday = configIsToday # type: ignore[attr-defined]
|
||||
builtins.typeName = typeName # type: ignore[attr-defined]
|
||||
builtins.safeTypeName = safeTypeName # type: ignore[attr-defined]
|
||||
builtins.histogramDict = histogramDict # type: ignore[attr-defined]
|
||||
|
|
|
|||
|
|
@ -120,7 +120,7 @@ from direct.extensions_native import NodePath_extensions # pylint: disable=unuse
|
|||
# This needs to be available early for DirectGUI imports
|
||||
import sys
|
||||
import builtins
|
||||
builtins.config = DConfig
|
||||
builtins.config = DConfig # type: ignore[attr-defined]
|
||||
|
||||
from direct.directnotify.DirectNotifyGlobal import directNotify, giveNotify
|
||||
from .MessengerGlobal import messenger
|
||||
|
|
@ -3315,8 +3315,9 @@ class ShowBase(DirectObject.DirectObject):
|
|||
init_app_for_gui()
|
||||
|
||||
# Disable the Windows message loop, since Tcl wants to handle this all
|
||||
# on its own.
|
||||
ConfigVariableBool('disable-message-loop', False).value = True
|
||||
# on its own, except if the Panda window is on a separate thread.
|
||||
if self.graphicsEngine.getThreadingModel().getDrawStage() == 0:
|
||||
ConfigVariableBool('disable-message-loop', False).value = True
|
||||
|
||||
if ConfigVariableBool('tk-main-loop', True):
|
||||
# Put Tkinter in charge of the main loop. It really
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ Note that you cannot directly import :data:`~builtins.base` from this module
|
|||
since ShowBase may not have been created yet; instead, ShowBase dynamically
|
||||
adds itself to this module's scope when instantiated."""
|
||||
|
||||
__all__ = []
|
||||
__all__ = ()
|
||||
|
||||
from .ShowBase import ShowBase, WindowControls # pylint: disable=unused-import
|
||||
from direct.directnotify.DirectNotifyGlobal import directNotify, giveNotify # pylint: disable=unused-import
|
||||
|
|
@ -23,6 +23,8 @@ import warnings
|
|||
|
||||
__dev__ = ConfigVariableBool('want-dev', __debug__).value
|
||||
|
||||
base: ShowBase
|
||||
|
||||
#: The global instance of the :ref:`virtual-file-system`, as obtained using
|
||||
#: :meth:`panda3d.core.VirtualFileSystem.getGlobalPtr()`.
|
||||
vfs = VirtualFileSystem.getGlobalPtr()
|
||||
|
|
@ -81,7 +83,7 @@ def inspect(anObject):
|
|||
|
||||
|
||||
import builtins
|
||||
builtins.inspect = inspect
|
||||
builtins.inspect = inspect # type: ignore[attr-defined]
|
||||
|
||||
# this also appears in AIBaseGlobal
|
||||
if (not __debug__) and __dev__:
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ This module hooks into Python's import mechanism to print out all imports to
|
|||
the standard output as they happen.
|
||||
"""
|
||||
|
||||
__all__ = []
|
||||
__all__ = ()
|
||||
|
||||
|
||||
import sys
|
||||
|
|
|
|||
|
|
@ -756,8 +756,8 @@ class TexMemWatcher(DirectObject):
|
|||
|
||||
# Sort the regions from largest to smallest to maximize
|
||||
# packing effectiveness.
|
||||
texRecords = list(self.texRecordsByTex.values())
|
||||
texRecords.sort(key = lambda tr: (tr.tw, tr.th), reverse = True)
|
||||
texRecords = sorted(self.texRecordsByTex.values(),
|
||||
key=lambda tr: (tr.tw, tr.th), reverse=True)
|
||||
|
||||
for tr in texRecords:
|
||||
self.placeTexture(tr)
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ BasePickler = pickle._Pickler
|
|||
BaseUnpickler = pickle._Unpickler
|
||||
|
||||
|
||||
class Pickler(BasePickler):
|
||||
class Pickler(BasePickler): # type: ignore[misc, valid-type]
|
||||
|
||||
def __init__(self, *args, **kw):
|
||||
self.bamWriter = BamWriter()
|
||||
|
|
@ -148,7 +148,7 @@ class Pickler(BasePickler):
|
|||
self.save_reduce(obj=obj, *rv)
|
||||
|
||||
|
||||
class Unpickler(BaseUnpickler):
|
||||
class Unpickler(BaseUnpickler): # type: ignore[misc, valid-type]
|
||||
|
||||
def __init__(self, *args, **kw):
|
||||
self.bamReader = BamReader()
|
||||
|
|
|
|||
|
|
@ -83,8 +83,8 @@ class ThreadBase:
|
|||
# Copy these static methods from Panda's Thread object. These are
|
||||
# useful if you may be running in Panda's SIMPLE_THREADS compilation
|
||||
# mode.
|
||||
ThreadBase.forceYield = core.Thread.forceYield
|
||||
ThreadBase.considerYield = core.Thread.considerYield
|
||||
ThreadBase.forceYield = core.Thread.forceYield # type: ignore[attr-defined]
|
||||
ThreadBase.considerYield = core.Thread.considerYield # type: ignore[attr-defined]
|
||||
|
||||
|
||||
class Thread(ThreadBase):
|
||||
|
|
@ -123,10 +123,7 @@ class Thread(ThreadBase):
|
|||
self.__dict__['ident'] = threadId
|
||||
|
||||
def __del__(self):
|
||||
# On interpreter shutdown, the _thread module might have
|
||||
# already been cleaned up.
|
||||
if _thread and _thread._remove_thread_id:
|
||||
_thread._remove_thread_id(self.ident)
|
||||
_thread._remove_thread_id(self.ident)
|
||||
|
||||
def is_alive(self):
|
||||
thread = self.__thread
|
||||
|
|
@ -435,108 +432,3 @@ def setprofile(func):
|
|||
|
||||
def stack_size(size = None):
|
||||
raise ThreadError
|
||||
|
||||
|
||||
if __debug__:
|
||||
def _test():
|
||||
from collections import deque
|
||||
|
||||
_sleep = core.Thread.sleep
|
||||
|
||||
_VERBOSE = False
|
||||
|
||||
class _Verbose(object):
|
||||
|
||||
def __init__(self, verbose=None):
|
||||
if verbose is None:
|
||||
verbose = _VERBOSE
|
||||
self.__verbose = verbose
|
||||
|
||||
def _note(self, format, *args):
|
||||
if self.__verbose:
|
||||
format = format % args
|
||||
format = "%s: %s\n" % (
|
||||
currentThread().getName(), format)
|
||||
_sys.stderr.write(format)
|
||||
|
||||
class BoundedQueue(_Verbose):
|
||||
|
||||
def __init__(self, limit):
|
||||
_Verbose.__init__(self)
|
||||
self.mon = Lock(name = "BoundedQueue.mon")
|
||||
self.rc = Condition(self.mon)
|
||||
self.wc = Condition(self.mon)
|
||||
self.limit = limit
|
||||
self.queue = deque()
|
||||
|
||||
def put(self, item):
|
||||
self.mon.acquire()
|
||||
while len(self.queue) >= self.limit:
|
||||
self._note("put(%s): queue full", item)
|
||||
self.wc.wait()
|
||||
self.queue.append(item)
|
||||
self._note("put(%s): appended, length now %d",
|
||||
item, len(self.queue))
|
||||
self.rc.notify()
|
||||
self.mon.release()
|
||||
|
||||
def get(self):
|
||||
self.mon.acquire()
|
||||
while not self.queue:
|
||||
self._note("get(): queue empty")
|
||||
self.rc.wait()
|
||||
item = self.queue.popleft()
|
||||
self._note("get(): got %s, %d left", item, len(self.queue))
|
||||
self.wc.notify()
|
||||
self.mon.release()
|
||||
return item
|
||||
|
||||
class ProducerThread(Thread):
|
||||
|
||||
def __init__(self, queue, quota):
|
||||
Thread.__init__(self, name="Producer")
|
||||
self.queue = queue
|
||||
self.quota = quota
|
||||
|
||||
def run(self):
|
||||
from random import random
|
||||
counter = 0
|
||||
while counter < self.quota:
|
||||
counter = counter + 1
|
||||
self.queue.put("%s.%d" % (self.getName(), counter))
|
||||
_sleep(random() * 0.00001)
|
||||
|
||||
class ConsumerThread(Thread):
|
||||
|
||||
def __init__(self, queue, count):
|
||||
Thread.__init__(self, name="Consumer")
|
||||
self.queue = queue
|
||||
self.count = count
|
||||
|
||||
def run(self):
|
||||
while self.count > 0:
|
||||
item = self.queue.get()
|
||||
print(item)
|
||||
self.count = self.count - 1
|
||||
|
||||
NP = 3
|
||||
QL = 4
|
||||
NI = 5
|
||||
|
||||
Q = BoundedQueue(QL)
|
||||
P = []
|
||||
for i in range(NP):
|
||||
t = ProducerThread(Q, NI)
|
||||
t.setName("Producer-%d" % (i+1))
|
||||
P.append(t)
|
||||
C = ConsumerThread(Q, NI*NP)
|
||||
for t in P:
|
||||
t.start()
|
||||
_sleep(0.000001)
|
||||
C.start()
|
||||
for t in P:
|
||||
t.join()
|
||||
C.join()
|
||||
|
||||
if __name__ == '__main__':
|
||||
_test()
|
||||
|
|
|
|||
|
|
@ -65,7 +65,7 @@ if __debug__:
|
|||
|
||||
else:
|
||||
# Disable this when using "python -O"
|
||||
class _Verbose(object):
|
||||
class _Verbose(object): # type: ignore[no-redef]
|
||||
def __init__(self, verbose=None):
|
||||
pass
|
||||
def _note(self, *args):
|
||||
|
|
@ -762,92 +762,3 @@ def main_thread():
|
|||
## from thread import _local as local
|
||||
## except ImportError:
|
||||
## from _threading_local import local
|
||||
|
||||
|
||||
# Self-test code
|
||||
if __debug__:
|
||||
def _test():
|
||||
from collections import deque
|
||||
|
||||
class BoundedQueue(_Verbose):
|
||||
|
||||
def __init__(self, limit):
|
||||
_Verbose.__init__(self)
|
||||
self.mon = RLock()
|
||||
self.rc = Condition(self.mon)
|
||||
self.wc = Condition(self.mon)
|
||||
self.limit = limit
|
||||
self.queue = deque()
|
||||
|
||||
def put(self, item):
|
||||
self.mon.acquire()
|
||||
while len(self.queue) >= self.limit:
|
||||
self._note("put(%s): queue full", item)
|
||||
self.wc.wait()
|
||||
self.queue.append(item)
|
||||
self._note("put(%s): appended, length now %d",
|
||||
item, len(self.queue))
|
||||
self.rc.notify()
|
||||
self.mon.release()
|
||||
|
||||
def get(self):
|
||||
self.mon.acquire()
|
||||
while not self.queue:
|
||||
self._note("get(): queue empty")
|
||||
self.rc.wait()
|
||||
item = self.queue.popleft()
|
||||
self._note("get(): got %s, %d left", item, len(self.queue))
|
||||
self.wc.notify()
|
||||
self.mon.release()
|
||||
return item
|
||||
|
||||
class ProducerThread(Thread):
|
||||
|
||||
def __init__(self, queue, quota):
|
||||
Thread.__init__(self, name="Producer")
|
||||
self.queue = queue
|
||||
self.quota = quota
|
||||
|
||||
def run(self):
|
||||
from random import random
|
||||
counter = 0
|
||||
while counter < self.quota:
|
||||
counter = counter + 1
|
||||
self.queue.put("%s.%d" % (self.getName(), counter))
|
||||
_sleep(random() * 0.00001)
|
||||
|
||||
|
||||
class ConsumerThread(Thread):
|
||||
|
||||
def __init__(self, queue, count):
|
||||
Thread.__init__(self, name="Consumer")
|
||||
self.queue = queue
|
||||
self.count = count
|
||||
|
||||
def run(self):
|
||||
while self.count > 0:
|
||||
item = self.queue.get()
|
||||
print(item)
|
||||
self.count = self.count - 1
|
||||
|
||||
NP = 3
|
||||
QL = 4
|
||||
NI = 5
|
||||
|
||||
Q = BoundedQueue(QL)
|
||||
P = []
|
||||
for i in range(NP):
|
||||
t = ProducerThread(Q, NI)
|
||||
t.setName("Producer-%d" % (i+1))
|
||||
P.append(t)
|
||||
C = ConsumerThread(Q, NI*NP)
|
||||
for t in P:
|
||||
t.start()
|
||||
_sleep(0.000001)
|
||||
C.start()
|
||||
for t in P:
|
||||
t.join()
|
||||
C.join()
|
||||
|
||||
if __name__ == '__main__':
|
||||
_test()
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ if hasattr(sys, 'getandroidapilevel'):
|
|||
signal = None
|
||||
else:
|
||||
try:
|
||||
import _signal as signal
|
||||
import _signal as signal # type: ignore[import, no-redef]
|
||||
except ImportError:
|
||||
signal = None
|
||||
|
||||
|
|
@ -801,532 +801,6 @@ class TaskManager:
|
|||
# time.sleep(delta)
|
||||
# delta = minFinTime - self.globalClock.getRealTime()
|
||||
|
||||
if __debug__:
|
||||
# to catch memory leaks during the tests at the bottom of the file
|
||||
def _startTrackingMemLeaks(self):
|
||||
pass
|
||||
|
||||
def _stopTrackingMemLeaks(self):
|
||||
pass
|
||||
|
||||
def _checkMemLeaks(self):
|
||||
pass
|
||||
|
||||
def _runTests(self):
|
||||
if __debug__:
|
||||
tm = TaskManager()
|
||||
tm.setClock(ClockObject())
|
||||
tm.setupTaskChain("default", tickClock = True)
|
||||
|
||||
# check for memory leaks after every test
|
||||
tm._startTrackingMemLeaks()
|
||||
tm._checkMemLeaks()
|
||||
|
||||
# run-once task
|
||||
l = []
|
||||
|
||||
def _testDone(task, l=l):
|
||||
l.append(None)
|
||||
return task.done
|
||||
tm.add(_testDone, 'testDone')
|
||||
tm.step()
|
||||
assert len(l) == 1
|
||||
tm.step()
|
||||
assert len(l) == 1
|
||||
_testDone = None
|
||||
tm._checkMemLeaks()
|
||||
|
||||
# remove by name
|
||||
def _testRemoveByName(task):
|
||||
return task.done
|
||||
tm.add(_testRemoveByName, 'testRemoveByName')
|
||||
assert tm.remove('testRemoveByName') == 1
|
||||
assert tm.remove('testRemoveByName') == 0
|
||||
_testRemoveByName = None
|
||||
tm._checkMemLeaks()
|
||||
|
||||
# duplicate named tasks
|
||||
def _testDupNamedTasks(task):
|
||||
return task.done
|
||||
tm.add(_testDupNamedTasks, 'testDupNamedTasks')
|
||||
tm.add(_testDupNamedTasks, 'testDupNamedTasks')
|
||||
assert tm.remove('testRemoveByName') == 0
|
||||
_testDupNamedTasks = None
|
||||
tm._checkMemLeaks()
|
||||
|
||||
# continued task
|
||||
l = []
|
||||
|
||||
def _testCont(task, l = l):
|
||||
l.append(None)
|
||||
return task.cont
|
||||
tm.add(_testCont, 'testCont')
|
||||
tm.step()
|
||||
assert len(l) == 1
|
||||
tm.step()
|
||||
assert len(l) == 2
|
||||
tm.remove('testCont')
|
||||
_testCont = None
|
||||
tm._checkMemLeaks()
|
||||
|
||||
# continue until done task
|
||||
l = []
|
||||
|
||||
def _testContDone(task, l = l):
|
||||
l.append(None)
|
||||
if len(l) >= 2:
|
||||
return task.done
|
||||
else:
|
||||
return task.cont
|
||||
tm.add(_testContDone, 'testContDone')
|
||||
tm.step()
|
||||
assert len(l) == 1
|
||||
tm.step()
|
||||
assert len(l) == 2
|
||||
tm.step()
|
||||
assert len(l) == 2
|
||||
assert not tm.hasTaskNamed('testContDone')
|
||||
_testContDone = None
|
||||
tm._checkMemLeaks()
|
||||
|
||||
# hasTaskNamed
|
||||
def _testHasTaskNamed(task):
|
||||
return task.done
|
||||
tm.add(_testHasTaskNamed, 'testHasTaskNamed')
|
||||
assert tm.hasTaskNamed('testHasTaskNamed')
|
||||
tm.step()
|
||||
assert not tm.hasTaskNamed('testHasTaskNamed')
|
||||
_testHasTaskNamed = None
|
||||
tm._checkMemLeaks()
|
||||
|
||||
# task sort
|
||||
l = []
|
||||
|
||||
def _testPri1(task, l = l):
|
||||
l.append(1)
|
||||
return task.cont
|
||||
|
||||
def _testPri2(task, l = l):
|
||||
l.append(2)
|
||||
return task.cont
|
||||
tm.add(_testPri1, 'testPri1', sort = 1)
|
||||
tm.add(_testPri2, 'testPri2', sort = 2)
|
||||
tm.step()
|
||||
assert len(l) == 2
|
||||
assert l == [1, 2,]
|
||||
tm.step()
|
||||
assert len(l) == 4
|
||||
assert l == [1, 2, 1, 2,]
|
||||
tm.remove('testPri1')
|
||||
tm.remove('testPri2')
|
||||
_testPri1 = None
|
||||
_testPri2 = None
|
||||
tm._checkMemLeaks()
|
||||
|
||||
# task extraArgs
|
||||
l = []
|
||||
|
||||
def _testExtraArgs(arg1, arg2, l=l):
|
||||
l.extend([arg1, arg2,])
|
||||
return done
|
||||
tm.add(_testExtraArgs, 'testExtraArgs', extraArgs=[4,5])
|
||||
tm.step()
|
||||
assert len(l) == 2
|
||||
assert l == [4, 5,]
|
||||
_testExtraArgs = None
|
||||
tm._checkMemLeaks()
|
||||
|
||||
# task appendTask
|
||||
l = []
|
||||
|
||||
def _testAppendTask(arg1, arg2, task, l=l):
|
||||
l.extend([arg1, arg2,])
|
||||
return task.done
|
||||
tm.add(_testAppendTask, '_testAppendTask', extraArgs=[4,5], appendTask=True)
|
||||
tm.step()
|
||||
assert len(l) == 2
|
||||
assert l == [4, 5,]
|
||||
_testAppendTask = None
|
||||
tm._checkMemLeaks()
|
||||
|
||||
# task uponDeath
|
||||
l = []
|
||||
|
||||
def _uponDeathFunc(task, l=l):
|
||||
l.append(task.name)
|
||||
|
||||
def _testUponDeath(task):
|
||||
return done
|
||||
tm.add(_testUponDeath, 'testUponDeath', uponDeath=_uponDeathFunc)
|
||||
tm.step()
|
||||
assert len(l) == 1
|
||||
assert l == ['testUponDeath']
|
||||
_testUponDeath = None
|
||||
_uponDeathFunc = None
|
||||
tm._checkMemLeaks()
|
||||
|
||||
# task owner
|
||||
class _TaskOwner:
|
||||
def _addTask(self, task):
|
||||
self.addedTaskName = task.name
|
||||
|
||||
def _clearTask(self, task):
|
||||
self.clearedTaskName = task.name
|
||||
to = _TaskOwner()
|
||||
l = []
|
||||
|
||||
def _testOwner(task):
|
||||
return done
|
||||
tm.add(_testOwner, 'testOwner', owner=to)
|
||||
tm.step()
|
||||
assert getattr(to, 'addedTaskName', None) == 'testOwner'
|
||||
assert getattr(to, 'clearedTaskName', None) == 'testOwner'
|
||||
_testOwner = None
|
||||
del to
|
||||
_TaskOwner = None
|
||||
tm._checkMemLeaks()
|
||||
|
||||
doLaterTests = [0,]
|
||||
|
||||
# doLater
|
||||
l = []
|
||||
|
||||
def _testDoLater1(task, l=l):
|
||||
l.append(1)
|
||||
|
||||
def _testDoLater2(task, l=l):
|
||||
l.append(2)
|
||||
|
||||
def _monitorDoLater(task, tm=tm, l=l, doLaterTests=doLaterTests):
|
||||
if task.time > .03:
|
||||
assert l == [1, 2,]
|
||||
doLaterTests[0] -= 1
|
||||
return task.done
|
||||
return task.cont
|
||||
tm.doMethodLater(.01, _testDoLater1, 'testDoLater1')
|
||||
tm.doMethodLater(.02, _testDoLater2, 'testDoLater2')
|
||||
doLaterTests[0] += 1
|
||||
# make sure we run this task after the doLaters if they all occur on the same frame
|
||||
tm.add(_monitorDoLater, 'monitorDoLater', sort=10)
|
||||
_testDoLater1 = None
|
||||
_testDoLater2 = None
|
||||
_monitorDoLater = None
|
||||
# don't check until all the doLaters are finished
|
||||
#tm._checkMemLeaks()
|
||||
|
||||
# doLater sort
|
||||
l = []
|
||||
|
||||
def _testDoLaterPri1(task, l=l):
|
||||
l.append(1)
|
||||
|
||||
def _testDoLaterPri2(task, l=l):
|
||||
l.append(2)
|
||||
|
||||
def _monitorDoLaterPri(task, tm=tm, l=l, doLaterTests=doLaterTests):
|
||||
if task.time > .02:
|
||||
assert l == [1, 2,]
|
||||
doLaterTests[0] -= 1
|
||||
return task.done
|
||||
return task.cont
|
||||
tm.doMethodLater(.01, _testDoLaterPri1, 'testDoLaterPri1', sort=1)
|
||||
tm.doMethodLater(.01, _testDoLaterPri2, 'testDoLaterPri2', sort=2)
|
||||
doLaterTests[0] += 1
|
||||
# make sure we run this task after the doLaters if they all occur on the same frame
|
||||
tm.add(_monitorDoLaterPri, 'monitorDoLaterPri', sort=10)
|
||||
_testDoLaterPri1 = None
|
||||
_testDoLaterPri2 = None
|
||||
_monitorDoLaterPri = None
|
||||
# don't check until all the doLaters are finished
|
||||
#tm._checkMemLeaks()
|
||||
|
||||
# doLater extraArgs
|
||||
l = []
|
||||
|
||||
def _testDoLaterExtraArgs(arg1, l=l):
|
||||
l.append(arg1)
|
||||
|
||||
def _monitorDoLaterExtraArgs(task, tm=tm, l=l, doLaterTests=doLaterTests):
|
||||
if task.time > .02:
|
||||
assert l == [3,]
|
||||
doLaterTests[0] -= 1
|
||||
return task.done
|
||||
return task.cont
|
||||
tm.doMethodLater(.01, _testDoLaterExtraArgs, 'testDoLaterExtraArgs', extraArgs=[3,])
|
||||
doLaterTests[0] += 1
|
||||
# make sure we run this task after the doLaters if they all occur on the same frame
|
||||
tm.add(_monitorDoLaterExtraArgs, 'monitorDoLaterExtraArgs', sort=10)
|
||||
_testDoLaterExtraArgs = None
|
||||
_monitorDoLaterExtraArgs = None
|
||||
# don't check until all the doLaters are finished
|
||||
#tm._checkMemLeaks()
|
||||
|
||||
# doLater appendTask
|
||||
l = []
|
||||
|
||||
def _testDoLaterAppendTask(arg1, task, l=l):
|
||||
assert task.name == 'testDoLaterAppendTask'
|
||||
l.append(arg1)
|
||||
|
||||
def _monitorDoLaterAppendTask(task, tm=tm, l=l, doLaterTests=doLaterTests):
|
||||
if task.time > .02:
|
||||
assert l == [4,]
|
||||
doLaterTests[0] -= 1
|
||||
return task.done
|
||||
return task.cont
|
||||
tm.doMethodLater(.01, _testDoLaterAppendTask, 'testDoLaterAppendTask',
|
||||
extraArgs=[4,], appendTask=True)
|
||||
doLaterTests[0] += 1
|
||||
# make sure we run this task after the doLaters if they all occur on the same frame
|
||||
tm.add(_monitorDoLaterAppendTask, 'monitorDoLaterAppendTask', sort=10)
|
||||
_testDoLaterAppendTask = None
|
||||
_monitorDoLaterAppendTask = None
|
||||
# don't check until all the doLaters are finished
|
||||
#tm._checkMemLeaks()
|
||||
|
||||
# doLater uponDeath
|
||||
l = []
|
||||
|
||||
def _testUponDeathFunc(task, l=l):
|
||||
assert task.name == 'testDoLaterUponDeath'
|
||||
l.append(10)
|
||||
|
||||
def _testDoLaterUponDeath(arg1, l=l):
|
||||
return done
|
||||
|
||||
def _monitorDoLaterUponDeath(task, tm=tm, l=l, doLaterTests=doLaterTests):
|
||||
if task.time > .02:
|
||||
assert l == [10,]
|
||||
doLaterTests[0] -= 1
|
||||
return task.done
|
||||
return task.cont
|
||||
tm.doMethodLater(.01, _testDoLaterUponDeath, 'testDoLaterUponDeath',
|
||||
uponDeath=_testUponDeathFunc)
|
||||
doLaterTests[0] += 1
|
||||
# make sure we run this task after the doLaters if they all occur on the same frame
|
||||
tm.add(_monitorDoLaterUponDeath, 'monitorDoLaterUponDeath', sort=10)
|
||||
_testUponDeathFunc = None
|
||||
_testDoLaterUponDeath = None
|
||||
_monitorDoLaterUponDeath = None
|
||||
# don't check until all the doLaters are finished
|
||||
#tm._checkMemLeaks()
|
||||
|
||||
# doLater owner
|
||||
class _DoLaterOwner:
|
||||
def _addTask(self, task):
|
||||
self.addedTaskName = task.name
|
||||
|
||||
def _clearTask(self, task):
|
||||
self.clearedTaskName = task.name
|
||||
doLaterOwner = _DoLaterOwner()
|
||||
l = []
|
||||
|
||||
def _testDoLaterOwner(l=l):
|
||||
pass
|
||||
|
||||
def _monitorDoLaterOwner(task, tm=tm, l=l, doLaterOwner=doLaterOwner,
|
||||
doLaterTests=doLaterTests):
|
||||
if task.time > .02:
|
||||
assert getattr(doLaterOwner, 'addedTaskName', None) == 'testDoLaterOwner'
|
||||
assert getattr(doLaterOwner, 'clearedTaskName', None) == 'testDoLaterOwner'
|
||||
doLaterTests[0] -= 1
|
||||
return task.done
|
||||
return task.cont
|
||||
tm.doMethodLater(.01, _testDoLaterOwner, 'testDoLaterOwner',
|
||||
owner=doLaterOwner)
|
||||
doLaterTests[0] += 1
|
||||
# make sure we run this task after the doLaters if they all occur on the same frame
|
||||
tm.add(_monitorDoLaterOwner, 'monitorDoLaterOwner', sort=10)
|
||||
_testDoLaterOwner = None
|
||||
_monitorDoLaterOwner = None
|
||||
del doLaterOwner
|
||||
_DoLaterOwner = None
|
||||
# don't check until all the doLaters are finished
|
||||
#tm._checkMemLeaks()
|
||||
|
||||
# run the doLater tests
|
||||
while doLaterTests[0] > 0:
|
||||
tm.step()
|
||||
del doLaterTests
|
||||
tm._checkMemLeaks()
|
||||
|
||||
# getTasks
|
||||
def _testGetTasks(task):
|
||||
return task.cont
|
||||
# No doLaterProcessor in the new world.
|
||||
assert len(tm.getTasks()) == 0
|
||||
tm.add(_testGetTasks, 'testGetTasks1')
|
||||
assert len(tm.getTasks()) == 1
|
||||
assert (tm.getTasks()[0].name == 'testGetTasks1' or
|
||||
tm.getTasks()[1].name == 'testGetTasks1')
|
||||
tm.add(_testGetTasks, 'testGetTasks2')
|
||||
tm.add(_testGetTasks, 'testGetTasks3')
|
||||
assert len(tm.getTasks()) == 3
|
||||
tm.remove('testGetTasks2')
|
||||
assert len(tm.getTasks()) == 2
|
||||
tm.remove('testGetTasks1')
|
||||
tm.remove('testGetTasks3')
|
||||
assert len(tm.getTasks()) == 0
|
||||
_testGetTasks = None
|
||||
tm._checkMemLeaks()
|
||||
|
||||
# getDoLaters
|
||||
def _testGetDoLaters():
|
||||
pass
|
||||
assert len(tm.getDoLaters()) == 0
|
||||
tm.doMethodLater(.1, _testGetDoLaters, 'testDoLater1')
|
||||
assert len(tm.getDoLaters()) == 1
|
||||
assert tm.getDoLaters()[0].name == 'testDoLater1'
|
||||
tm.doMethodLater(.1, _testGetDoLaters, 'testDoLater2')
|
||||
tm.doMethodLater(.1, _testGetDoLaters, 'testDoLater3')
|
||||
assert len(tm.getDoLaters()) == 3
|
||||
tm.remove('testDoLater2')
|
||||
assert len(tm.getDoLaters()) == 2
|
||||
tm.remove('testDoLater1')
|
||||
tm.remove('testDoLater3')
|
||||
assert len(tm.getDoLaters()) == 0
|
||||
_testGetDoLaters = None
|
||||
tm._checkMemLeaks()
|
||||
|
||||
# duplicate named doLaters removed via taskMgr.remove
|
||||
def _testDupNameDoLaters():
|
||||
pass
|
||||
# the doLaterProcessor is always running
|
||||
tm.doMethodLater(.1, _testDupNameDoLaters, 'testDupNameDoLater')
|
||||
tm.doMethodLater(.1, _testDupNameDoLaters, 'testDupNameDoLater')
|
||||
assert len(tm.getDoLaters()) == 2
|
||||
tm.remove('testDupNameDoLater')
|
||||
assert len(tm.getDoLaters()) == 0
|
||||
_testDupNameDoLaters = None
|
||||
tm._checkMemLeaks()
|
||||
|
||||
# duplicate named doLaters removed via remove()
|
||||
def _testDupNameDoLatersRemove():
|
||||
pass
|
||||
# the doLaterProcessor is always running
|
||||
dl1 = tm.doMethodLater(.1, _testDupNameDoLatersRemove, 'testDupNameDoLaterRemove')
|
||||
dl2 = tm.doMethodLater(.1, _testDupNameDoLatersRemove, 'testDupNameDoLaterRemove')
|
||||
assert len(tm.getDoLaters()) == 2
|
||||
dl2.remove()
|
||||
assert len(tm.getDoLaters()) == 1
|
||||
dl1.remove()
|
||||
assert len(tm.getDoLaters()) == 0
|
||||
_testDupNameDoLatersRemove = None
|
||||
# nameDict etc. isn't cleared out right away with task.remove()
|
||||
tm._checkMemLeaks()
|
||||
|
||||
# getTasksNamed
|
||||
def _testGetTasksNamed(task):
|
||||
return task.cont
|
||||
assert len(tm.getTasksNamed('testGetTasksNamed')) == 0
|
||||
tm.add(_testGetTasksNamed, 'testGetTasksNamed')
|
||||
assert len(tm.getTasksNamed('testGetTasksNamed')) == 1
|
||||
assert tm.getTasksNamed('testGetTasksNamed')[0].name == 'testGetTasksNamed'
|
||||
tm.add(_testGetTasksNamed, 'testGetTasksNamed')
|
||||
tm.add(_testGetTasksNamed, 'testGetTasksNamed')
|
||||
assert len(tm.getTasksNamed('testGetTasksNamed')) == 3
|
||||
tm.remove('testGetTasksNamed')
|
||||
assert len(tm.getTasksNamed('testGetTasksNamed')) == 0
|
||||
_testGetTasksNamed = None
|
||||
tm._checkMemLeaks()
|
||||
|
||||
# removeTasksMatching
|
||||
def _testRemoveTasksMatching(task):
|
||||
return task.cont
|
||||
tm.add(_testRemoveTasksMatching, 'testRemoveTasksMatching')
|
||||
assert len(tm.getTasksNamed('testRemoveTasksMatching')) == 1
|
||||
tm.removeTasksMatching('testRemoveTasksMatching')
|
||||
assert len(tm.getTasksNamed('testRemoveTasksMatching')) == 0
|
||||
tm.add(_testRemoveTasksMatching, 'testRemoveTasksMatching1')
|
||||
tm.add(_testRemoveTasksMatching, 'testRemoveTasksMatching2')
|
||||
assert len(tm.getTasksNamed('testRemoveTasksMatching1')) == 1
|
||||
assert len(tm.getTasksNamed('testRemoveTasksMatching2')) == 1
|
||||
tm.removeTasksMatching('testRemoveTasksMatching*')
|
||||
assert len(tm.getTasksNamed('testRemoveTasksMatching1')) == 0
|
||||
assert len(tm.getTasksNamed('testRemoveTasksMatching2')) == 0
|
||||
tm.add(_testRemoveTasksMatching, 'testRemoveTasksMatching1a')
|
||||
tm.add(_testRemoveTasksMatching, 'testRemoveTasksMatching2a')
|
||||
assert len(tm.getTasksNamed('testRemoveTasksMatching1a')) == 1
|
||||
assert len(tm.getTasksNamed('testRemoveTasksMatching2a')) == 1
|
||||
tm.removeTasksMatching('testRemoveTasksMatching?a')
|
||||
assert len(tm.getTasksNamed('testRemoveTasksMatching1a')) == 0
|
||||
assert len(tm.getTasksNamed('testRemoveTasksMatching2a')) == 0
|
||||
_testRemoveTasksMatching = None
|
||||
tm._checkMemLeaks()
|
||||
|
||||
# create Task object and add to mgr
|
||||
l = []
|
||||
|
||||
def _testTaskObj(task, l=l):
|
||||
l.append(None)
|
||||
return task.cont
|
||||
t = Task(_testTaskObj)
|
||||
tm.add(t, 'testTaskObj')
|
||||
tm.step()
|
||||
assert len(l) == 1
|
||||
tm.step()
|
||||
assert len(l) == 2
|
||||
tm.remove('testTaskObj')
|
||||
tm.step()
|
||||
assert len(l) == 2
|
||||
_testTaskObj = None
|
||||
tm._checkMemLeaks()
|
||||
|
||||
# remove Task via task.remove()
|
||||
l = []
|
||||
|
||||
def _testTaskObjRemove(task, l=l):
|
||||
l.append(None)
|
||||
return task.cont
|
||||
t = Task(_testTaskObjRemove)
|
||||
tm.add(t, 'testTaskObjRemove')
|
||||
tm.step()
|
||||
assert len(l) == 1
|
||||
tm.step()
|
||||
assert len(l) == 2
|
||||
t.remove()
|
||||
tm.step()
|
||||
assert len(l) == 2
|
||||
del t
|
||||
_testTaskObjRemove = None
|
||||
tm._checkMemLeaks()
|
||||
|
||||
# this test fails, and it's not clear what the correct behavior should be.
|
||||
# sort passed to Task.__init__ is always overridden by taskMgr.add()
|
||||
# even if no sort is specified, and calling Task.setSort() has no
|
||||
# effect on the taskMgr's behavior.
|
||||
# set/get Task sort
|
||||
#l = []
|
||||
#def _testTaskObjSort(arg, task, l=l):
|
||||
# l.append(arg)
|
||||
# return task.cont
|
||||
#t1 = Task(_testTaskObjSort, sort=1)
|
||||
#t2 = Task(_testTaskObjSort, sort=2)
|
||||
#tm.add(t1, 'testTaskObjSort1', extraArgs=['a',], appendTask=True)
|
||||
#tm.add(t2, 'testTaskObjSort2', extraArgs=['b',], appendTask=True)
|
||||
#tm.step()
|
||||
#assert len(l) == 2
|
||||
#assert l == ['a', 'b']
|
||||
#assert t1.getSort() == 1
|
||||
#assert t2.getSort() == 2
|
||||
#t1.setSort(3)
|
||||
#assert t1.getSort() == 3
|
||||
#tm.step()
|
||||
#assert len(l) == 4
|
||||
#assert l == ['a', 'b', 'b', 'a',]
|
||||
#t1.remove()
|
||||
#t2.remove()
|
||||
#tm.step()
|
||||
#assert len(l) == 4
|
||||
#del t1
|
||||
#del t2
|
||||
#_testTaskObjSort = None
|
||||
#tm._checkMemLeaks()
|
||||
|
||||
del l
|
||||
tm.destroy()
|
||||
del tm
|
||||
|
||||
|
||||
if __debug__:
|
||||
def checkLeak():
|
||||
|
|
|
|||
|
|
@ -358,8 +358,7 @@ class FSMInspector(AppShell):
|
|||
|
||||
def printLayout(self):
|
||||
dict = self.stateInspectorDict
|
||||
keys = list(dict.keys())
|
||||
keys.sort()
|
||||
keys = sorted(dict)
|
||||
print("ClassicFSM.ClassicFSM('%s', [" % self.name)
|
||||
for key in keys[:-1]:
|
||||
si = dict[key]
|
||||
|
|
|
|||
|
|
@ -95,9 +95,7 @@ class Inspector:
|
|||
|
||||
def initializePartsList(self):
|
||||
self._partsList = []
|
||||
keys = self.namedParts()
|
||||
keys.sort()
|
||||
for each in keys:
|
||||
for each in sorted(self.namedParts()):
|
||||
self._partsList.append(each)
|
||||
#if not callable(getattr(self.object, each)):
|
||||
# self._partsList.append(each)
|
||||
|
|
@ -202,9 +200,7 @@ class DictionaryInspector(Inspector):
|
|||
|
||||
def initializePartsList(self):
|
||||
Inspector.initializePartsList(self)
|
||||
keys = list(self.object.keys())
|
||||
keys.sort()
|
||||
for each in keys:
|
||||
for each in sorted(self.object):
|
||||
self._partsList.append(each)
|
||||
|
||||
def partNumber(self, partNumber):
|
||||
|
|
|
|||
|
|
@ -1174,9 +1174,7 @@ class ParticlePanel(AppShell):
|
|||
self.particlesLabelMenu.add_separator()
|
||||
# Add in a checkbutton for each effect (to toggle on/off)
|
||||
particles = self.particleEffect.getParticlesList()
|
||||
names = [x.getName() for x in particles]
|
||||
names.sort()
|
||||
for name in names:
|
||||
for name in sorted(x.getName() for x in particles):
|
||||
particle = self.particleEffect.getParticlesNamed(name)
|
||||
self.particlesLabelMenu.add_command(
|
||||
label = name,
|
||||
|
|
@ -1199,9 +1197,7 @@ class ParticlePanel(AppShell):
|
|||
self.forceGroupLabelMenu.add_separator()
|
||||
# Add in a checkbutton for each effect (to toggle on/off)
|
||||
forceGroupList = self.particleEffect.getForceGroupList()
|
||||
names = [x.getName() for x in forceGroupList]
|
||||
names.sort()
|
||||
for name in names:
|
||||
for name in sorted(x.getName() for x in forceGroupList):
|
||||
force = self.particleEffect.getForceGroupNamed(name)
|
||||
self.forceGroupLabelMenu.add_command(
|
||||
label = name,
|
||||
|
|
@ -2913,21 +2909,3 @@ class ParticlePanel(AppShell):
|
|||
min = 0.01,
|
||||
value = force.getRadius())
|
||||
self.createForceActiveWidget(frame, pageName, forceName, force)
|
||||
|
||||
######################################################################
|
||||
|
||||
|
||||
# Create demo in root window for testing.
|
||||
if __name__ == '__main__':
|
||||
try:
|
||||
base
|
||||
except NameError:
|
||||
from direct.showbase.ShowBase import ShowBase
|
||||
base = ShowBase()
|
||||
|
||||
root = Pmw.initialise()
|
||||
pp = ParticlePanel()
|
||||
base.pp=pp
|
||||
#ve = VectorEntry(Toplevel(), relief = GROOVE)
|
||||
#ve.pack()
|
||||
base.run()
|
||||
|
|
|
|||
|
|
@ -786,11 +786,3 @@ class Placer(AppShell):
|
|||
|
||||
def place(nodePath):
|
||||
return Placer(nodePath = nodePath)
|
||||
|
||||
######################################################################
|
||||
|
||||
|
||||
# Create demo in root window for testing.
|
||||
if __name__ == '__main__':
|
||||
root = Pmw.initialise()
|
||||
widget = Placer()
|
||||
|
|
|
|||
|
|
@ -151,10 +151,8 @@ class TaskManagerWidget(DirectObject):
|
|||
# Get a list of task names
|
||||
taskNames = []
|
||||
self.__taskDict = {}
|
||||
tasks = self.taskMgr.getTasks()
|
||||
tasks.sort(key = lambda t: t.getName())
|
||||
count = 0
|
||||
for task in tasks:
|
||||
for task in sorted(self.taskMgr.getTasks(), key=lambda t: t.getName()):
|
||||
taskNames.append(task.getName())
|
||||
self.__taskDict[count] = task
|
||||
count += 1
|
||||
|
|
|
|||
|
|
@ -21,11 +21,11 @@ import builtins
|
|||
|
||||
# Create toplevel widget dictionary
|
||||
if not hasattr(builtins, "widgetDict"):
|
||||
builtins.widgetDict = {}
|
||||
builtins.widgetDict = {} # type: ignore[attr-defined]
|
||||
|
||||
# Create toplevel variable dictionary
|
||||
if not hasattr(builtins, "variableDict"):
|
||||
builtins.variableDict = {}
|
||||
builtins.variableDict = {} # type: ignore[attr-defined]
|
||||
|
||||
|
||||
def resetWidgetDict():
|
||||
|
|
@ -550,7 +550,3 @@ class TestAppShell(AppShell):
|
|||
def createInterface(self):
|
||||
self.createButtons()
|
||||
self.createMain()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
test = TestAppShell(balloon_state='none')
|
||||
|
|
|
|||
|
|
@ -422,18 +422,3 @@ class DialWidget(Pmw.MegaWidget):
|
|||
""" User redefinable callback executed on button release """
|
||||
if self['postCallback']:
|
||||
self['postCallback'](*self['callbackData'])
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
tl = tk.Toplevel()
|
||||
d = Dial(tl)
|
||||
d2 = Dial(tl, dial_numSegments = 12, max = 360,
|
||||
dial_fRollover = 0, value = 180)
|
||||
d3 = Dial(tl, dial_numSegments = 12, max = 90, min = -90,
|
||||
dial_fRollover = 0)
|
||||
d4 = Dial(tl, dial_numSegments = 16, max = 256,
|
||||
dial_fRollover = 0)
|
||||
d.pack(expand = 1, fill = tk.X)
|
||||
d2.pack(expand = 1, fill = tk.X)
|
||||
d3.pack(expand = 1, fill = tk.X)
|
||||
d4.pack(expand = 1, fill = tk.X)
|
||||
|
|
|
|||
|
|
@ -517,45 +517,3 @@ def rgbPanel(nodePath, callback = None):
|
|||
messenger.send('RGBPanel_setColor', [nodePath, r, g, b, a])
|
||||
esg['postCallback'] = onRelease
|
||||
return esg
|
||||
|
||||
|
||||
## SAMPLE CODE
|
||||
if __name__ == '__main__':
|
||||
# Initialise Tkinter and Pmw.
|
||||
root = tk.Toplevel()
|
||||
root.title('Pmw EntryScale demonstration')
|
||||
|
||||
# Dummy command
|
||||
def printVal(val):
|
||||
print(val)
|
||||
|
||||
# Create and pack a EntryScale megawidget.
|
||||
mega1 = EntryScale(root, command = printVal)
|
||||
mega1.pack(side = 'left', expand = 1, fill = 'x')
|
||||
|
||||
# These are things you can set/configure
|
||||
# Starting value for entryScale
|
||||
#mega1['value'] = 123.456
|
||||
#mega1['text'] = 'Drive delta X'
|
||||
#mega1['min'] = 0.0
|
||||
#mega1['max'] = 1000.0
|
||||
#mega1['resolution'] = 1.0
|
||||
# To change the color of the label:
|
||||
#mega1.label['foreground'] = 'Red'
|
||||
# Max change/update, default is 100
|
||||
# To have really fine control, for example
|
||||
# mega1['maxVelocity'] = 0.1
|
||||
# Number of digits to the right of the decimal point, default = 2
|
||||
# mega1['numDigits'] = 5
|
||||
|
||||
# To create a entryScale group to set an RGBA value:
|
||||
group1 = EntryScaleGroup(root, dim = 4,
|
||||
title = 'Simple RGBA Panel',
|
||||
labels = ('R', 'G', 'B', 'A'),
|
||||
Valuator_min = 0.0,
|
||||
Valuator_max = 255.0,
|
||||
Valuator_resolution = 1.0,
|
||||
command = printVal)
|
||||
|
||||
# Uncomment this if you aren't running in IDLE
|
||||
#root.mainloop()
|
||||
|
|
|
|||
|
|
@ -329,42 +329,3 @@ class FloaterGroup(Pmw.MegaToplevel):
|
|||
|
||||
def reset(self):
|
||||
self.set(self['value'])
|
||||
|
||||
|
||||
## SAMPLE CODE
|
||||
if __name__ == '__main__':
|
||||
# Initialise Tkinter and Pmw.
|
||||
root = tk.Toplevel()
|
||||
root.title('Pmw Floater demonstration')
|
||||
|
||||
# Dummy command
|
||||
def printVal(val):
|
||||
print(val)
|
||||
|
||||
# Create and pack a Floater megawidget.
|
||||
mega1 = Floater(root, command = printVal)
|
||||
mega1.pack(side = 'left', expand = 1, fill = 'x')
|
||||
|
||||
# These are things you can set/configure
|
||||
# Starting value for floater
|
||||
#mega1['value'] = 123.456
|
||||
#mega1['text'] = 'Drive delta X'
|
||||
# To change the color of the label:
|
||||
#mega1.label['foreground'] = 'Red'
|
||||
# Max change/update, default is 100
|
||||
# To have really fine control, for example
|
||||
#mega1['maxVelocity'] = 0.1
|
||||
# Number of digits to the right of the decimal point, default = 2
|
||||
#mega1['numDigits'] = 5
|
||||
|
||||
# To create a floater group to set an RGBA value:
|
||||
group1 = FloaterGroup(root, dim = 4,
|
||||
title = 'Simple RGBA Panel',
|
||||
labels = ('R', 'G', 'B', 'A'),
|
||||
Valuator_min = 0.0,
|
||||
Valuator_max = 255.0,
|
||||
Valuator_resolution = 1.0,
|
||||
command = printVal)
|
||||
|
||||
# Uncomment this if you aren't running in IDLE
|
||||
#root.mainloop()
|
||||
|
|
|
|||
|
|
@ -329,17 +329,3 @@ class ColorEntry(VectorEntry):
|
|||
initialcolor = tuple(self.get()[:3]))[0]
|
||||
if color:
|
||||
self.set((color[0], color[1], color[2], self.getAt(3)))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
root = tk.Toplevel()
|
||||
root.title('Vector Widget demo')
|
||||
|
||||
ve = VectorEntry(root)
|
||||
ve.pack()
|
||||
v3e = Vector3Entry(root)
|
||||
v3e.pack()
|
||||
v4e = Vector4Entry(root)
|
||||
v4e.pack()
|
||||
ce = ColorEntry(root)
|
||||
ce.pack()
|
||||
|
|
|
|||
|
|
@ -21,8 +21,7 @@ class WidgetPropertiesDialog(tk.Toplevel):
|
|||
self.propertyDict = propertyDict
|
||||
self.propertyList = propertyList
|
||||
if self.propertyList is None:
|
||||
self.propertyList = list(self.propertyDict.keys())
|
||||
self.propertyList.sort()
|
||||
self.propertyList = sorted(self.propertyDict)
|
||||
# Use default parent if none specified
|
||||
if not parent:
|
||||
parent = tk._default_root
|
||||
|
|
|
|||
|
|
@ -6,6 +6,8 @@ Modified by gjeon.
|
|||
Modified by Summer 2010 Carnegie Mellon University ETC PandaLE team: fixed a bug in Viewport.Close
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
__all__ = ["Viewport", "ViewportManager"]
|
||||
|
||||
from panda3d.core import (
|
||||
|
|
@ -36,7 +38,7 @@ VPPERSPECTIVE = 13
|
|||
|
||||
class ViewportManager:
|
||||
"""Manages the global viewport stuff."""
|
||||
viewports = []
|
||||
viewports: list[Viewport] = []
|
||||
gsg = None
|
||||
|
||||
@staticmethod
|
||||
|
|
@ -58,7 +60,7 @@ class ViewportManager:
|
|||
v.Layout(*args, **kwargs)
|
||||
|
||||
|
||||
class Viewport(WxPandaWindow, DirectObject):
|
||||
class Viewport(WxPandaWindow, DirectObject): # type: ignore[misc, valid-type]
|
||||
"""Class representing a 3D Viewport."""
|
||||
CREATENEW = CREATENEW
|
||||
VPLEFT = VPLEFT
|
||||
|
|
|
|||
|
|
@ -1,2 +1,3 @@
|
|||
from direct.showbase.ShowBaseGlobal import base
|
||||
from .WxPandaShell import WxPandaShell
|
||||
base.app = WxPandaShell()
|
||||
base.app = WxPandaShell() # type: ignore[attr-defined]
|
||||
|
|
|
|||
|
|
@ -81,7 +81,7 @@ class EmbeddedPandaWindow(wx.Window):
|
|||
if not hasattr(wxgl, 'GLCanvas'):
|
||||
OpenGLPandaWindow = None
|
||||
else:
|
||||
class OpenGLPandaWindow(wxgl.GLCanvas):
|
||||
class OpenGLPandaWindow(wxgl.GLCanvas): # type: ignore[no-redef]
|
||||
""" This class implements a Panda3D "window" that actually draws
|
||||
within the wx GLCanvas object. It is supported whenever OpenGL is
|
||||
Panda's rendering engine, and GLCanvas is available in wx. """
|
||||
|
|
|
|||
|
|
@ -0,0 +1,200 @@
|
|||
Panda3D C++ Style Guide
|
||||
=======================
|
||||
|
||||
Rather than try to justify every decision made, this document attempts to be as
|
||||
at-a-glance as possible. Examples provided where necessary to illustrate best
|
||||
practices.
|
||||
|
||||
Note that this style guide is, for the most part, not very strict, and there
|
||||
are exceptions to every rule. However, this guide does serve to illustrate the
|
||||
preferred style for the entire codebase.
|
||||
|
||||
Naming conventions
|
||||
------------------
|
||||
|
||||
- **Classes**: `CamelCaseFirstUpper`
|
||||
- **Filenames**: `lowerCamelCase.h`, `lowerCamelCase.cxx`
|
||||
- Note, every header file must have a unique filename. They are all
|
||||
installed into the same path.
|
||||
- **Functions**: `lower_snake_case_without_prefix`
|
||||
- **Local variables**: `lower_snake_case_without_prefix`
|
||||
- **Member variables**: `_lower_snake_case_with_initial_score`
|
||||
- **Enum constants**: `SE_enum_value` (for an enum type named SomeEnum)
|
||||
- **Enum class constants**: `ENUM_VALUE`
|
||||
|
||||
Indentation
|
||||
-----------
|
||||
|
||||
Always use two spaces to indent. Tabs should never appear in a C++ file.
|
||||
|
||||
Access modifiers (`public`/`private`/`protected`/`PUBLISHED`) are never
|
||||
indented relative to the class they are in, and do not affect the indentation
|
||||
of the surrounding lines.
|
||||
|
||||
Spaces
|
||||
------
|
||||
|
||||
Always put one space after a control keyword, before the condition's
|
||||
parentheses. Don't pad the inside of parentheses with spaces unless there are
|
||||
several nested parenthetical expressions and the extra spaces contribute
|
||||
substantially to readability.
|
||||
|
||||
if (x == y) {
|
||||
|
||||
Don't place a space after a function name (declarations, definitions, or calls).
|
||||
|
||||
void function_name();
|
||||
...
|
||||
function_name();
|
||||
|
||||
Always place a space after each comma in an arguments list.
|
||||
|
||||
function_call(x, y, z);
|
||||
|
||||
Always pad binary operators with a space on either side.
|
||||
|
||||
a || b
|
||||
|
||||
Never end a line with trailing whitespace.
|
||||
|
||||
Function definitions
|
||||
--------------------
|
||||
|
||||
The recipe for a function definition is:
|
||||
|
||||
1. JavaDoc comment describing the purpose of the function
|
||||
2. Function return value and class
|
||||
3. **At the beginning of its own line,** the function's name, followed by the
|
||||
parameter list and anything else necessary for the function's signature.
|
||||
4. Opening brace on the same line, not its own line.
|
||||
5. Single empty line before next definition.
|
||||
|
||||
For example:
|
||||
|
||||
/**
|
||||
* String documenting the function, in JavaDoc style.
|
||||
*/
|
||||
void ClassName::
|
||||
function_name(int x, int y) const {
|
||||
...
|
||||
}
|
||||
|
||||
/**
|
||||
* ...
|
||||
*/
|
||||
...
|
||||
|
||||
If the function is a constructor with an initializer list, the `:` goes on the
|
||||
same line as the constructor name, and the initializers are listed *one per
|
||||
line*, indented by two spaces.
|
||||
|
||||
ClassName::
|
||||
ClassName() :
|
||||
_a("a"),
|
||||
_b("b"),
|
||||
_c("c")
|
||||
{
|
||||
}
|
||||
|
||||
Empty function bodies in a .cxx/.I file still contain a single line break (i.e.
|
||||
to put `}` on its own line). In a .h file, an empty function can be given as
|
||||
`{}`
|
||||
|
||||
Braces
|
||||
------
|
||||
|
||||
Always put an opening `{` on the same line as the statement that calls for the
|
||||
brace. There is exactly one exception to this: constructors with initializer
|
||||
lists.
|
||||
|
||||
SomeClass::
|
||||
SomeClass() :
|
||||
_one(1),
|
||||
_two(2)
|
||||
{
|
||||
if (_one < _two) {
|
||||
...
|
||||
}
|
||||
}
|
||||
|
||||
Comments
|
||||
--------
|
||||
|
||||
Comments should be properly-formatted English, with proper capitalization and
|
||||
punctuation rules. There are two spaces between sentences.
|
||||
|
||||
Note that `//` is preferred over `/*` except in some special circumstances.
|
||||
|
||||
Except for commented-out lines of code, there should be a space between the
|
||||
first word and the `//`.
|
||||
|
||||
// The following line is commented out.
|
||||
//if (value == 0) {
|
||||
|
||||
Line limits and continuations
|
||||
-----------------------------
|
||||
|
||||
Lines should be limited to 80 columns. This is not a hard limit, and lines
|
||||
should not be wrapped if doing so hurts readability, except comments, which
|
||||
should always be wrapped.
|
||||
|
||||
Continuation lines shall be aligned to the same column as appropriate, or
|
||||
indented two spaces otherwise:
|
||||
|
||||
if ((a &&
|
||||
b) ||
|
||||
c) {
|
||||
...
|
||||
}
|
||||
|
||||
When choosing where to break a line, these are the preferred places, from best
|
||||
to worst:
|
||||
|
||||
1. If inside a comment, break the comment to as many lines as appropriate, but
|
||||
only after moving the comment to its own line.
|
||||
2. After a comma in an argument/parameter list.
|
||||
3. After a binary operator (leaving the binary operator at the end of the line)
|
||||
4. In a function declaration, after the function's return type but before the
|
||||
function's name. (Indented by two spaces.)
|
||||
5. In a log statement with `<<`, before a `<<`. (Avoid ending a line with `<<`)
|
||||
6. Around a string literal, at a natural word boundary, with a space left on
|
||||
the previous line (e.g. `"This is a "` / `"continued string literal."`)
|
||||
7. After the `=` in an assignment operator.
|
||||
8. As a last resort, after the opening `(` in a function call.
|
||||
|
||||
If none of these rules can apply cleanly, it is okay to have lines extend past
|
||||
the 80-column boundary.
|
||||
|
||||
Alignment
|
||||
---------
|
||||
|
||||
Avoid the temptation to align multiple assignments in consecutive lines of code.
|
||||
While it may look neater, it decreases the maintainability of the code.
|
||||
|
||||
Asterisks and ampersands indicating a pointer or reference type should always
|
||||
be aligned against the name, and not the type:
|
||||
|
||||
Type *x, &y;
|
||||
|
||||
Grouping
|
||||
--------
|
||||
|
||||
Try to group logically-similar lines, separating them with a single blank line.
|
||||
|
||||
Modern language features
|
||||
------------------------
|
||||
|
||||
Panda3D is a C++11 project. The use of the following modern language features
|
||||
is greatly encouraged:
|
||||
|
||||
1. `nullptr` over `NULL`
|
||||
2. `std::move` and move semantics
|
||||
3. Range-based for loops
|
||||
|
||||
Using `auto` can be okay, such as when storing an iterator, but consider
|
||||
creating a typedef for the container type instead.
|
||||
|
||||
Avoid using `std::function` in cases where a lambda can be accepted directly
|
||||
(using a template function), since it has extra overhead over lambdas.
|
||||
|
||||
C++14 and C++17 features should be avoided for now.
|
||||
|
|
@ -16,6 +16,7 @@ if(MSVC)
|
|||
else()
|
||||
set(CMAKE_C_FLAGS_STANDARD "-O3")
|
||||
set(CMAKE_CXX_FLAGS_STANDARD "-O3")
|
||||
set(CMAKE_OBJCXX_FLAGS_STANDARD "-O3")
|
||||
endif()
|
||||
set(CMAKE_SHARED_LINKER_FLAGS_STANDARD "")
|
||||
set(CMAKE_MODULE_LINKER_FLAGS_STANDARD "")
|
||||
|
|
@ -27,6 +28,8 @@ if(CMAKE_CXX_COMPILER_ID MATCHES "(AppleClang|Clang)")
|
|||
"${CMAKE_C_FLAGS_DEBUG} -fprofile-instr-generate -fcoverage-mapping")
|
||||
set(CMAKE_CXX_FLAGS_COVERAGE
|
||||
"${CMAKE_CXX_FLAGS_DEBUG} -fprofile-instr-generate -fcoverage-mapping")
|
||||
set(CMAKE_OBJCXX_FLAGS_COVERAGE
|
||||
"${CMAKE_OBJCXX_FLAGS_DEBUG} -fprofile-instr-generate -fcoverage-mapping")
|
||||
|
||||
set(CMAKE_SHARED_LINKER_FLAGS_COVERAGE
|
||||
"${CMAKE_SHARED_LINKER_FLAGS_DEBUG} -fprofile-instr-generate")
|
||||
|
|
@ -101,11 +104,14 @@ endif()
|
|||
# Set warning levels
|
||||
if(MSVC)
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /W3")
|
||||
set(CMAKE_CCXX_FLAGS "${CMAKE_CXX_FLAGS} /W3")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W3")
|
||||
|
||||
else()
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall")
|
||||
if(APPLE)
|
||||
set(CMAKE_OBJCXX_FLAGS "${CMAKE_OBJCXX_FLAGS} -Wall")
|
||||
endif()
|
||||
|
||||
endif()
|
||||
|
||||
|
|
@ -133,6 +139,14 @@ if(CMAKE_CXX_COMPILER_ID MATCHES "(GNU|Clang)")
|
|||
set(CMAKE_CXX_FLAGS_MINSIZEREL "${CMAKE_CXX_FLAGS_MINSIZEREL} ${release_flags}")
|
||||
set(CMAKE_CXX_FLAGS_STANDARD "${CMAKE_CXX_FLAGS_STANDARD} ${standard_flags}")
|
||||
|
||||
if(APPLE)
|
||||
set(CMAKE_OBJCXX_FLAGS "${CMAKE_OBJCXX_FLAGS} ${global_flags}")
|
||||
set(CMAKE_OBJCXX_FLAGS_RELEASE "${CMAKE_OBJCXX_FLAGS_RELEASE} ${global_flags}")
|
||||
set(CMAKE_OBJCXX_FLAGS_RELWITHDEBINFO "${CMAKE_OBJCXX_FLAGS_RELWITHDEBINFO} ${global_flags}")
|
||||
set(CMAKE_OBJCXX_FLAGS_MINSIZEREL "${CMAKE_OBJCXX_FLAGS_MINSIZEREL} ${global_flags}")
|
||||
set(CMAKE_OBJCXX_FLAGS_STANDARD "${CMAKE_OBJCXX_FLAGS_STANDARD} ${global_flags}")
|
||||
endif()
|
||||
|
||||
if(MSVC)
|
||||
# Clang behaving as MSVC
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-unused-command-line-argument")
|
||||
|
|
@ -151,6 +165,7 @@ endif()
|
|||
# and stops us from identifying cases where ENABLE_EXPORTS is needed.
|
||||
set(CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "")
|
||||
set(CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS "")
|
||||
set(CMAKE_SHARED_LIBRARY_LINK_OBJCXX_FLAGS "")
|
||||
|
||||
# As long as we're figuring out compiler flags, figure out the flags for
|
||||
# turning C++ exception support on and off
|
||||
|
|
|
|||
|
|
@ -518,7 +518,9 @@ package_status(OPUS "Opus")
|
|||
#
|
||||
|
||||
# FMOD Ex
|
||||
find_package(FMODEx QUIET)
|
||||
if(NOT APPLE)
|
||||
find_package(FMODEx QUIET)
|
||||
endif()
|
||||
|
||||
package_option(FMODEx
|
||||
"This enables support for the FMOD Ex sound library,
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -2971,8 +2971,17 @@ base_specification:
|
|||
;
|
||||
|
||||
enum:
|
||||
enum_decl '{' enum_body '}'
|
||||
enum_decl
|
||||
{
|
||||
if (current_enum->_scope != nullptr) {
|
||||
push_scope(current_enum->_scope);
|
||||
}
|
||||
}
|
||||
'{' enum_body '}'
|
||||
{
|
||||
if (current_enum->_scope != nullptr) {
|
||||
pop_scope();
|
||||
}
|
||||
$$ = current_enum;
|
||||
current_enum = nullptr;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -130,6 +130,7 @@
|
|||
// flag to link in Python, we'll just excerpt the forward declaration of
|
||||
// PyObject.
|
||||
typedef struct _object PyObject;
|
||||
typedef struct _typeobject PyTypeObject;
|
||||
|
||||
#ifndef HAVE_EIGEN
|
||||
// If we don't have the Eigen library, don't define LINMATH_ALIGN.
|
||||
|
|
|
|||
|
|
@ -155,7 +155,7 @@ deallocate_array(void *ptr) {
|
|||
/**
|
||||
* Returns the internal void pointer that is stored for interrogate's benefit.
|
||||
*/
|
||||
PyObject *TypeHandle::
|
||||
PyTypeObject *TypeHandle::
|
||||
get_python_type() const {
|
||||
TypeRegistryNode *rnode = TypeRegistry::ptr()->look_up(*this, nullptr);
|
||||
if (rnode != nullptr) {
|
||||
|
|
@ -164,6 +164,22 @@ get_python_type() const {
|
|||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a Python wrapper object corresponding to the given C++ pointer.
|
||||
*/
|
||||
PyObject *TypeHandle::
|
||||
wrap_python(void *ptr, PyTypeObject *cast_from) const {
|
||||
if (ptr == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
TypeRegistryNode *rnode = TypeRegistry::ptr()->look_up(*this, nullptr);
|
||||
if (rnode != nullptr) {
|
||||
return rnode->wrap_python(ptr, cast_from);
|
||||
} else {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
std::ostream &
|
||||
|
|
|
|||
|
|
@ -140,7 +140,8 @@ PUBLISHED:
|
|||
|
||||
public:
|
||||
#ifdef HAVE_PYTHON
|
||||
PyObject *get_python_type() const;
|
||||
PyTypeObject *get_python_type() const;
|
||||
PyObject *wrap_python(void *ptr, PyTypeObject *cast_from = nullptr) const;
|
||||
#endif // HAVE_PYTHON
|
||||
|
||||
void *allocate_array(size_t size) RETURNS_ALIGNED(MEMORY_HOOK_ALIGNMENT);
|
||||
|
|
|
|||
|
|
@ -46,7 +46,26 @@ __reduce__() const {
|
|||
|
||||
// If we have a Python binding registered for it, that's the preferred method,
|
||||
// since it ensures that the appropriate module gets loaded by pickle.
|
||||
PyObject *py_type = _this->get_python_type();
|
||||
PyTypeObject *py_type = _this->get_python_type();
|
||||
if (py_type != nullptr && py_type->tp_dict != nullptr) {
|
||||
// Look for a get_class_type method, if it returns this handle.
|
||||
PyObject *func = PyDict_GetItemString(py_type->tp_dict, "get_class_type");
|
||||
if (func != nullptr && PyCallable_Check(func)) {
|
||||
PyObject *result = PyObject_CallNoArgs(func);
|
||||
TypeHandle *result_handle = nullptr;
|
||||
if (result == nullptr) {
|
||||
// Never mind.
|
||||
PyErr_Clear();
|
||||
}
|
||||
else if (DtoolInstance_GetPointer(result, result_handle, Dtool_TypeHandle) &&
|
||||
*result_handle == *_this) {
|
||||
// It returned the correct result, so we can use this.
|
||||
return Py_BuildValue("O()", func);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Fall back to TypeHandle::make(), if would produce the correct result.
|
||||
if (py_type != nullptr && *_this == ((Dtool_PyTypedObject *)py_type)->_type) {
|
||||
PyObject *func = PyObject_GetAttrString((PyObject *)&Dtool_TypeHandle, "make");
|
||||
return Py_BuildValue("N(O)", func, py_type);
|
||||
|
|
|
|||
|
|
@ -213,12 +213,13 @@ record_alternate_name(TypeHandle type, const string &name) {
|
|||
* of interrogate, which expects this to contain a Dtool_PyTypedObject.
|
||||
*/
|
||||
void TypeRegistry::
|
||||
record_python_type(TypeHandle type, PyObject *python_type) {
|
||||
record_python_type(TypeHandle type, PyTypeObject *cls, PythonWrapFunc *wrap_func) {
|
||||
_lock.lock();
|
||||
|
||||
TypeRegistryNode *rnode = look_up(type, nullptr);
|
||||
if (rnode != nullptr) {
|
||||
rnode->_python_type = python_type;
|
||||
rnode->_python_type = cls;
|
||||
rnode->_python_wrap_func = wrap_func;
|
||||
}
|
||||
|
||||
_lock.unlock();
|
||||
|
|
|
|||
|
|
@ -40,13 +40,18 @@ public:
|
|||
// convenience function, defined in register_type.h.
|
||||
bool register_type(TypeHandle &type_handle, const std::string &name);
|
||||
|
||||
#ifdef HAVE_PYTHON
|
||||
typedef PyObject *PythonWrapFunc(void *ptr, PyTypeObject *cast_from);
|
||||
#endif
|
||||
|
||||
PUBLISHED:
|
||||
TypeHandle register_dynamic_type(const std::string &name);
|
||||
|
||||
void record_derivation(TypeHandle child, TypeHandle parent);
|
||||
void record_alternate_name(TypeHandle type, const std::string &name);
|
||||
#ifdef HAVE_PYTHON
|
||||
void record_python_type(TypeHandle type, PyObject *python_type);
|
||||
void record_python_type(TypeHandle type, PyTypeObject *cls,
|
||||
PythonWrapFunc *wrap_func);
|
||||
#endif
|
||||
|
||||
TypeHandle find_type(const std::string &name) const;
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@
|
|||
/**
|
||||
* Returns the Python type object associated with this node.
|
||||
*/
|
||||
INLINE PyObject *TypeRegistryNode::
|
||||
INLINE PyTypeObject *TypeRegistryNode::
|
||||
get_python_type() const {
|
||||
if (_python_type != nullptr || _parent_classes.empty()) {
|
||||
return _python_type;
|
||||
|
|
@ -24,6 +24,23 @@ get_python_type() const {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a Python wrapper object corresponding to the given C++ pointer.
|
||||
*/
|
||||
INLINE PyObject *TypeRegistryNode::
|
||||
wrap_python(void *ptr, PyTypeObject *cast_from) const {
|
||||
if (_python_wrap_func != nullptr) {
|
||||
return _python_wrap_func(ptr, cast_from);
|
||||
}
|
||||
else if (_parent_classes.empty()) {
|
||||
return nullptr;
|
||||
}
|
||||
else {
|
||||
// Recurse through parent classes.
|
||||
return r_wrap_python(ptr, cast_from);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -311,16 +311,14 @@ r_build_subtrees(TypeRegistryNode *top, int bit_count,
|
|||
* Recurses through the parent nodes to find the best Python type object to
|
||||
* represent objects of this type.
|
||||
*/
|
||||
PyObject *TypeRegistryNode::
|
||||
PyTypeObject *TypeRegistryNode::
|
||||
r_get_python_type() const {
|
||||
Classes::const_iterator ni;
|
||||
for (ni = _parent_classes.begin(); ni != _parent_classes.end(); ++ni) {
|
||||
const TypeRegistryNode *parent = *ni;
|
||||
for (const TypeRegistryNode *parent : _parent_classes) {
|
||||
if (parent->_python_type != nullptr) {
|
||||
return parent->_python_type;
|
||||
|
||||
} else if (!parent->_parent_classes.empty()) {
|
||||
PyObject *py_type = parent->r_get_python_type();
|
||||
}
|
||||
else if (!parent->_parent_classes.empty()) {
|
||||
PyTypeObject *py_type = parent->r_get_python_type();
|
||||
if (py_type != nullptr) {
|
||||
return py_type;
|
||||
}
|
||||
|
|
@ -330,6 +328,28 @@ r_get_python_type() const {
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a Python wrapper object to represent the given C++ pointer, which
|
||||
* must be exactly of the correct type, unless cast_from is set to one of its
|
||||
* base classes, in which case it will be cast appropriately.
|
||||
*/
|
||||
PyObject *TypeRegistryNode::
|
||||
r_wrap_python(void *ptr, PyTypeObject *cast_from) const {
|
||||
for (const TypeRegistryNode *parent : _parent_classes) {
|
||||
if (parent->_python_wrap_func != nullptr) {
|
||||
return parent->_python_wrap_func(ptr, cast_from);
|
||||
}
|
||||
else if (!parent->_parent_classes.empty()) {
|
||||
PyObject *wrapper = parent->r_wrap_python(ptr, cast_from);
|
||||
if (wrapper != nullptr) {
|
||||
return wrapper;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/**
|
||||
* A recursive function to double-check the result of is_derived_from(). This
|
||||
* is the slow, examine-the-whole-graph approach, as opposed to the clever and
|
||||
|
|
|
|||
|
|
@ -30,6 +30,8 @@
|
|||
*/
|
||||
class EXPCL_DTOOL_DTOOLBASE TypeRegistryNode {
|
||||
public:
|
||||
typedef PyObject *PythonWrapFunc(void *ptr, PyTypeObject *cast_from);
|
||||
|
||||
TypeRegistryNode(TypeHandle handle, const std::string &name, TypeHandle &ref);
|
||||
|
||||
static bool is_derived_from(const TypeRegistryNode *child,
|
||||
|
|
@ -38,7 +40,8 @@ public:
|
|||
static TypeHandle get_parent_towards(const TypeRegistryNode *child,
|
||||
const TypeRegistryNode *base);
|
||||
|
||||
INLINE PyObject *get_python_type() const;
|
||||
INLINE PyTypeObject *get_python_type() const;
|
||||
INLINE PyObject *wrap_python(void *ptr, PyTypeObject *cast_from) const;
|
||||
|
||||
void clear_subtree();
|
||||
void define_subtree();
|
||||
|
|
@ -49,7 +52,8 @@ public:
|
|||
typedef std::vector<TypeRegistryNode *> Classes;
|
||||
Classes _parent_classes;
|
||||
Classes _child_classes;
|
||||
PyObject *_python_type = nullptr;
|
||||
PyTypeObject *_python_type = nullptr;
|
||||
PythonWrapFunc *_python_wrap_func = nullptr;
|
||||
|
||||
patomic<size_t> _memory_usage[TypeHandle::MC_limit];
|
||||
|
||||
|
|
@ -81,7 +85,8 @@ private:
|
|||
void r_build_subtrees(TypeRegistryNode *top,
|
||||
int bit_count, SubtreeMaskType bits);
|
||||
|
||||
PyObject *r_get_python_type() const;
|
||||
PyTypeObject *r_get_python_type() const;
|
||||
PyObject *r_wrap_python(void *ptr, PyTypeObject *cast_from) const;
|
||||
|
||||
static bool check_derived_from(const TypeRegistryNode *child,
|
||||
const TypeRegistryNode *base);
|
||||
|
|
|
|||
|
|
@ -1289,9 +1289,12 @@ to_os_long_name() const {
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns true if the filename exists on the disk, false otherwise. If the
|
||||
* type is indicated to be executable, this also tests that the file has
|
||||
* Returns true if the filename exists on the physical disk, false otherwise.
|
||||
* If the type is indicated to be executable, this also tests that the file has
|
||||
* execute permission.
|
||||
*
|
||||
* @see VirtualFileSystem::exists() for checking whether the filename exists in
|
||||
* the virtual file system.
|
||||
*/
|
||||
bool Filename::
|
||||
exists() const {
|
||||
|
|
@ -1320,8 +1323,11 @@ exists() const {
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns true if the filename exists and is the name of a regular file (i.e.
|
||||
* not a directory or device), false otherwise.
|
||||
* Returns true if the filename exists on the physical disk and is the name of
|
||||
* a regular file (i.e. not a directory or device), false otherwise.
|
||||
*
|
||||
* @see VirtualFileSystem::is_regular_file() for checking whether the filename
|
||||
* exists and is a regular file in the virtual file system.
|
||||
*/
|
||||
bool Filename::
|
||||
is_regular_file() const {
|
||||
|
|
@ -1350,8 +1356,8 @@ is_regular_file() const {
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns true if the filename exists and is either a directory or a regular
|
||||
* file that can be written to, or false otherwise.
|
||||
* Returns true if the filename exists on the physical disk and is either a
|
||||
* directory or a regular file that can be written to, or false otherwise.
|
||||
*/
|
||||
bool Filename::
|
||||
is_writable() const {
|
||||
|
|
@ -1382,8 +1388,11 @@ is_writable() const {
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns true if the filename exists and is a directory name, false
|
||||
* otherwise.
|
||||
* Returns true if the filename exists on the physical disk and is a directory
|
||||
* name, false otherwise.
|
||||
*
|
||||
* @see VirtualFileSystem::is_directory() for checking whether the filename
|
||||
* exists as a directory in the virtual file system.
|
||||
*/
|
||||
bool Filename::
|
||||
is_directory() const {
|
||||
|
|
|
|||
|
|
@ -36,6 +36,11 @@ class DSearchPath;
|
|||
* convention, and it knows how to perform basic OS-specific I/O, like testing
|
||||
* for file existence and searching a searchpath, as well as the best way to
|
||||
* open an fstream for reading or writing.
|
||||
*
|
||||
* Note that the methods of Filename that interact with the filesystem (such
|
||||
* as exists(), open_read(), etc.) directly interface with the operating system
|
||||
* and are not aware of Panda's virtual file system. To interact with the VFS,
|
||||
* use the methods on VirtualFileSystem instead.
|
||||
*/
|
||||
class EXPCL_DTOOL_DTOOLUTIL Filename {
|
||||
PUBLISHED:
|
||||
|
|
|
|||
|
|
@ -494,6 +494,10 @@ get_call_str(const string &container, const vector_string &pexprs) const {
|
|||
call << separator << "self";
|
||||
separator = ", ";
|
||||
}
|
||||
if (_flags & F_explicit_cls) {
|
||||
call << separator << "cls";
|
||||
separator = ", ";
|
||||
}
|
||||
|
||||
size_t pn;
|
||||
size_t num_parameters = pexprs.size();
|
||||
|
|
@ -781,14 +785,20 @@ setup_properties(const InterrogateFunction &ifunc, InterfaceMaker *interface_mak
|
|||
first_param = 1;
|
||||
}
|
||||
|
||||
if (_parameters.size() > first_param && _parameters[first_param]._name == "self" &&
|
||||
if (_parameters.size() > first_param &&
|
||||
TypeManager::is_pointer_to_PyObject(_parameters[first_param]._remap->get_orig_type())) {
|
||||
// Here's a special case. If the first parameter of a nonstatic method
|
||||
// is a PyObject * called "self", then we will automatically fill it in
|
||||
// from the this pointer, and remove it from the generated parameter
|
||||
// list.
|
||||
_parameters.erase(_parameters.begin() + first_param);
|
||||
_flags |= F_explicit_self;
|
||||
// from the this pointer, and remove it from the generated parameter list.
|
||||
// For static methods, we offer "cls" instead, containing the type object.
|
||||
if (_parameters[first_param]._name == "self") {
|
||||
_parameters.erase(_parameters.begin() + first_param);
|
||||
_flags |= F_explicit_self;
|
||||
}
|
||||
else if (!_has_this && _parameters[first_param]._name == "cls") {
|
||||
_parameters.erase(_parameters.begin() + first_param);
|
||||
_flags |= F_explicit_cls;
|
||||
}
|
||||
}
|
||||
|
||||
if (_parameters.size() == first_param) {
|
||||
|
|
|
|||
|
|
@ -101,6 +101,7 @@ public:
|
|||
F_divide_integer = 0x2000,
|
||||
F_hash = 0x4000,
|
||||
F_explicit_args = 0x8000,
|
||||
F_explicit_cls =0x10000,
|
||||
};
|
||||
|
||||
typedef std::vector<Parameter> Parameters;
|
||||
|
|
|
|||
|
|
@ -115,6 +115,7 @@ RenameSet methodRenameDictionary[] = {
|
|||
{ "__deepcopy__" , "__deepcopy__", 0 },
|
||||
{ "__getstate__" , "__getstate__", 0 },
|
||||
{ "__setstate__" , "__setstate__", 0 },
|
||||
{ "__new__" , "__new__", 0 },
|
||||
{ "print" , "Cprint", 0 },
|
||||
{ "CInterval.set_t", "_priv__cSetT", 0 },
|
||||
{ nullptr, nullptr, -1 }
|
||||
|
|
@ -664,6 +665,12 @@ get_slotted_function_def(Object *obj, Function *func, FunctionRemap *remap,
|
|||
return true;
|
||||
}
|
||||
|
||||
if (method_name == "__new__") {
|
||||
def._answer_location = "tp_new";
|
||||
def._wrapper_type = WT_new;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (remap->_type == FunctionRemap::T_typecast_method) {
|
||||
// A typecast operator. Check for a supported low-level typecast type.
|
||||
if (TypeManager::is_bool(remap->_return_type->get_orig_type())) {
|
||||
|
|
@ -1106,10 +1113,14 @@ write_class_details(ostream &out, Object *obj) {
|
|||
out << " */\n";
|
||||
|
||||
// First write out all the wrapper functions for the methods.
|
||||
bool have_new = false;
|
||||
for (Function *func : obj->_methods) {
|
||||
if (func) {
|
||||
// Write the definition of the generic wrapper function for this
|
||||
// function.
|
||||
if (func->_ifunc.get_name() == "__new__") {
|
||||
have_new = true;
|
||||
}
|
||||
write_function_for_top(out, obj, func);
|
||||
}
|
||||
}
|
||||
|
|
@ -1128,10 +1139,16 @@ write_class_details(ostream &out, Object *obj) {
|
|||
if (obj->_constructors.size() == 0) {
|
||||
// We still need to write a dummy constructor to prevent inheriting the
|
||||
// constructor from a base class.
|
||||
out << fname << " {\n"
|
||||
" Dtool_Raise_TypeError(\"cannot init abstract class\");\n"
|
||||
" return -1;\n"
|
||||
"}\n\n";
|
||||
if (have_new) {
|
||||
out << fname << " {\n"
|
||||
" return 0;\n"
|
||||
"}\n\n";
|
||||
} else {
|
||||
out << fname << " {\n"
|
||||
" Dtool_Raise_TypeError(\"cannot init abstract class\");\n"
|
||||
" return -1;\n"
|
||||
"}\n\n";
|
||||
}
|
||||
}
|
||||
|
||||
CPPType *cpptype = TypeManager::resolve_type(obj->_itype._cpptype);
|
||||
|
|
@ -1221,18 +1238,17 @@ write_class_details(ostream &out, Object *obj) {
|
|||
out << " return nullptr;\n";
|
||||
out << "}\n\n";
|
||||
|
||||
out << "static Dtool_PyInstDef *Dtool_Wrap_" << ClassName << "(void *from_this, Dtool_PyTypedObject *from_type) {\n";
|
||||
out << " if (from_this == nullptr || from_type == nullptr) {\n";
|
||||
out << " return nullptr;\n";
|
||||
out << " }\n";
|
||||
//NB. This may be called with nullptr in either argument and should produce
|
||||
// a valid wrapper object even with a null pointer.
|
||||
out << "static PyObject *Dtool_Wrap_" << ClassName << "(void *from_this, PyTypeObject *from_type) {\n";
|
||||
out << " " << cClassName << " *to_this;\n";
|
||||
out << " if (from_type == &Dtool_" << ClassName << ") {\n";
|
||||
out << " if (from_type == nullptr || from_type == &Dtool_" << ClassName << "._PyType) {\n";
|
||||
out << " to_this = (" << cClassName << "*)from_this;\n";
|
||||
out << " }\n";
|
||||
for (di = details.begin(); di != details.end(); di++) {
|
||||
if (di->second._can_downcast && di->second._is_legal_py_class) {
|
||||
out << " else if (from_type == Dtool_Ptr_" << make_safe_name(di->second._to_class_name) << ") {\n";
|
||||
out << " " << di->second._to_class_name << "* other_this = (" << di->second._to_class_name << "*)from_this;\n" ;
|
||||
out << " else if (from_type == (PyTypeObject *)Dtool_Ptr_" << make_safe_name(di->second._to_class_name) << ") {\n";
|
||||
out << " " << di->second._to_class_name << " *other_this = (" << di->second._to_class_name << " *)from_this;\n" ;
|
||||
out << " to_this = (" << cClassName << "*)other_this;\n";
|
||||
out << " }\n";
|
||||
}
|
||||
|
|
@ -1247,7 +1263,7 @@ write_class_details(ostream &out, Object *obj) {
|
|||
out << " self->_ptr_to_object = to_this;\n";
|
||||
out << " self->_memory_rules = false;\n";
|
||||
out << " self->_is_const = false;\n";
|
||||
out << " return self;\n";
|
||||
out << " return (PyObject *)self;\n";
|
||||
out << "}\n\n";
|
||||
}
|
||||
}
|
||||
|
|
@ -1405,8 +1421,9 @@ write_module_support(ostream &out, ostream *out_h, InterrogateModuleDef *def) {
|
|||
out << " TypeHandle handle = " << type->get_local_name(&parser)
|
||||
<< "::get_class_type();\n";
|
||||
out << " Dtool_" << safe_name << "._type = handle;\n";
|
||||
out << " registry->record_python_type(handle, "
|
||||
"(PyObject *)&Dtool_" << safe_name << ");\n";
|
||||
out << " registry->record_python_type(handle,"
|
||||
" &Dtool_" << safe_name << "._PyType,"
|
||||
" Dtool_Wrap_" << safe_name << ");\n";
|
||||
out << " }\n";
|
||||
} else {
|
||||
if (IsPandaTypedObject(type->as_struct_type())) {
|
||||
|
|
@ -1706,7 +1723,11 @@ write_module_class(ostream &out, Object *obj) {
|
|||
}
|
||||
|
||||
if (!func->_has_this) {
|
||||
flags += " | METH_STATIC";
|
||||
if (func->_flags & FunctionRemap::F_explicit_cls) {
|
||||
flags += " | METH_CLASS";
|
||||
} else {
|
||||
flags += " | METH_STATIC";
|
||||
}
|
||||
|
||||
// Skip adding this entry if we also have a property with the same name.
|
||||
// In that case, we will use a Dtool_StaticProperty to disambiguate
|
||||
|
|
@ -2620,6 +2641,17 @@ write_module_class(ostream &out, Object *obj) {
|
|||
}
|
||||
break;
|
||||
|
||||
case WT_new:
|
||||
{
|
||||
string fname = "static PyObject *" + def._wrapper_name + "(PyTypeObject *cls, PyObject *args, PyObject *kwds)\n";
|
||||
|
||||
std::vector<FunctionRemap *> remaps;
|
||||
remaps.insert(remaps.end(), def._remaps.begin(), def._remaps.end());
|
||||
string expected_params;
|
||||
write_function_for_name(out, obj, remaps, fname, expected_params, true, AT_keyword_args, RF_pyobject | RF_err_null);
|
||||
}
|
||||
break;
|
||||
|
||||
case WT_none:
|
||||
// Nothing special about the wrapper function: just write it normally.
|
||||
string fname = "static PyObject *" + def._wrapper_name + "(PyObject *self, PyObject *args, PyObject *kwds)\n";
|
||||
|
|
@ -3225,7 +3257,7 @@ write_module_class(ostream &out, Object *obj) {
|
|||
// allocfunc tp_alloc;
|
||||
out << " PyType_GenericAlloc,\n";
|
||||
// newfunc tp_new;
|
||||
out << " Dtool_new_" << ClassName << ",\n";
|
||||
write_function_slot(out, 4, slots, "tp_new", "Dtool_new_" + ClassName);
|
||||
// freefunc tp_free;
|
||||
if (obj->_protocol_types & Object::PT_python_gc) {
|
||||
out << " PyObject_GC_Del,\n";
|
||||
|
|
@ -3652,6 +3684,9 @@ write_function_for_top(ostream &out, InterfaceMaker::Object *obj, InterfaceMaker
|
|||
if (func->_has_this) {
|
||||
prototype += "self";
|
||||
}
|
||||
else if (func->_flags & FunctionRemap::F_explicit_cls) {
|
||||
prototype += "cls";
|
||||
}
|
||||
|
||||
switch (func->_args_type) {
|
||||
case AT_keyword_args:
|
||||
|
|
|
|||
|
|
@ -82,6 +82,7 @@ private:
|
|||
WT_traverse,
|
||||
WT_compare,
|
||||
WT_hash,
|
||||
WT_new,
|
||||
};
|
||||
|
||||
// This enum is passed to the wrapper generation functions to indicate what
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue