Merge branch 'master' into deploy-ng

This commit is contained in:
rdb 2017-09-04 21:31:32 +02:00
commit f16cd29971
186 changed files with 4774 additions and 3949 deletions

View File

@ -11,18 +11,32 @@ __all__ = [
'interrupt_main',
'exit', 'allocate_lock', 'get_ident',
'stack_size',
'force_yield', 'consider_yield',
'forceYield', 'considerYield',
'TIMEOUT_MAX'
]
from panda3d import core
import sys
if sys.platform == "win32":
TIMEOUT_MAX = float(0xffffffff // 1000)
else:
TIMEOUT_MAX = float(0x7fffffffffffffff // 1000000000)
# These methods are defined in Panda, and are particularly useful if
# you may be running in Panda's SIMPLE_THREADS compilation mode.
forceYield = core.Thread.forceYield
considerYield = core.Thread.considerYield
force_yield = core.Thread.force_yield
consider_yield = core.Thread.consider_yield
class error(Exception):
pass
forceYield = force_yield
considerYield = consider_yield
if sys.version_info >= (3, 3):
error = RuntimeError
else:
class error(Exception):
pass
class LockType:
""" Implements a mutex lock. Instead of directly subclassing
@ -36,13 +50,18 @@ class LockType:
self.__cvar = core.ConditionVar(self.__lock)
self.__locked = False
def acquire(self, waitflag = 1):
def acquire(self, waitflag = 1, timeout = -1):
self.__lock.acquire()
try:
if self.__locked and not waitflag:
return False
while self.__locked:
self.__cvar.wait()
if timeout >= 0:
while self.__locked:
self.__cvar.wait(timeout)
else:
while self.__locked:
self.__cvar.wait()
self.__locked = True
return True
@ -202,12 +221,17 @@ def _get_thread_locals(thread, i):
def _remove_thread_id(threadId):
""" Removes the thread with the indicated ID from the thread list. """
# On interpreter shutdown, Python may set module globals to None.
if _threadsLock is None or _threads is None:
return
_threadsLock.acquire()
try:
thread, locals, wrapper = _threads[threadId]
assert thread.getPythonIndex() == threadId
del _threads[threadId]
thread.setPythonIndex(-1)
if threadId in _threads:
thread, locals, wrapper = _threads[threadId]
assert thread.getPythonIndex() == threadId
del _threads[threadId]
thread.setPythonIndex(-1)
finally:
_threadsLock.release()

View File

@ -35,11 +35,15 @@ __all__ = [
'Event',
'Timer',
'local',
'current_thread', 'currentThread',
'enumerate', 'active_count', 'activeCount',
'current_thread',
'main_thread',
'enumerate', 'active_count',
'settrace', 'setprofile', 'stack_size',
'TIMEOUT_MAX',
]
TIMEOUT_MAX = _thread.TIMEOUT_MAX
local = _thread._local
_newname = _thread._newname
@ -98,7 +102,15 @@ class Thread(ThreadBase):
self.__dict__['daemon'] = current.daemon
self.__dict__['name'] = name
self.__thread = core.PythonThread(self.run, None, name, name)
def call_run():
# As soon as the thread is done, break the circular reference.
try:
self.run()
finally:
self.__thread = None
_thread._remove_thread_id(self.ident)
self.__thread = core.PythonThread(call_run, None, name, name)
threadId = _thread._add_thread(self.__thread, weakref.proxy(self))
self.__dict__['ident'] = threadId
@ -109,16 +121,17 @@ class Thread(ThreadBase):
_thread._remove_thread_id(self.ident)
def is_alive(self):
return self.__thread.isStarted()
thread = self.__thread
return thread is not None and thread.is_started()
def isAlive(self):
return self.__thread.isStarted()
isAlive = is_alive
def start(self):
if self.__thread.isStarted():
thread = self.__thread
if thread is None or thread.is_started():
raise RuntimeError
if not self.__thread.start(core.TPNormal, True):
if not thread.start(core.TPNormal, True):
raise RuntimeError
def run(self):
@ -132,8 +145,12 @@ class Thread(ThreadBase):
def join(self, timeout = None):
# We don't support a timed join here, sorry.
assert timeout is None
self.__thread.join()
self.__thread = None
thread = self.__thread
if thread is not None:
thread.join()
# Clear the circular reference.
self.__thread = None
_thread._remove_thread_id(self.ident)
def setName(self, name):
self.__dict__['name'] = name
@ -379,6 +396,10 @@ def current_thread():
t = core.Thread.getCurrentThread()
return _thread._get_thread_wrapper(t, _create_thread_wrapper)
def main_thread():
t = core.Thread.getMainThread()
return _thread._get_thread_wrapper(t, _create_thread_wrapper)
currentThread = current_thread
def enumerate():
@ -386,7 +407,7 @@ def enumerate():
_thread._threadsLock.acquire()
try:
for thread, locals, wrapper in list(_thread._threads.values()):
if wrapper and thread.isStarted():
if wrapper and wrapper.is_alive():
tlist.append(wrapper)
return tlist
finally:
@ -394,6 +415,7 @@ def enumerate():
def active_count():
return len(enumerate())
activeCount = active_count
_settrace_func = None

View File

@ -15,7 +15,7 @@ implementation. """
import sys as _sys
from direct.stdpy import thread
from direct.stdpy import thread as _thread
from direct.stdpy.thread import stack_size, _newname, _local as local
from panda3d import core
_sleep = core.Thread.sleep
@ -23,16 +23,19 @@ _sleep = core.Thread.sleep
from time import time as _time
from traceback import format_exc as _format_exc
# Rename some stuff so "from threading import *" is safe
__all__ = ['activeCount', 'Condition', 'currentThread', 'enumerate', 'Event',
'Lock', 'RLock', 'Semaphore', 'BoundedSemaphore', 'Thread',
'Timer', 'setprofile', 'settrace', 'local', 'stack_size']
__all__ = ['get_ident', 'active_count', 'Condition', 'current_thread',
'enumerate', 'main_thread', 'TIMEOUT_MAX',
'Event', 'Lock', 'RLock', 'Semaphore', 'BoundedSemaphore', 'Thread',
'Timer', 'ThreadError',
'setprofile', 'settrace', 'local', 'stack_size']
_start_new_thread = thread.start_new_thread
_allocate_lock = thread.allocate_lock
_get_ident = thread.get_ident
ThreadError = thread.error
del thread
# Rename some stuff so "from threading import *" is safe
_start_new_thread = _thread.start_new_thread
_allocate_lock = _thread.allocate_lock
get_ident = _thread.get_ident
ThreadError = _thread.error
TIMEOUT_MAX = _thread.TIMEOUT_MAX
del _thread
# Debug support (adapted from ihooks.py).
@ -446,7 +449,7 @@ class Thread(_Verbose):
try:
self.__started = True
_active_limbo_lock.acquire()
_active[_get_ident()] = self
_active[get_ident()] = self
del _limbo[self]
_active_limbo_lock.release()
if __debug__:
@ -537,7 +540,7 @@ class Thread(_Verbose):
_active_limbo_lock.acquire()
try:
try:
del _active[_get_ident()]
del _active[get_ident()]
except KeyError:
if 'dummy_threading' not in _sys.modules:
raise
@ -581,10 +584,12 @@ class Thread(_Verbose):
assert self.__initialized, "Thread.__init__() not called"
self.__name = str(name)
def isAlive(self):
def is_alive(self):
assert self.__initialized, "Thread.__init__() not called"
return self.__started and not self.__stopped
isAlive = is_alive
def isDaemon(self):
assert self.__initialized, "Thread.__init__() not called"
return self.__daemonic
@ -634,7 +639,7 @@ class _MainThread(Thread):
Thread.__init__(self, name="MainThread")
self._Thread__started = True
_active_limbo_lock.acquire()
_active[_get_ident()] = self
_active[get_ident()] = self
_active_limbo_lock.release()
def _set_daemon(self):
@ -653,12 +658,6 @@ class _MainThread(Thread):
self._note("%s: exiting", self)
self._Thread__delete()
def _pickSomeNonDaemonThread():
for t in enumerate():
if not t.isDaemon() and t.isAlive():
return t
return None
# Dummy thread class to represent threads not started here.
# These aren't garbage collected when they die, nor can they be waited for.
@ -680,7 +679,7 @@ class _DummyThread(Thread):
self._Thread__started = True
_active_limbo_lock.acquire()
_active[_get_ident()] = self
_active[get_ident()] = self
_active_limbo_lock.release()
def _set_daemon(self):
@ -692,19 +691,23 @@ class _DummyThread(Thread):
# Global API functions
def currentThread():
def current_thread():
try:
return _active[_get_ident()]
return _active[get_ident()]
except KeyError:
##print "currentThread(): no current thread for", _get_ident()
##print "current_thread(): no current thread for", get_ident()
return _DummyThread()
def activeCount():
currentThread = current_thread
def active_count():
_active_limbo_lock.acquire()
count = len(_active) + len(_limbo)
_active_limbo_lock.release()
return count
activeCount = active_count
def enumerate():
_active_limbo_lock.acquire()
active = list(_active.values()) + list(_limbo.values())
@ -717,7 +720,21 @@ def enumerate():
# and make it available for the interpreter
# (Py_Main) as threading._shutdown.
_shutdown = _MainThread()._exitfunc
_main_thread = _MainThread()
_shutdown = _main_thread._exitfunc
def _pickSomeNonDaemonThread():
for t in enumerate():
if not t.isDaemon() and t.isAlive():
return t
return None
def main_thread():
"""Return the main thread object.
In normal conditions, the main thread is the thread from which the
Python interpreter was started.
"""
return _main_thread
# get thread-local implementation, either from the thread
# module, or from the python fallback

File diff suppressed because it is too large Load Diff

View File

@ -4051,6 +4051,10 @@ name:
| KW_STATIC
{
$$ = new CPPIdentifier("static", @1);
}
| KW_DEFAULT
{
$$ = new CPPIdentifier("default", @1);
}
;

View File

@ -332,7 +332,7 @@ typedef struct _object PyObject;
#ifdef __WORDSIZE
#define NATIVE_WORDSIZE __WORDSIZE
#elif defined(_LP64)
#elif defined(_LP64) || defined(_WIN64)
#define NATIVE_WORDSIZE 64
#else
#define NATIVE_WORDSIZE 32

View File

@ -34,9 +34,9 @@ using namespace std;
#define ALWAYS_INLINE inline
#define TYPENAME typename
#define CONSTEXPR constexpr
#define ALWAYS_INLINE_CONSTEXPR constexpr
#define NOEXCEPT noexcept
#define FINAL final
#define OVERRIDE override
#define MOVE(x) x
#define DEFAULT_CTOR = default
#define DEFAULT_DTOR = default
@ -166,7 +166,6 @@ template<class T> typename remove_reference<T>::type &&move(T &&t) {
# endif
# if __has_extension(cxx_override_control) && (__cplusplus >= 201103L)
# define FINAL final
# define OVERRIDE override
# endif
# if __has_extension(cxx_defaulted_functions)
# define DEFAULT_CTOR = default
@ -197,7 +196,6 @@ template<class T> typename remove_reference<T>::type &&move(T &&t) {
// Starting at GCC 4.7
# if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7)
# define FINAL final
# define OVERRIDE override
# endif
// GCC defines several macros which we can query. List of all supported
@ -211,11 +209,9 @@ template<class T> typename remove_reference<T>::type &&move(T &&t) {
# define NOEXCEPT noexcept
# define USE_MOVE_SEMANTICS
# define FINAL final
# define OVERRIDE override
# define MOVE(x) move(x)
#elif defined(_MSC_VER) && _MSC_VER >= 1600 // Visual Studio 2010
# define NOEXCEPT throw()
# define OVERRIDE override
# define USE_MOVE_SEMANTICS
# define FINAL sealed
# define MOVE(x) move(x)
@ -231,6 +227,9 @@ template<class T> typename remove_reference<T>::type &&move(T &&t) {
// Fallbacks if features are not supported
#ifndef CONSTEXPR
# define CONSTEXPR INLINE
# define ALWAYS_INLINE_CONSTEXPR ALWAYS_INLINE
#else
# define ALWAYS_INLINE_CONSTEXPR ALWAYS_INLINE CONSTEXPR
#endif
#ifndef NOEXCEPT
# define NOEXCEPT
@ -241,9 +240,6 @@ template<class T> typename remove_reference<T>::type &&move(T &&t) {
#ifndef FINAL
# define FINAL
#endif
#ifndef OVERRIDE
# define OVERRIDE
#endif
#ifndef DEFAULT_CTOR
# define DEFAULT_CTOR {}
#endif

View File

@ -202,13 +202,11 @@ MemoryHook() {
#endif // WIN32
#ifdef DO_MEMORY_USAGE
_total_heap_single_size = 0;
_total_heap_array_size = 0;
_requested_heap_size = 0;
_total_mmap_size = 0;
_max_heap_size = ~(size_t)0;
#endif
}
/**
@ -216,19 +214,16 @@ MemoryHook() {
*/
MemoryHook::
MemoryHook(const MemoryHook &copy) :
_page_size(copy._page_size)
{
#ifdef DO_MEMORY_USAGE
_total_heap_single_size = copy._total_heap_single_size;
_total_heap_array_size = copy._total_heap_array_size;
_requested_heap_size = copy._requested_heap_size;
_total_mmap_size = copy._total_mmap_size;
_max_heap_size = copy._max_heap_size;
#endif
_page_size(copy._page_size),
_total_heap_single_size(copy._total_heap_single_size),
_total_heap_array_size(copy._total_heap_array_size),
_requested_heap_size(copy._requested_heap_size),
_total_mmap_size(copy._total_mmap_size),
_max_heap_size(copy._max_heap_size) {
((MutexImpl &)copy._lock).acquire();
copy._lock.acquire();
_deleted_chains = copy._deleted_chains;
((MutexImpl &)copy._lock).release();
copy._lock.release();
}
/**
@ -631,7 +626,6 @@ alloc_fail(size_t attempted_size) {
abort();
}
#ifdef DO_MEMORY_USAGE
/**
* This callback method is called whenever the total allocated heap size
* exceeds _max_heap_size. It's mainly intended for reporting memory leaks,
@ -642,6 +636,7 @@ alloc_fail(size_t attempted_size) {
*/
void MemoryHook::
overflow_heap_size() {
#ifdef DO_MEMORY_USAGE
_max_heap_size = ~(size_t)0;
}
#endif // DO_MEMORY_USAGE
}

View File

@ -67,7 +67,6 @@ public:
INLINE static size_t get_ptr_size(void *ptr);
#ifdef DO_MEMORY_USAGE
protected:
TVOLATILE AtomicAdjust::Integer _total_heap_single_size;
TVOLATILE AtomicAdjust::Integer _total_heap_array_size;
@ -79,7 +78,6 @@ protected:
size_t _max_heap_size;
virtual void overflow_heap_size();
#endif // DO_MEMORY_USAGE
private:
size_t _page_size;
@ -87,7 +85,7 @@ private:
typedef map<size_t, DeletedBufferChain *> DeletedChains;
DeletedChains _deleted_chains;
MutexImpl _lock;
mutable MutexImpl _lock;
};
#include "memoryHook.I"

View File

@ -26,9 +26,7 @@ TypeRegistryNode(TypeHandle handle, const string &name, TypeHandle &ref) :
_handle(handle), _name(name), _ref(ref)
{
clear_subtree();
#ifdef DO_MEMORY_USAGE
memset(_memory_usage, 0, sizeof(_memory_usage));
#endif
}
/**

View File

@ -47,9 +47,7 @@ public:
Classes _parent_classes;
Classes _child_classes;
#ifdef DO_MEMORY_USAGE
AtomicAdjust::Integer _memory_usage[TypeHandle::MC_limit];
#endif
static bool _paranoid_inheritance;

View File

@ -341,6 +341,22 @@ ns_get_environment_variable(const string &var) const {
}
}
#elif !defined(__APPLE__)
// Similarly, we define fallbacks on POSIX systems for the variables defined
// in the XDG Base Directory specification, so that they can be safely used
// in Config.prc files.
if (var == "XDG_CONFIG_HOME") {
Filename home_dir = Filename::get_home_directory();
return home_dir.get_fullpath() + "/.config";
} else if (var == "XDG_CACHE_HOME") {
Filename home_dir = Filename::get_home_directory();
return home_dir.get_fullpath() + "/.cache";
} else if (var == "XDG_DATA_HOME") {
Filename home_dir = Filename::get_home_directory();
return home_dir.get_fullpath() + "/.local/share";
}
#endif // _WIN32
return string();

View File

@ -51,6 +51,11 @@ PUBLISHED:
static Filename get_cwd();
MAKE_SEQ_PROPERTY(args, get_num_args, get_arg);
MAKE_PROPERTY(binary_name, get_binary_name, set_binary_name);
MAKE_PROPERTY(dtool_name, get_dtool_name, set_dtool_name);
MAKE_PROPERTY(cwd, get_cwd);
private:
bool ns_has_environment_variable(const string &var) const;
string ns_get_environment_variable(const string &var) const;

View File

@ -600,8 +600,14 @@ get_user_appdata_directory() {
user_appdata_directory.set_basename("files");
#else
// Posix case.
user_appdata_directory = get_home_directory();
// Posix case. We follow the XDG base directory spec.
struct stat st;
const char *datadir = getenv("XDG_DATA_HOME");
if (datadir != nullptr && stat(datadir, &st) == 0 && S_ISDIR(st.st_mode)) {
user_appdata_directory = datadir;
} else {
user_appdata_directory = Filename(get_home_directory(), ".local/share");
}
#endif // WIN32
@ -649,9 +655,10 @@ get_common_appdata_directory() {
common_appdata_directory.set_dirname(_internal_data_dir);
common_appdata_directory.set_basename("files");
#elif defined(__FreeBSD__)
common_appdata_directory = "/usr/local/share";
#else
// Posix case.
common_appdata_directory = "/var";
common_appdata_directory = "/usr/share";
#endif // WIN32
if (common_appdata_directory.empty()) {

View File

@ -47,20 +47,20 @@ load_dso(const DSearchPath &path, const Filename &filename) {
if (!abspath.is_regular_file()) {
return NULL;
}
string os_specific = abspath.to_os_specific();
wstring os_specific_w = abspath.to_os_specific_w();
// Try using LoadLibraryEx, if possible.
typedef HMODULE (WINAPI *tLoadLibraryEx)(LPCTSTR, HANDLE, DWORD);
typedef HMODULE (WINAPI *tLoadLibraryEx)(LPCWSTR, HANDLE, DWORD);
tLoadLibraryEx pLoadLibraryEx;
HINSTANCE hLib = LoadLibrary("kernel32.dll");
if (hLib) {
pLoadLibraryEx = (tLoadLibraryEx)GetProcAddress(hLib, "LoadLibraryExA");
pLoadLibraryEx = (tLoadLibraryEx)GetProcAddress(hLib, "LoadLibraryExW");
if (pLoadLibraryEx) {
return pLoadLibraryEx(os_specific.c_str(), NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
return pLoadLibraryEx(os_specific_w.c_str(), NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
}
}
return LoadLibrary(os_specific.c_str());
return LoadLibraryW(os_specific_w.c_str());
}
bool

View File

@ -48,6 +48,21 @@ PUBLISHED:
static string get_platform();
MAKE_PROPERTY(version_string, get_version_string);
MAKE_PROPERTY(major_version, get_major_version);
MAKE_PROPERTY(minor_version, get_minor_version);
MAKE_PROPERTY(sequence_version, get_sequence_version);
MAKE_PROPERTY(official_version, is_official_version);
MAKE_PROPERTY(memory_alignment, get_memory_alignment);
MAKE_PROPERTY(distributor, get_distributor);
MAKE_PROPERTY(compiler, get_compiler);
MAKE_PROPERTY(build_date, get_build_date);
MAKE_PROPERTY(git_commit, get_git_commit);
MAKE_PROPERTY(platform, get_platform);
bool has_system(const string &system) const;
size_t get_num_systems() const;
string get_system(size_t n) const;

View File

@ -46,6 +46,7 @@ PUBLISHED:
INLINE static void set_default_encoding(Encoding encoding);
INLINE static Encoding get_default_encoding();
MAKE_PROPERTY(default_encoding, get_default_encoding, set_default_encoding);
INLINE void set_text(const string &text);
INLINE void set_text(const string &text, Encoding encoding);

View File

@ -91,7 +91,8 @@ Property(const InterrogateElement &ielement) :
_setter(NULL),
_has_function(NULL),
_clear_function(NULL),
_deleter(NULL)
_deleter(NULL),
_has_this(false)
{
}

View File

@ -132,6 +132,7 @@ public:
Function *_has_function;
Function *_clear_function;
Function *_deleter;
bool _has_this;
};
typedef vector<Property *> Properties;

View File

@ -2623,7 +2623,8 @@ write_module_class(ostream &out, Object *obj) {
for (pit = obj->_properties.begin(); pit != obj->_properties.end(); ++pit) {
Property *property = (*pit);
const InterrogateElement &ielem = property->_ielement;
if (property->_getter == NULL || !is_function_legal(property->_getter)) {
if (!property->_has_this ||
property->_getter == NULL || !is_function_legal(property->_getter)) {
continue;
}
@ -3169,6 +3170,45 @@ write_module_class(ostream &out, Object *obj) {
}
}
// Also add the static properties, which can't be added via getset.
Properties::const_iterator pit;
for (pit = obj->_properties.begin(); pit != obj->_properties.end(); ++pit) {
Property *property = (*pit);
const InterrogateElement &ielem = property->_ielement;
if (property->_has_this ||
property->_getter == NULL || !is_function_legal(property->_getter)) {
continue;
}
string name1 = methodNameFromCppName(ielem.get_name(), "", false);
// string name2 = methodNameFromCppName(ielem.get_name(), "", true);
string getter = "&Dtool_" + ClassName + "_" + ielem.get_name() + "_Getter";
string setter = "NULL";
if (property->_length_function == NULL &&
property->_setter != NULL && is_function_legal(property->_setter)) {
setter = "&Dtool_" + ClassName + "_" + ielem.get_name() + "_Setter";
}
out << " static const PyGetSetDef def_" << name1 << " = {(char *)\"" << name1 << "\", " << getter << ", " << setter;
if (ielem.has_comment()) {
out << ", (char *)\n";
output_quoted(out, 4, ielem.get_comment());
out << ",\n ";
} else {
out << ", NULL, ";
}
// Extra void* argument; we don't make use of it.
out << "NULL};\n";
out << " PyDict_SetItemString(dict, \"" << name1 << "\", Dtool_NewStaticProperty(&Dtool_" << ClassName << "._PyType, &def_" << name1 << "));\n";
/* Alternative spelling:
out << " PyDict_SetItemString(\"" << name2 << "\", &def_" << name1 << ");\n";
*/
}
out << " if (PyType_Ready((PyTypeObject *)&Dtool_" << ClassName << ") < 0) {\n"
" Dtool_Raise_TypeError(\"PyType_Ready(" << ClassName << ")\");\n"
" return;\n"
@ -6443,11 +6483,15 @@ write_getset(ostream &out, Object *obj, Property *property) {
"/**\n"
" * sequence getter for property " << cClassName << "::" << ielem.get_name() << "\n"
" */\n"
"static PyObject *Dtool_" + ClassName + "_" + ielem.get_name() + "_Getitem(PyObject *self, Py_ssize_t index) {\n"
" " << cClassName << " *local_this = NULL;\n"
" if (!Dtool_Call_ExtractThisPointer(self, Dtool_" << ClassName << ", (void **)&local_this)) {\n"
" return NULL;\n"
" }\n";
"static PyObject *Dtool_" + ClassName + "_" + ielem.get_name() + "_Getitem(PyObject *self, Py_ssize_t index) {\n";
if (property->_getter->_has_this ||
(property->_has_function && property->_has_function->_has_this)) {
out <<
" " << cClassName << " *local_this = NULL;\n"
" if (!Dtool_Call_ExtractThisPointer(self, Dtool_" << ClassName << ", (void **)&local_this)) {\n"
" return NULL;\n"
" }\n";
}
// This is a getitem of a sequence type. This means we *need* to raise
// IndexError if we're out of bounds.
@ -6458,8 +6502,12 @@ write_getset(ostream &out, Object *obj, Property *property) {
out << " }\n";
if (property->_has_function != NULL) {
out << " if (!local_this->" << property->_has_function->_ifunc.get_name() << "(index)) {\n"
<< " Py_INCREF(Py_None);\n"
if (property->_has_function->_has_this) {
out << " if (!local_this->" << property->_has_function->_ifunc.get_name() << "(index)) {\n";
} else {
out << " if (!" << cClassName << "::" << property->_has_function->_ifunc.get_name() << "(index)) {\n";
}
out << " Py_INCREF(Py_None);\n"
<< " return Py_None;\n"
<< " }\n";
}
@ -6494,16 +6542,22 @@ write_getset(ostream &out, Object *obj, Property *property) {
// Write out a setitem if this is not a read-only property.
if (property->_setter != NULL) {
out << "static int Dtool_" + ClassName + "_" + ielem.get_name() + "_Setitem(PyObject *self, Py_ssize_t index, PyObject *arg) {\n";
out << " " << cClassName << " *local_this = NULL;\n";
out << " if (!Dtool_Call_ExtractThisPointer_NonConst(self, Dtool_" << ClassName << ", (void **)&local_this, \""
<< classNameFromCppName(cClassName, false) << "." << ielem.get_name() << "\")) {\n";
out << " return -1;\n";
out << " }\n\n";
if (property->_has_this) {
out << " " << cClassName << " *local_this = NULL;\n";
out << " if (!Dtool_Call_ExtractThisPointer_NonConst(self, Dtool_" << ClassName << ", (void **)&local_this, \""
<< classNameFromCppName(cClassName, false) << "." << ielem.get_name() << "\")) {\n";
out << " return -1;\n";
out << " }\n\n";
}
out << " if (arg == (PyObject *)NULL) {\n";
if (property->_deleter != NULL) {
out << " local_this->" << property->_deleter->_ifunc.get_name() << "(index);\n"
<< " return 0;\n";
if (property->_deleter->_has_this) {
out << " local_this->" << property->_deleter->_ifunc.get_name() << "(index);\n";
} else {
out << " " << cClassName << "::" << property->_deleter->_ifunc.get_name() << "(index);\n";
}
out << " return 0;\n";
} else {
out << " Dtool_Raise_TypeError(\"can't delete " << ielem.get_name() << "[] attribute\");\n"
" return -1;\n";
@ -6511,9 +6565,13 @@ write_getset(ostream &out, Object *obj, Property *property) {
out << " }\n";
if (property->_clear_function != NULL) {
out << " if (arg == Py_None) {\n"
<< " local_this->" << property->_clear_function->_ifunc.get_name() << "(index);\n"
<< " return 0;\n"
out << " if (arg == Py_None) {\n";
if (property->_clear_function->_has_this) {
out << " local_this->" << property->_clear_function->_ifunc.get_name() << "(index);\n";
} else {
out << " " << cClassName << "::" << property->_clear_function->_ifunc.get_name() << "(index);\n";
}
out << " return 0;\n"
<< " }\n";
}
@ -6547,9 +6605,14 @@ write_getset(ostream &out, Object *obj, Property *property) {
}
// Now write the getter, which returns a special wrapper object.
out << "static PyObject *Dtool_" + ClassName + "_" + ielem.get_name() + "_Getter(PyObject *self, void *) {\n"
" Py_INCREF(self);\n"
" Dtool_SequenceWrapper *wrap = PyObject_New(Dtool_SequenceWrapper, &Dtool_SequenceWrapper_Type);\n"
out << "static PyObject *Dtool_" + ClassName + "_" + ielem.get_name() + "_Getter(PyObject *self, void *) {\n";
if (property->_has_this) {
out << " nassertr(self != NULL, NULL);\n"
" Py_INCREF(self);\n";
} else {
out << " Py_XINCREF(self);\n";
}
out << " Dtool_SequenceWrapper *wrap = PyObject_New(Dtool_SequenceWrapper, &Dtool_SequenceWrapper_Type);\n"
" wrap->_base = self;\n"
" wrap->_len_func = &Dtool_" << ClassName << "_" << ielem.get_name() << "_Len;\n"
" wrap->_getitem_func = &Dtool_" << ClassName << "_" << ielem.get_name() << "_Getitem;\n";
@ -6566,20 +6629,26 @@ write_getset(ostream &out, Object *obj, Property *property) {
out << "static PyObject *Dtool_" + ClassName + "_" + ielem.get_name() + "_Getter(PyObject *self, void *) {\n";
FunctionRemap *remap = property->_getter->_remaps.front();
if (remap->_const_method) {
out << " const " << cClassName << " *local_this = NULL;\n";
out << " if (!Dtool_Call_ExtractThisPointer(self, Dtool_" << ClassName << ", (void **)&local_this)) {\n";
} else {
out << " " << cClassName << " *local_this = NULL;\n";
out << " if (!Dtool_Call_ExtractThisPointer_NonConst(self, Dtool_" << ClassName << ", (void **)&local_this, \""
<< classNameFromCppName(cClassName, false) << "." << ielem.get_name() << "\")) {\n";
if (remap->_has_this) {
if (remap->_const_method) {
out << " const " << cClassName << " *local_this = NULL;\n";
out << " if (!Dtool_Call_ExtractThisPointer(self, Dtool_" << ClassName << ", (void **)&local_this)) {\n";
} else {
out << " " << cClassName << " *local_this = NULL;\n";
out << " if (!Dtool_Call_ExtractThisPointer_NonConst(self, Dtool_" << ClassName << ", (void **)&local_this, \""
<< classNameFromCppName(cClassName, false) << "." << ielem.get_name() << "\")) {\n";
}
out << " return NULL;\n";
out << " }\n\n";
}
out << " return NULL;\n";
out << " }\n\n";
if (property->_has_function != NULL) {
out << " if (!local_this->" << property->_has_function->_ifunc.get_name() << "()) {\n"
<< " Py_INCREF(Py_None);\n"
if (remap->_has_this) {
out << " if (!local_this->" << property->_has_function->_ifunc.get_name() << "()) {\n";
} else {
out << " if (!" << cClassName << "::" << property->_has_function->_ifunc.get_name() << "()) {\n";
}
out << " Py_INCREF(Py_None);\n"
<< " return Py_None;\n"
<< " }\n";
}
@ -6596,16 +6665,21 @@ write_getset(ostream &out, Object *obj, Property *property) {
// Write out a setter if this is not a read-only property.
if (property->_setter != NULL) {
out << "static int Dtool_" + ClassName + "_" + ielem.get_name() + "_Setter(PyObject *self, PyObject *arg, void *) {\n";
out << " " << cClassName << " *local_this = NULL;\n";
out << " if (!Dtool_Call_ExtractThisPointer_NonConst(self, Dtool_" << ClassName << ", (void **)&local_this, \""
<< classNameFromCppName(cClassName, false) << "." << ielem.get_name() << "\")) {\n";
out << " return -1;\n";
out << " }\n\n";
if (remap->_has_this) {
out << " " << cClassName << " *local_this = NULL;\n";
out << " if (!Dtool_Call_ExtractThisPointer_NonConst(self, Dtool_" << ClassName << ", (void **)&local_this, \""
<< classNameFromCppName(cClassName, false) << "." << ielem.get_name() << "\")) {\n";
out << " return -1;\n";
out << " }\n\n";
}
out << " if (arg == (PyObject *)NULL) {\n";
if (property->_deleter != NULL) {
if (property->_deleter != NULL && remap->_has_this) {
out << " local_this->" << property->_deleter->_ifunc.get_name() << "();\n"
<< " return 0;\n";
} else if (property->_deleter != NULL) {
out << " " << cClassName << "::" << property->_deleter->_ifunc.get_name() << "();\n"
<< " return 0;\n";
} else {
out << " Dtool_Raise_TypeError(\"can't delete " << ielem.get_name() << " attribute\");\n"
" return -1;\n";
@ -6613,9 +6687,13 @@ write_getset(ostream &out, Object *obj, Property *property) {
out << " }\n";
if (property->_clear_function != NULL) {
out << " if (arg == Py_None) {\n"
<< " local_this->" << property->_clear_function->_ifunc.get_name() << "();\n"
<< " return 0;\n"
out << " if (arg == Py_None) {\n";
if (remap->_has_this) {
out << " local_this->" << property->_clear_function->_ifunc.get_name() << "();\n";
} else {
out << " " << cClassName << "::" << property->_clear_function->_ifunc.get_name() << "();\n";
}
out << " return 0;\n"
<< " }\n";
}
@ -6744,6 +6822,7 @@ record_object(TypeIndex type_index) {
Function *setter = record_function(itype, func_index);
if (is_function_legal(setter)) {
property->_setter = setter;
property->_has_this |= setter->_has_this;
}
}
@ -6752,6 +6831,7 @@ record_object(TypeIndex type_index) {
Function *getter = record_function(itype, func_index);
if (is_function_legal(getter)) {
property->_getter = getter;
property->_has_this |= getter->_has_this;
}
}
@ -6760,6 +6840,7 @@ record_object(TypeIndex type_index) {
Function *has_function = record_function(itype, func_index);
if (is_function_legal(has_function)) {
property->_has_function = has_function;
property->_has_this |= has_function->_has_this;
}
}
@ -6768,6 +6849,7 @@ record_object(TypeIndex type_index) {
Function *clear_function = record_function(itype, func_index);
if (is_function_legal(clear_function)) {
property->_clear_function = clear_function;
property->_has_this |= clear_function->_has_this;
}
}
@ -6776,12 +6858,16 @@ record_object(TypeIndex type_index) {
Function *del_function = record_function(itype, func_index);
if (is_function_legal(del_function)) {
property->_deleter = del_function;
property->_has_this |= del_function->_has_this;
}
}
if (ielement.is_sequence()) {
FunctionIndex func_index = ielement.get_length_function();
property->_length_function = record_function(itype, func_index);
if (property->_length_function != nullptr) {
property->_has_this |= property->_length_function->_has_this;
}
}
if (property->_getter != NULL) {

View File

@ -618,8 +618,11 @@ PyObject *Dtool_PyModuleInitHelper(LibraryDef *defs[], const char *modulename) {
dtool_inited = true;
if (PyType_Ready(&Dtool_SequenceWrapper_Type) < 0) {
PyErr_SetString(PyExc_TypeError, "PyType_Ready(Dtool_SequenceWrapper)");
return NULL;
return Dtool_Raise_TypeError("PyType_Ready(Dtool_SequenceWrapper)");
}
if (PyType_Ready(&Dtool_StaticProperty_Type) < 0) {
return Dtool_Raise_TypeError("PyType_Ready(Dtool_StaticProperty_Type)");
}
// Initialize the base class of everything.
@ -1035,7 +1038,7 @@ bool Dtool_ExtractOptionalArg(PyObject **result, PyObject *args, PyObject *kwds)
static void Dtool_SequenceWrapper_dealloc(PyObject *self) {
Dtool_SequenceWrapper *wrap = (Dtool_SequenceWrapper *)self;
nassertv(wrap);
Py_DECREF(wrap->_base);
Py_XDECREF(wrap->_base);
}
static Py_ssize_t Dtool_SequenceWrapper_length(PyObject *self) {
@ -1131,4 +1134,136 @@ PyTypeObject Dtool_SequenceWrapper_Type = {
#endif
};
/**
* This is a variant of the Python getset mechanism that permits static
* properties.
*/
PyObject *
Dtool_NewStaticProperty(PyTypeObject *type, const PyGetSetDef *getset) {
PyGetSetDescrObject *descr;
descr = (PyGetSetDescrObject *)PyType_GenericAlloc(&Dtool_StaticProperty_Type, 0);
if (descr != nullptr) {
Py_XINCREF(type);
descr->d_getset = (PyGetSetDef *)getset;
#if PY_MAJOR_VERSION >= 3
descr->d_common.d_type = type;
descr->d_common.d_name = PyUnicode_InternFromString(getset->name);
#if PY_VERSION_HEX >= 0x03030000
descr->d_common.d_qualname = nullptr;
#endif
#else
descr->d_type = type;
descr->d_name = PyString_InternFromString(getset->name);
#endif
}
return (PyObject *)descr;
}
static void
Dtool_StaticProperty_dealloc(PyDescrObject *descr) {
_PyObject_GC_UNTRACK(descr);
Py_XDECREF(descr->d_type);
Py_XDECREF(descr->d_name);
//#if PY_MAJOR_VERSION >= 3
// Py_XDECREF(descr->d_qualname);
//#endif
PyObject_GC_Del(descr);
}
static PyObject *
Dtool_StaticProperty_repr(PyDescrObject *descr, const char *format) {
#if PY_MAJOR_VERSION >= 3
return PyUnicode_FromFormat("<attribute '%V' of '%s'>", descr->d_name, "?", descr->d_type->tp_name);
#else
return PyString_FromFormat("<attribute '%V' of '%s'>", descr->d_name, "?", descr->d_type->tp_name);
#endif
}
static int
Dtool_StaticProperty_traverse(PyObject *self, visitproc visit, void *arg) {
PyDescrObject *descr = (PyDescrObject *)self;
Py_VISIT(descr->d_type);
return 0;
}
static PyObject *
Dtool_StaticProperty_get(PyGetSetDescrObject *descr, PyObject *obj, PyObject *type) {
if (descr->d_getset->get != nullptr) {
return descr->d_getset->get(obj, descr->d_getset->closure);
} else {
return PyErr_Format(PyExc_AttributeError,
"attribute '%V' of type '%.100s' is not readable",
((PyDescrObject *)descr)->d_name, "?",
((PyDescrObject *)descr)->d_type->tp_name);
}
}
static int
Dtool_StaticProperty_set(PyGetSetDescrObject *descr, PyObject *obj, PyObject *value) {
if (descr->d_getset->set != nullptr) {
return descr->d_getset->set(obj, value, descr->d_getset->closure);
} else {
PyErr_Format(PyExc_AttributeError,
"attribute '%V' of type '%.100s' is not writable",
((PyDescrObject *)descr)->d_name, "?",
((PyDescrObject *)descr)->d_type->tp_name);
return -1;
}
}
PyTypeObject Dtool_StaticProperty_Type = {
PyVarObject_HEAD_INIT(&PyType_Type, 0)
"getset_descriptor",
sizeof(PyGetSetDescrObject),
0, // tp_itemsize
(destructor)Dtool_StaticProperty_dealloc,
0, // tp_print
0, // tp_getattr
0, // tp_setattr
0, // tp_reserved
(reprfunc)Dtool_StaticProperty_repr,
0, // tp_as_number
0, // tp_as_sequence
0, // tp_as_mapping
0, // tp_hash
0, // tp_call
0, // tp_str
PyObject_GenericGetAttr,
0, // tp_setattro
0, // tp_as_buffer
Py_TPFLAGS_DEFAULT,
0, // tp_doc
Dtool_StaticProperty_traverse,
0, // tp_clear
0, // tp_richcompare
0, // tp_weaklistoffset
0, // tp_iter
0, // tp_iternext
0, // tp_methods
0, // tp_members
0, // tp_getset
0, // tp_base
0, // tp_dict
(descrgetfunc)Dtool_StaticProperty_get,
(descrsetfunc)Dtool_StaticProperty_set,
0, // tp_dictoffset
0, // tp_init
0, // tp_alloc
0, // tp_new
0, // tp_del
0, // tp_is_gc
0, // tp_bases
0, // tp_mro
0, // tp_cache
0, // tp_subclasses
0, // tp_weaklist
0, // tp_del
#if PY_VERSION_HEX >= 0x02060000
0, // tp_version_tag
#endif
#if PY_VERSION_HEX >= 0x03040000
0, // tp_finalize
#endif
};
#endif // HAVE_PYTHON

View File

@ -471,6 +471,9 @@ struct Dtool_SequenceWrapper {
};
EXPCL_INTERROGATEDB extern PyTypeObject Dtool_SequenceWrapper_Type;
EXPCL_INTERROGATEDB extern PyTypeObject Dtool_StaticProperty_Type;
EXPCL_INTERROGATEDB PyObject *Dtool_NewStaticProperty(PyTypeObject *obj, const PyGetSetDef *getset);
/**
* These functions check whether the arguments passed to a function conform to

View File

@ -105,6 +105,7 @@ extern "C" {
EXPCL_PYSTUB int PyObject_Cmp(...);
EXPCL_PYSTUB int PyObject_Compare(...);
EXPCL_PYSTUB int PyObject_Free(...);
EXPCL_PYSTUB int PyObject_GC_Del(...);
EXPCL_PYSTUB int PyObject_GenericGetAttr(...);
EXPCL_PYSTUB int PyObject_GenericSetAttr(...);
EXPCL_PYSTUB int PyObject_GetAttrString(...);
@ -223,6 +224,7 @@ extern "C" {
EXPCL_PYSTUB extern void *PyExc_SystemExit;
EXPCL_PYSTUB extern void *PyExc_TypeError;
EXPCL_PYSTUB extern void *PyExc_ValueError;
EXPCL_PYSTUB extern void *PyType_Type;
EXPCL_PYSTUB extern void *_PyThreadState_Current;
EXPCL_PYSTUB extern void *_Py_FalseStruct;
EXPCL_PYSTUB extern void *_Py_NoneStruct;
@ -324,6 +326,7 @@ int PyObject_CallObject(...) { return 0; }
int PyObject_Cmp(...) { return 0; }
int PyObject_Compare(...) { return 0; }
int PyObject_Free(...) { return 0; }
int PyObject_GC_Del(...) { return 0; }
int PyObject_GenericGetAttr(...) { return 0; };
int PyObject_GenericSetAttr(...) { return 0; };
int PyObject_GetAttrString(...) { return 0; }
@ -448,6 +451,7 @@ void *PyExc_StopIteration = (void *)NULL;
void *PyExc_SystemExit = (void *)NULL;
void *PyExc_TypeError = (void *)NULL;
void *PyExc_ValueError = (void *)NULL;
void *PyType_Type = (void *)NULL;
void *_PyThreadState_Current = (void *)NULL;
void *_Py_FalseStruct = (void *)NULL;
void *_Py_NoneStruct = (void *)NULL;

View File

@ -89,7 +89,7 @@ hardware-animated-vertices #f
# Enable the model-cache, but only for models, not textures.
model-cache-dir $HOME/.panda3d/cache
model-cache-dir $XDG_CACHE_HOME/panda3d
model-cache-textures #f
# This option specifies the default profiles for Cg shaders.

View File

@ -1516,7 +1516,9 @@ def CompileLib(lib, obj, opts):
if HasTargetArch():
cmd += " /MACHINE:" + GetTargetArch().upper()
cmd += ' /OUT:' + BracketNameWithQuotes(lib)
for x in obj: cmd += ' ' + BracketNameWithQuotes(x)
for x in obj:
if not x.endswith('.lib'):
cmd += ' ' + BracketNameWithQuotes(x)
oscmd(cmd)
else:
# Choose Intel linker; from Jean-Claude
@ -1569,6 +1571,21 @@ def CompileLink(dll, obj, opts):
cmd += " /FIXED:NO /OPT:REF /STACK:4194304 /INCREMENTAL:NO "
cmd += ' /OUT:' + BracketNameWithQuotes(dll)
if not PkgSkip("PYTHON"):
# If we're building without Python, don't pick it up implicitly.
if "PYTHON" not in opts:
pythonv = SDK["PYTHONVERSION"].replace('.', '')
if optlevel <= 2:
cmd += ' /NOD:{}d.lib'.format(pythonv)
else:
cmd += ' /NOD:{}.lib'.format(pythonv)
# Yes, we know we are importing "locally defined symbols".
for x in obj:
if x.endswith('libp3pystub.lib'):
cmd += ' /ignore:4049,4217'
break
# Set the subsystem. Specify that we want to target Windows XP.
subsystem = GetValueOption(opts, "SUBSYSTEM:") or "CONSOLE"
cmd += " /SUBSYSTEM:" + subsystem
@ -2693,7 +2710,7 @@ if '__file__' in locals():
import os
bindir = os.path.join(os.path.dirname(__file__), '..', 'bin')
if os.path.isfile(os.path.join(bindir, 'libpanda.dll')):
if os.path.isdir(bindir):
if not os.environ.get('PATH'):
os.environ['PATH'] = bindir
else:
@ -2811,12 +2828,12 @@ else:
configprc = ReadFile("makepanda/config.in")
if (GetTarget() == 'windows'):
configprc = configprc.replace("$HOME/.panda3d", "$USER_APPDATA/Panda3D-%s" % MAJOR_VERSION)
configprc = configprc.replace("$XDG_CACHE_HOME/panda3d", "$USER_APPDATA/Panda3D-%s" % MAJOR_VERSION)
else:
configprc = configprc.replace("aux-display pandadx9", "")
if (GetTarget() == 'darwin'):
configprc = configprc.replace(".panda3d/cache", "Library/Caches/Panda3D-%s" % MAJOR_VERSION)
configprc = configprc.replace("$XDG_CACHE_HOME/panda3d", "Library/Caches/Panda3D-%s" % MAJOR_VERSION)
# OpenAL is not yet working well on OSX for us, so let's do this for now.
configprc = configprc.replace("p3openal_audio", "p3fmod_audio")
@ -4900,7 +4917,7 @@ if (PkgSkip("BULLET")==0 and not RUNTIME):
#
if (PkgSkip("PHYSX")==0):
OPTS=['DIR:panda/src/physx', 'BUILDING:PANDAPHYSX', 'PHYSX', 'NOARCH:PPC']
OPTS=['DIR:panda/src/physx', 'BUILDING:PANDAPHYSX', 'PHYSX', 'NOARCH:PPC', 'PYTHON']
TargetAdd('p3physx_composite.obj', opts=OPTS, input='p3physx_composite.cxx')
OPTS=['DIR:panda/src/physx', 'PHYSX', 'NOARCH:PPC', 'PYTHON']
@ -4920,7 +4937,7 @@ if (PkgSkip("PHYSX")==0):
TargetAdd('libpandaphysx.dll', input='pandaphysx_pandaphysx.obj')
TargetAdd('libpandaphysx.dll', input='p3physx_composite.obj')
TargetAdd('libpandaphysx.dll', input=COMMON_PANDA_LIBS)
TargetAdd('libpandaphysx.dll', opts=['WINUSER', 'PHYSX', 'NOARCH:PPC'])
TargetAdd('libpandaphysx.dll', opts=['WINUSER', 'PHYSX', 'NOARCH:PPC', 'PYTHON'])
OPTS=['DIR:panda/metalibs/pandaphysx', 'PHYSX', 'NOARCH:PPC', 'PYTHON']
TargetAdd('physx_module.obj', input='libpandaphysx.in')

View File

@ -2422,6 +2422,7 @@ def SetupVisualStudioEnviron():
winsdk_ver = SDK["MSPLATFORM_VERSION"]
if winsdk_ver.startswith('10.'):
AddToPathEnv("PATH", SDK["MSPLATFORM"] + "bin\\" + arch)
AddToPathEnv("PATH", SDK["MSPLATFORM"] + "bin\\" + winsdk_ver + "\\" + arch)
# Windows Kit 10 introduces the "universal CRT".
inc_dir = SDK["MSPLATFORM"] + "Include\\" + winsdk_ver + "\\"
@ -3157,6 +3158,17 @@ def TargetAdd(target, dummy=0, opts=[], input=[], dep=[], ipath=None, winrc=None
for d in CxxCalcDependencies(fullinput, ipath, []):
t.deps[d] = 1
# If we are linking statically, add the source DLL's dynamic dependencies.
if GetLinkAllStatic() and ORIG_EXT[fullinput] == '.lib' and fullinput in TARGET_TABLE:
tdep = TARGET_TABLE[fullinput]
for y in tdep.inputs:
if ORIG_EXT[y] == '.lib':
t.inputs.append(y)
for opt, _ in LIBNAMES + LIBDIRECTORIES + FRAMEWORKDIRECTORIES:
if opt in tdep.opts and opt not in t.opts:
t.opts.append(opt)
if x.endswith(".in"):
# Mark the _igate.cxx file as a dependency also.
outbase = os.path.basename(x)[:-3]

View File

@ -170,7 +170,7 @@ get_null_sound() {
*
*/
int AudioManager::
getSpeakerSetup() {
get_speaker_setup() {
// intentionally blank
return 0;
}
@ -179,7 +179,7 @@ getSpeakerSetup() {
*
*/
void AudioManager::
setSpeakerSetup(SpeakerModeCategory cat) {
set_speaker_setup(SpeakerModeCategory cat) {
// intentionally blank
}

View File

@ -62,8 +62,8 @@ PUBLISHED:
SM_stream,
};
virtual int getSpeakerSetup();
virtual void setSpeakerSetup(SpeakerModeCategory cat);
virtual int get_speaker_setup();
virtual void set_speaker_setup(SpeakerModeCategory cat);
virtual bool configure_filters(FilterProperties *config);
// Create an AudioManager for each category of sounds you have. E.g.
@ -172,6 +172,7 @@ PUBLISHED:
virtual PN_stdfloat audio_3d_get_drop_off_factor() const;
static Filename get_dls_pathname();
MAKE_PROPERTY(dls_pathname, get_dls_pathname);
virtual void output(ostream &out) const;
virtual void write(ostream &out) const;

View File

@ -447,7 +447,7 @@ get_sound(MovieAudio *source, bool positional, int) {
* This is to query if you are using a MultiChannel Setup.
*/
int FmodAudioManager::
getSpeakerSetup() {
get_speaker_setup() {
ReMutexHolder holder(_lock);
FMOD_RESULT result;
FMOD_SPEAKERMODE speakerMode;
@ -502,7 +502,7 @@ getSpeakerSetup() {
* init or re-init the AudioManagers after Panda is running.
*/
void FmodAudioManager::
setSpeakerSetup(AudioManager::SpeakerModeCategory cat) {
set_speaker_setup(AudioManager::SpeakerModeCategory cat) {
ReMutexHolder holder(_lock);
FMOD_RESULT result;
FMOD_SPEAKERMODE speakerModeType = (FMOD_SPEAKERMODE)cat;

View File

@ -91,8 +91,8 @@ public:
virtual PT(AudioSound) get_sound(const string&, bool positional = false, int mode=SM_heuristic);
virtual PT(AudioSound) get_sound(MovieAudio *, bool positional = false, int mode=SM_heuristic);
virtual int getSpeakerSetup();
virtual void setSpeakerSetup(SpeakerModeCategory cat);
virtual int get_speaker_setup();
virtual void set_speaker_setup(SpeakerModeCategory cat);
virtual void set_volume(PN_stdfloat);
virtual PN_stdfloat get_volume() const;

View File

@ -30,8 +30,8 @@ BulletHeightfieldShape(const BulletHeightfieldShape &copy) :
_num_rows(copy._num_rows),
_num_cols(copy._num_cols) {
_data = new float[_num_rows * _num_cols];
memcpy(_data, copy._data, _num_rows * _num_cols * sizeof(float));
_data = new btScalar[_num_rows * _num_cols];
memcpy(_data, copy._data, _num_rows * _num_cols * sizeof(btScalar));
}
/**
@ -44,6 +44,6 @@ operator = (const BulletHeightfieldShape &copy) {
_num_rows = copy._num_rows;
_num_cols = copy._num_cols;
_data = new float[_num_rows * _num_cols];
memcpy(_data, copy._data, _num_rows * _num_cols * sizeof(float));
_data = new btScalar[_num_rows * _num_cols];
memcpy(_data, copy._data, _num_rows * _num_cols * sizeof(btScalar));
}

View File

@ -26,7 +26,7 @@ BulletHeightfieldShape(const PNMImage &image, PN_stdfloat max_height, BulletUpAx
_num_rows = image.get_x_size();
_num_cols = image.get_y_size();
_data = new float[_num_rows * _num_cols];
_data = new btScalar[_num_rows * _num_cols];
for (int row=0; row < _num_rows; row++) {
for (int column=0; column < _num_cols; column++) {
@ -75,10 +75,10 @@ BulletHeightfieldShape(Texture *tex, PN_stdfloat max_height, BulletUpAxis up) {
_num_rows = tex->get_x_size() + 1;
_num_cols = tex->get_y_size() + 1;
_data = new float[_num_rows * _num_cols];
_data = new btScalar[_num_rows * _num_cols];
PN_stdfloat step_x = 1.0 / (PN_stdfloat)tex->get_x_size();
PN_stdfloat step_y = 1.0 / (PN_stdfloat)tex->get_y_size();
btScalar step_x = 1.0 / (btScalar)tex->get_x_size();
btScalar step_y = 1.0 / (btScalar)tex->get_y_size();
PT(TexturePeeker) peeker = tex->peek();
LColor sample;
@ -100,4 +100,4 @@ BulletHeightfieldShape(Texture *tex, PN_stdfloat max_height, BulletUpAxis up) {
up,
true, false);
_shape->setUserPointer(this);
}
}

View File

@ -44,7 +44,7 @@ public:
private:
int _num_rows;
int _num_cols;
float *_data;
btScalar *_data;
btHeightfieldTerrainShape *_shape;
public:

View File

@ -53,6 +53,10 @@ void BulletTriangleMesh::
preallocate(int num_verts, int num_indices) {
_vertices.reserve(num_verts);
_indices.reserve(num_indices);
btIndexedMesh &mesh = _mesh.getIndexedMeshArray()[0];
mesh.m_vertexBase = (unsigned char*)&_vertices[0];
mesh.m_triangleIndexBase = (unsigned char *)&_indices[0];
}
/**
@ -160,12 +164,22 @@ add_geom(const Geom *geom, bool remove_duplicate_vertices, const TransformState
_indices.reserve(_indices.size() + num_vertices);
mesh.m_numTriangles += num_vertices / 3;
GeomVertexReader index(prim->get_vertices(), 0);
while (!index.is_at_end()) {
_indices.push_back(index_offset + index.get_data1i());
CPT(GeomVertexArrayData) vertices = prim->get_vertices();
if (vertices != nullptr) {
GeomVertexReader index(move(vertices), 0);
while (!index.is_at_end()) {
_indices.push_back(index_offset + index.get_data1i());
}
} else {
int index = index_offset + prim->get_first_vertex();
int end_index = index + num_vertices;
while (index < end_index) {
_indices.push_back(index++);
}
}
}
}
nassertv(mesh.m_numTriangles * 3 == _indices.size());
} else {
// Collect points
@ -193,12 +207,22 @@ add_geom(const Geom *geom, bool remove_duplicate_vertices, const TransformState
_indices.reserve(_indices.size() + num_vertices);
mesh.m_numTriangles += num_vertices / 3;
GeomVertexReader index(prim->get_vertices(), 0);
while (!index.is_at_end()) {
_indices.push_back(find_or_add_vertex(points[index.get_data1i()]));
CPT(GeomVertexArrayData) vertices = prim->get_vertices();
if (vertices != nullptr) {
GeomVertexReader index(move(vertices), 0);
while (!index.is_at_end()) {
_indices.push_back(find_or_add_vertex(points[index.get_data1i()]));
}
} else {
int index = prim->get_first_vertex();
int end_index = index + num_vertices;
while (index < end_index) {
_indices.push_back(find_or_add_vertex(points[index]));
}
}
}
}
nassertv(mesh.m_numTriangles * 3 == _indices.size());
}
// Reset the pointers, since the vectors may have been reallocated.
@ -282,7 +306,7 @@ unsigned int BulletTriangleMesh::
find_or_add_vertex(const LVecBase3 &p) {
btVector3 vertex = LVecBase3_to_btVector3(p);
for (unsigned int i = 0; i < _vertices.size(); ++i) {
for (int i = 0; i < _vertices.size(); ++i) {
if ((_vertices[i] - vertex).length2() <= _welding_distance) {
return i;
}

View File

@ -277,7 +277,21 @@ process_events() {
break;
}
[NSApp sendEvent: event];
// If we're in fullscreen mode, send mouse events directly to the window.
NSEventType type = [event type];
if (_properties.get_fullscreen() && (
type == NSLeftMouseDown || type == NSLeftMouseUp ||
type == NSRightMouseDown || type == NSRightMouseUp ||
type == NSOtherMouseDown || type == NSOtherMouseUp ||
type == NSLeftMouseDragged ||
type == NSRightMouseDragged ||
type == NSOtherMouseDragged ||
type == NSMouseMoved ||
type == NSScrollWheel)) {
[_window sendEvent: event];
} else {
[NSApp sendEvent: event];
}
}
if (_window != nil) {

View File

@ -75,6 +75,7 @@ PUBLISHED:
MAKE_PROPERTY(collider_sort, get_collider_sort, set_collider_sort);
INLINE static CollideMask get_default_collide_mask();
MAKE_PROPERTY(default_collide_mask, get_default_collide_mask);
protected:
virtual void compute_internal_bounds(CPT(BoundingVolume) &internal_bounds,

View File

@ -99,7 +99,7 @@ draw(bool force, Thread *current_thread) {
data_reader.set_object(object->_munged_data);
data_reader.check_array_readers();
geom_reader.set_object(object->_geom);
geom_reader.draw(_gsg, object->_munger, &data_reader, force);
geom_reader.draw(_gsg, &data_reader, force);
} else {
// It has a callback associated.
object->draw_callback(_gsg, force, current_thread);

View File

@ -85,7 +85,7 @@ draw(bool force, Thread *current_thread) {
data_reader.set_object(object->_munged_data);
data_reader.check_array_readers();
geom_reader.set_object(object->_geom);
geom_reader.draw(_gsg, object->_munger, &data_reader, force);
geom_reader.draw(_gsg, &data_reader, force);
} else {
// It has a callback associated.
object->draw_callback(_gsg, force, current_thread);

View File

@ -99,7 +99,7 @@ draw(bool force, Thread *current_thread) {
data_reader.set_object(object->_munged_data);
data_reader.check_array_readers();
geom_reader.set_object(object->_geom);
geom_reader.draw(_gsg, object->_munger, &data_reader, force);
geom_reader.draw(_gsg, &data_reader, force);
} else {
// It has a callback associated.
object->draw_callback(_gsg, force, current_thread);

View File

@ -84,7 +84,7 @@ draw(bool force, Thread *current_thread) {
data_reader.set_object(object->_munged_data);
data_reader.check_array_readers();
geom_reader.set_object(object->_geom);
geom_reader.draw(_gsg, object->_munger, &data_reader, force);
geom_reader.draw(_gsg, &data_reader, force);
} else {
// It has a callback associated.
object->draw_callback(_gsg, force, current_thread);

View File

@ -69,7 +69,7 @@ draw(bool force, Thread *current_thread) {
data_reader.set_object(object->_munged_data);
data_reader.check_array_readers();
geom_reader.set_object(object->_geom);
geom_reader.draw(_gsg, object->_munger, &data_reader, force);
geom_reader.draw(_gsg, &data_reader, force);
} else {
// It has a callback associated.
object->draw_callback(_gsg, force, current_thread);

View File

@ -581,9 +581,13 @@ get_quality(const FrameBufferProperties &reqs) const {
}
}
// Bonus for each depth bit. Extra: 2 per bit.
// Bonus for each depth bit. Extra: 8 per bit.
// Please note that the Intel Windows driver only gives extra depth in
// combination with a stencil buffer, so we need 8 extra depth bits to
// outweigh the penalty of 50 for the unwanted stencil buffer, otherwise we
// will end up only getting 16-bit depth.
if (reqs._property[FBP_depth_bits] != 0) {
quality += 2 * _property[FBP_depth_bits];
quality += 8 * _property[FBP_depth_bits];
}
// Bonus for each multisample. Extra: 2 per sample.

View File

@ -44,6 +44,7 @@
#include "ambientLight.h"
#include "directionalLight.h"
#include "pointLight.h"
#include "sphereLight.h"
#include "spotlight.h"
#include "textureReloadRequest.h"
#include "shaderAttrib.h"
@ -1122,6 +1123,28 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name,
return &LMatrix4::ident_mat();
}
}
case Shader::SMO_texscale_i: {
const TexMatrixAttrib *tma;
const TextureAttrib *ta;
if (_target_rs->get_attrib(ta) && _target_rs->get_attrib(tma) &&
index < ta->get_num_on_stages()) {
LVecBase3 scale = tma->get_transform(ta->get_on_stage(index))->get_scale();
t = LMatrix4(0,0,0,0,0,0,0,0,0,0,0,0,scale[0],scale[1],scale[2],0);
return &t;
} else {
return &LMatrix4::ident_mat();
}
}
case Shader::SMO_texcolor_i: {
const TextureAttrib *ta;
if (_target_rs->get_attrib(ta) && index < ta->get_num_on_stages()) {
TextureStage *ts = ta->get_on_stage(index);
t.set_row(3, ts->get_color());
return &t;
} else {
return &LMatrix4::zeros_mat();
}
}
case Shader::SMO_tex_is_alpha_i: {
// This is a hack so we can support both F_alpha and other formats in the
// default shader, to fix font rendering in GLES2
@ -1156,9 +1179,14 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name,
nassertr(!np.is_empty(), &LMatrix4::zeros_mat());
const PlaneNode *plane_node;
DCAST_INTO_R(plane_node, np.node(), &LMatrix4::zeros_mat());
LPlane p (plane_node->get_plane());
p.xform(np.get_net_transform()->get_mat()); // World-space
t = LMatrix4(0,0,0,0,0,0,0,0,0,0,0,0,p[0],p[1],p[2],p[3]);
// Transform plane to world space
CPT(TransformState) transform = np.get_net_transform();
LPlane plane = plane_node->get_plane();
if (!transform->is_identity()) {
plane.xform(transform->get_mat());
}
t.set_row(3, plane);
return &t;
}
case Shader::SMO_apiview_clipplane_i: {
@ -1195,7 +1223,6 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name,
}
case Shader::SMO_world_to_view: {
return &(_scene_setup->get_world_transform()->get_mat());
break;
}
case Shader::SMO_view_to_world: {
return &(_scene_setup->get_camera_transform()->get_mat());
@ -1387,6 +1414,62 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name,
}
return fetch_specified_member(NodePath(), name, t);
}
case Shader::SMO_light_source_i_packed: {
// The light matrix contains COLOR, ATTENUATION, POSITION, VIEWVECTOR
const LightAttrib *target_light;
_target_rs->get_attrib_def(target_light);
// We don't count ambient lights, which would be pretty silly to handle
// via this mechanism.
size_t num_lights = target_light->get_num_non_ambient_lights();
if (index >= 0 && (size_t)index < num_lights) {
NodePath np = target_light->get_on_light((size_t)index);
nassertr(!np.is_empty(), &LMatrix4::ident_mat());
PandaNode *node = np.node();
Light *light = node->as_light();
nassertr(light != nullptr, &LMatrix4::zeros_mat());
t.set_row(0, light->get_color());
t.set_row(1, light->get_attenuation());
LMatrix4 mat = np.get_net_transform()->get_mat() *
_scene_setup->get_world_transform()->get_mat();
if (node->is_of_type(DirectionalLight::get_class_type())) {
LVecBase3 d = mat.xform_vec(((const DirectionalLight *)node)->get_direction());
d.normalize();
t.set_row(2, LVecBase4(d, 0));
t.set_row(3, LVecBase4(-d, 0));
} else if (node->is_of_type(LightLensNode::get_class_type())) {
const Lens *lens = ((const LightLensNode *)node)->get_lens();
LPoint3 p = mat.xform_point(lens->get_nodal_point());
t.set_row(3, LVecBase4(p));
// For shadowed point light we need to store near/far.
// For spotlight we need to store cutoff angle.
if (node->is_of_type(Spotlight::get_class_type())) {
PN_stdfloat cutoff = ccos(deg_2_rad(lens->get_hfov() * 0.5f));
LVecBase3 d = -(mat.xform_vec(lens->get_view_vector()));
t.set_cell(1, 3, ((const Spotlight *)node)->get_exponent());
t.set_row(2, LVecBase4(d, cutoff));
} else if (node->is_of_type(PointLight::get_class_type())) {
t.set_cell(1, 3, lens->get_far());
t.set_cell(3, 3, lens->get_near());
if (node->is_of_type(SphereLight::get_class_type())) {
t.set_cell(2, 3, ((const SphereLight *)node)->get_radius());
}
}
}
} else if (index == 0) {
// Apply the default OpenGL lights otherwise.
// Special exception for light 0, which defaults to white.
t.set_row(0, _light_color_scale);
}
return &t;
}
default:
nassertr(false /*should never get here*/, &LMatrix4::ident_mat());
return &LMatrix4::ident_mat();
@ -2263,10 +2346,8 @@ finish_decal() {
*/
bool GraphicsStateGuardian::
begin_draw_primitives(const GeomPipelineReader *geom_reader,
const GeomMunger *munger,
const GeomVertexDataPipelineReader *data_reader,
bool force) {
_munger = munger;
_data_reader = data_reader;
// Always draw if we have a shader, since the shader might use a different
@ -2337,7 +2418,6 @@ draw_points(const GeomPrimitivePipelineReader *, bool) {
*/
void GraphicsStateGuardian::
end_draw_primitives() {
_munger = NULL;
_data_reader = NULL;
}

View File

@ -367,7 +367,6 @@ public:
virtual void finish_decal();
virtual bool begin_draw_primitives(const GeomPipelineReader *geom_reader,
const GeomMunger *munger,
const GeomVertexDataPipelineReader *data_reader,
bool force);
virtual bool draw_triangles(const GeomPrimitivePipelineReader *reader,
@ -496,9 +495,8 @@ protected:
CPT(ShaderAttrib) _state_shader;
CPT(ShaderAttrib) _target_shader;
// These are set by begin_draw_primitives(), and are only valid between
// This is set by begin_draw_primitives(), and are only valid between
// begin_draw_primitives() and end_draw_primitives().
CPT(GeomMunger) _munger;
const GeomVertexDataPipelineReader *_data_reader;
unsigned int _color_write_mask;

View File

@ -343,28 +343,29 @@ munge_state_impl(const RenderState *state) {
#ifdef HAVE_CG
if (_auto_shader) {
CPT(RenderState) shader_state = munged_state->get_auto_shader_state();
GraphicsStateGuardian *gsg = get_gsg();
ShaderGenerator *shader_generator = gsg->get_shader_generator();
if (shader_generator == nullptr) {
shader_generator = new ShaderGenerator(gsg);
gsg->set_shader_generator(shader_generator);
}
if (shader_state->_generated_shader == NULL) {
if (munged_state->_generated_shader == nullptr) {
// Cache the generated ShaderAttrib on the shader state.
GeomVertexAnimationSpec spec;
// Currently we overload this flag to request vertex animation for the
// shader generator.
const ShaderAttrib *sattr;
shader_state->get_attrib_def(sattr);
munged_state->get_attrib_def(sattr);
if (sattr->get_flag(ShaderAttrib::F_hardware_skinning)) {
spec.set_hardware(4, true);
}
shader_state->_generated_shader = shader_generator->synthesize_shader(shader_state, spec);
munged_state->_generated_shader = shader_generator->synthesize_shader(munged_state, spec);
}
if (munged_state->_generated_shader != nullptr) {
munged_state = munged_state->set_attrib(munged_state->_generated_shader);
}
munged_state = munged_state->set_attrib(shader_state->_generated_shader);
}
#endif

View File

@ -49,6 +49,8 @@ PUBLISHED:
static WindowProperties get_default();
static void set_default(const WindowProperties &default_properties);
static void clear_default();
MAKE_PROPERTY(config_properties, get_config_properties);
MAKE_PROPERTY(default, get_default, set_default);
static WindowProperties size(int x_size, int y_size);

View File

@ -1141,11 +1141,9 @@ end_frame(Thread *current_thread) {
*/
bool DXGraphicsStateGuardian9::
begin_draw_primitives(const GeomPipelineReader *geom_reader,
const GeomMunger *munger,
const GeomVertexDataPipelineReader *data_reader,
bool force) {
if (!GraphicsStateGuardian::begin_draw_primitives(geom_reader, munger,
data_reader, force)) {
if (!GraphicsStateGuardian::begin_draw_primitives(geom_reader, data_reader, force)) {
return false;
}
nassertr(_data_reader != (GeomVertexDataPipelineReader *)NULL, false);

View File

@ -106,7 +106,6 @@ public:
virtual void end_frame(Thread *current_thread);
virtual bool begin_draw_primitives(const GeomPipelineReader *geom_reader,
const GeomMunger *munger,
const GeomVertexDataPipelineReader *data_reader,
bool force);
virtual bool draw_triangles(const GeomPrimitivePipelineReader *reader,

View File

@ -29,9 +29,9 @@ PUBLISHED:
INLINE EggLine &operator = (const EggLine &copy);
virtual ~EggLine();
virtual EggLine *make_copy() const OVERRIDE;
virtual EggLine *make_copy() const override;
virtual void write(ostream &out, int indent_level) const OVERRIDE;
virtual void write(ostream &out, int indent_level) const override;
INLINE bool has_thick() const;
INLINE double get_thick() const;
@ -39,7 +39,7 @@ PUBLISHED:
INLINE void clear_thick();
protected:
virtual int get_num_lead_vertices() const OVERRIDE;
virtual int get_num_lead_vertices() const override;
private:
double _thick;
@ -54,10 +54,10 @@ public:
register_type(_type_handle, "EggLine",
EggCompositePrimitive::get_class_type());
}
virtual TypeHandle get_type() const OVERRIDE {
virtual TypeHandle get_type() const override {
return get_class_type();
}
virtual TypeHandle force_init_type() OVERRIDE {
virtual TypeHandle force_init_type() override {
init_type();
return get_class_type();
}

View File

@ -29,7 +29,7 @@ PUBLISHED:
INLINE EggNurbsCurve(const EggNurbsCurve &copy);
INLINE EggNurbsCurve &operator = (const EggNurbsCurve &copy);
virtual EggNurbsCurve *make_copy() const OVERRIDE;
virtual EggNurbsCurve *make_copy() const override;
void setup(int order, int num_knots);
@ -50,7 +50,7 @@ PUBLISHED:
INLINE double get_knot(int k) const;
MAKE_SEQ(get_knots, get_num_knots, get_knot);
virtual void write(ostream &out, int indent_level) const OVERRIDE;
virtual void write(ostream &out, int indent_level) const override;
MAKE_PROPERTY(order, get_order, set_order);
MAKE_PROPERTY(degree, get_degree);
@ -72,10 +72,10 @@ public:
register_type(_type_handle, "EggNurbsCurve",
EggCurve::get_class_type());
}
virtual TypeHandle get_type() const OVERRIDE {
virtual TypeHandle get_type() const override {
return get_class_type();
}
virtual TypeHandle force_init_type() OVERRIDE {
virtual TypeHandle force_init_type() override {
init_type();
return get_class_type();
}

View File

@ -36,7 +36,7 @@ PUBLISHED:
INLINE EggNurbsSurface(const EggNurbsSurface &copy);
INLINE EggNurbsSurface &operator = (const EggNurbsSurface &copy);
virtual EggNurbsSurface *make_copy() const OVERRIDE;
virtual EggNurbsSurface *make_copy() const override;
void setup(int u_order, int v_order,
int num_u_knots, int num_v_knots);
@ -75,14 +75,14 @@ PUBLISHED:
MAKE_SEQ(get_v_knots, get_num_v_knots, get_v_knot);
INLINE EggVertex *get_cv(int ui, int vi) const;
virtual void write(ostream &out, int indent_level) const OVERRIDE;
virtual void write(ostream &out, int indent_level) const override;
public:
Curves _curves_on_surface;
Trims _trims;
protected:
virtual void r_apply_texmats(EggTextureCollection &textures) OVERRIDE;
virtual void r_apply_texmats(EggTextureCollection &textures) override;
private:
typedef vector_double Knots;
@ -101,10 +101,10 @@ public:
register_type(_type_handle, "EggNurbsSurface",
EggSurface::get_class_type());
}
virtual TypeHandle get_type() const OVERRIDE {
virtual TypeHandle get_type() const override {
return get_class_type();
}
virtual TypeHandle force_init_type() OVERRIDE {
virtual TypeHandle force_init_type() override {
init_type();
return get_class_type();
}

View File

@ -28,9 +28,9 @@ PUBLISHED:
INLINE EggPatch(const EggPatch &copy);
INLINE EggPatch &operator = (const EggPatch &copy);
virtual EggPatch *make_copy() const OVERRIDE;
virtual EggPatch *make_copy() const override;
virtual void write(ostream &out, int indent_level) const OVERRIDE;
virtual void write(ostream &out, int indent_level) const override;
public:
static TypeHandle get_class_type() {
@ -41,10 +41,10 @@ public:
register_type(_type_handle, "EggPatch",
EggPrimitive::get_class_type());
}
virtual TypeHandle get_type() const OVERRIDE {
virtual TypeHandle get_type() const override {
return get_class_type();
}
virtual TypeHandle force_init_type() OVERRIDE {
virtual TypeHandle force_init_type() override {
init_type();
return get_class_type();
}

View File

@ -28,7 +28,7 @@ PUBLISHED:
INLINE EggPoint(const EggPoint &copy);
INLINE EggPoint &operator = (const EggPoint &copy);
virtual EggPoint *make_copy() const OVERRIDE;
virtual EggPoint *make_copy() const override;
INLINE bool has_thick() const;
INLINE double get_thick() const;
@ -40,9 +40,9 @@ PUBLISHED:
INLINE void set_perspective(bool perspective);
INLINE void clear_perspective();
virtual bool cleanup() OVERRIDE;
virtual bool cleanup() override;
virtual void write(ostream &out, int indent_level) const OVERRIDE;
virtual void write(ostream &out, int indent_level) const override;
private:
enum Flags {
@ -64,10 +64,10 @@ public:
register_type(_type_handle, "EggPoint",
EggPrimitive::get_class_type());
}
virtual TypeHandle get_type() const OVERRIDE {
virtual TypeHandle get_type() const override {
return get_class_type();
}
virtual TypeHandle force_init_type() OVERRIDE {
virtual TypeHandle force_init_type() override {
init_type();
return get_class_type();
}

View File

@ -27,9 +27,9 @@ PUBLISHED:
INLINE EggPolygon(const EggPolygon &copy);
INLINE EggPolygon &operator = (const EggPolygon &copy);
virtual EggPolygon *make_copy() const OVERRIDE;
virtual EggPolygon *make_copy() const override;
virtual bool cleanup() OVERRIDE;
virtual bool cleanup() override;
bool calculate_normal(LNormald &result, CoordinateSystem cs = CS_default) const;
bool is_planar() const;
@ -39,7 +39,7 @@ PUBLISHED:
INLINE bool triangulate_into(EggGroupNode *container, bool convex_also) const;
PT(EggPolygon) triangulate_in_place(bool convex_also);
virtual void write(ostream &out, int indent_level) const OVERRIDE;
virtual void write(ostream &out, int indent_level) const override;
private:
bool decomp_concave(EggGroupNode *container, int asum, int x, int y) const;
@ -55,10 +55,10 @@ public:
register_type(_type_handle, "EggPolygon",
EggPrimitive::get_class_type());
}
virtual TypeHandle get_type() const OVERRIDE {
virtual TypeHandle get_type() const override {
return get_class_type();
}
virtual TypeHandle force_init_type() OVERRIDE {
virtual TypeHandle force_init_type() override {
init_type();
return get_class_type();
}

View File

@ -29,14 +29,14 @@ PUBLISHED:
INLINE EggTriangleFan &operator = (const EggTriangleFan &copy);
virtual ~EggTriangleFan();
virtual EggTriangleFan *make_copy() const OVERRIDE;
virtual EggTriangleFan *make_copy() const override;
virtual void write(ostream &out, int indent_level) const OVERRIDE;
virtual void apply_first_attribute() OVERRIDE;
virtual void write(ostream &out, int indent_level) const override;
virtual void apply_first_attribute() override;
protected:
virtual int get_num_lead_vertices() const OVERRIDE;
virtual bool do_triangulate(EggGroupNode *container) const OVERRIDE;
virtual int get_num_lead_vertices() const override;
virtual bool do_triangulate(EggGroupNode *container) const override;
public:
static TypeHandle get_class_type() {
@ -47,10 +47,10 @@ public:
register_type(_type_handle, "EggTriangleFan",
EggCompositePrimitive::get_class_type());
}
virtual TypeHandle get_type() const OVERRIDE {
virtual TypeHandle get_type() const override {
return get_class_type();
}
virtual TypeHandle force_init_type() OVERRIDE {
virtual TypeHandle force_init_type() override {
init_type();
return get_class_type();
}

View File

@ -29,13 +29,13 @@ PUBLISHED:
INLINE EggTriangleStrip &operator = (const EggTriangleStrip &copy);
virtual ~EggTriangleStrip();
virtual EggTriangleStrip *make_copy() const OVERRIDE;
virtual EggTriangleStrip *make_copy() const override;
virtual void write(ostream &out, int indent_level) const OVERRIDE;
virtual void write(ostream &out, int indent_level) const override;
protected:
virtual int get_num_lead_vertices() const OVERRIDE;
virtual bool do_triangulate(EggGroupNode *container) const OVERRIDE;
virtual int get_num_lead_vertices() const override;
virtual bool do_triangulate(EggGroupNode *container) const override;
public:
static TypeHandle get_class_type() {
@ -46,10 +46,10 @@ public:
register_type(_type_handle, "EggTriangleStrip",
EggCompositePrimitive::get_class_type());
}
virtual TypeHandle get_type() const OVERRIDE {
virtual TypeHandle get_type() const override {
return get_class_type();
}
virtual TypeHandle force_init_type() OVERRIDE {
virtual TypeHandle force_init_type() override {
init_type();
return get_class_type();
}

View File

@ -75,6 +75,9 @@ private:
#include "memoryInfo.I"
#else
class MemoryInfo;
#endif // DO_MEMORY_USAGE
#endif

View File

@ -16,9 +16,13 @@
* to true, indicating that this class will be in effect. If this returns
* false, the user has indicated not to do any of this.
*/
INLINE bool MemoryUsage::
ALWAYS_INLINE bool MemoryUsage::
get_track_memory_usage() {
#ifdef DO_MEMORY_USAGE
return get_global_ptr()->_track_memory_usage;
#else
return false;
#endif
}
/**
@ -26,7 +30,19 @@ get_track_memory_usage() {
*/
INLINE void MemoryUsage::
record_pointer(ReferenceCount *ptr) {
#ifdef DO_MEMORY_USAGE
get_global_ptr()->ns_record_pointer(ptr);
#endif
}
/**
* Indicates that the given pointer has been recently allocated.
*/
INLINE void MemoryUsage::
record_pointer(void *ptr, TypeHandle type) {
#ifdef DO_MEMORY_USAGE
get_global_ptr()->ns_record_pointer(ptr, type);
#endif
}
/**
@ -37,7 +53,9 @@ record_pointer(ReferenceCount *ptr) {
*/
INLINE void MemoryUsage::
update_type(ReferenceCount *ptr, TypeHandle type) {
get_global_ptr()->ns_update_type(ptr, type);
#ifdef DO_MEMORY_USAGE
get_global_ptr()->ns_update_type((void *)ptr, type);
#endif
}
/**
@ -48,7 +66,21 @@ update_type(ReferenceCount *ptr, TypeHandle type) {
*/
INLINE void MemoryUsage::
update_type(ReferenceCount *ptr, TypedObject *typed_ptr) {
get_global_ptr()->ns_update_type(ptr, typed_ptr);
#ifdef DO_MEMORY_USAGE
get_global_ptr()->ns_update_type((void *)ptr, typed_ptr);
#endif
}
/**
* Associates the indicated type with the given pointer. This should be
* called by functions (e.g. the constructor) that know more specifically
* what type of thing we've got.
*/
INLINE void MemoryUsage::
update_type(void *ptr, TypeHandle type) {
#ifdef DO_MEMORY_USAGE
get_global_ptr()->ns_update_type(ptr, type);
#endif
}
/**
@ -56,7 +88,9 @@ update_type(ReferenceCount *ptr, TypedObject *typed_ptr) {
*/
INLINE void MemoryUsage::
remove_pointer(ReferenceCount *ptr) {
#ifdef DO_MEMORY_USAGE
get_global_ptr()->ns_remove_pointer(ptr);
#endif
}
/**
@ -65,7 +99,11 @@ remove_pointer(ReferenceCount *ptr) {
*/
INLINE bool MemoryUsage::
is_tracking() {
#ifdef DO_MEMORY_USAGE
return get_global_ptr()->_track_memory_usage;
#else
return false;
#endif
}
/**
@ -75,7 +113,11 @@ is_tracking() {
*/
INLINE bool MemoryUsage::
is_counting() {
#ifdef DO_MEMORY_USAGE
return get_global_ptr()->_count_memory_usage;
#else
return false;
#endif
}
/**
@ -84,7 +126,11 @@ is_counting() {
*/
INLINE size_t MemoryUsage::
get_current_cpp_size() {
#ifdef DO_MEMORY_USAGE
return get_global_ptr()->_current_cpp_size;
#else
return 0;
#endif
}
/**
@ -93,7 +139,11 @@ get_current_cpp_size() {
*/
INLINE size_t MemoryUsage::
get_total_cpp_size() {
#ifdef DO_MEMORY_USAGE
return get_global_ptr()->_total_cpp_size;
#else
return 0;
#endif
}
/**
@ -102,7 +152,11 @@ get_total_cpp_size() {
*/
INLINE size_t MemoryUsage::
get_panda_heap_single_size() {
#ifdef DO_MEMORY_USAGE
return (size_t)AtomicAdjust::get(get_global_ptr()->_total_heap_single_size);
#else
return 0;
#endif
}
/**
@ -111,7 +165,11 @@ get_panda_heap_single_size() {
*/
INLINE size_t MemoryUsage::
get_panda_heap_array_size() {
#ifdef DO_MEMORY_USAGE
return (size_t)AtomicAdjust::get(get_global_ptr()->_total_heap_array_size);
#else
return 0;
#endif
}
/**
@ -121,7 +179,7 @@ get_panda_heap_array_size() {
*/
INLINE size_t MemoryUsage::
get_panda_heap_overhead() {
#if defined(USE_MEMORY_DLMALLOC) || defined(USE_MEMORY_PTMALLOC2)
#if defined(DO_MEMORY_USAGE) && (defined(USE_MEMORY_DLMALLOC) || defined(USE_MEMORY_PTMALLOC2))
MemoryUsage *mu = get_global_ptr();
return (size_t)(AtomicAdjust::get(mu->_requested_heap_size) - AtomicAdjust::get(mu->_total_heap_single_size) - AtomicAdjust::get(mu->_total_heap_array_size));
#else
@ -135,7 +193,11 @@ get_panda_heap_overhead() {
*/
INLINE size_t MemoryUsage::
get_panda_mmap_size() {
#ifdef DO_MEMORY_USAGE
return (size_t)AtomicAdjust::get(get_global_ptr()->_total_mmap_size);
#else
return 0;
#endif
}
/**
@ -152,6 +214,7 @@ get_panda_mmap_size() {
*/
INLINE size_t MemoryUsage::
get_external_size() {
#ifdef DO_MEMORY_USAGE
MemoryUsage *mu = get_global_ptr();
if (mu->_count_memory_usage) {
// We can only possibly know this with memory counting, which tracks every
@ -169,6 +232,9 @@ get_external_size() {
} else {
return 0;
}
#else
return 0;
#endif
}
/**
@ -177,6 +243,7 @@ get_external_size() {
*/
INLINE size_t MemoryUsage::
get_total_size() {
#ifdef DO_MEMORY_USAGE
MemoryUsage *mu = get_global_ptr();
if (mu->_count_memory_usage) {
return mu->_total_size + (size_t)mu->_requested_heap_size;
@ -187,6 +254,9 @@ get_total_size() {
return (size_t)(AtomicAdjust::get(mu->_total_heap_single_size) + AtomicAdjust::get(mu->_total_heap_array_size));
#endif
}
#else
return 0;
#endif
}
/**
@ -194,7 +264,11 @@ get_total_size() {
*/
INLINE int MemoryUsage::
get_num_pointers() {
#ifdef DO_MEMORY_USAGE
return get_global_ptr()->ns_get_num_pointers();
#else
return 0;
#endif
}
/**
@ -203,7 +277,9 @@ get_num_pointers() {
*/
INLINE void MemoryUsage::
get_pointers(MemoryUsagePointers &result) {
#ifdef DO_MEMORY_USAGE
get_global_ptr()->ns_get_pointers(result);
#endif
}
/**
@ -212,7 +288,9 @@ get_pointers(MemoryUsagePointers &result) {
*/
INLINE void MemoryUsage::
get_pointers_of_type(MemoryUsagePointers &result, TypeHandle type) {
#ifdef DO_MEMORY_USAGE
get_global_ptr()->ns_get_pointers_of_type(result, type);
#endif
}
/**
@ -221,7 +299,9 @@ get_pointers_of_type(MemoryUsagePointers &result, TypeHandle type) {
*/
INLINE void MemoryUsage::
get_pointers_of_age(MemoryUsagePointers &result, double from, double to) {
#ifdef DO_MEMORY_USAGE
get_global_ptr()->ns_get_pointers_of_age(result, from, to);
#endif
}
/**
@ -242,7 +322,9 @@ get_pointers_of_age(MemoryUsagePointers &result, double from, double to) {
*/
INLINE void MemoryUsage::
get_pointers_with_zero_count(MemoryUsagePointers &result) {
#ifdef DO_MEMORY_USAGE
get_global_ptr()->ns_get_pointers_with_zero_count(result);
#endif
}
/**
@ -253,7 +335,9 @@ get_pointers_with_zero_count(MemoryUsagePointers &result) {
*/
INLINE void MemoryUsage::
freeze() {
#ifdef DO_MEMORY_USAGE
get_global_ptr()->ns_freeze();
#endif
}
/**
@ -261,7 +345,9 @@ freeze() {
*/
INLINE void MemoryUsage::
show_current_types() {
#ifdef DO_MEMORY_USAGE
get_global_ptr()->ns_show_current_types();
#endif
}
/**
@ -270,7 +356,9 @@ show_current_types() {
*/
INLINE void MemoryUsage::
show_trend_types() {
#ifdef DO_MEMORY_USAGE
get_global_ptr()->ns_show_trend_types();
#endif
}
/**
@ -278,7 +366,9 @@ show_trend_types() {
*/
INLINE void MemoryUsage::
show_current_ages() {
#ifdef DO_MEMORY_USAGE
get_global_ptr()->ns_show_current_ages();
#endif
}
/**
@ -287,7 +377,9 @@ show_current_ages() {
*/
INLINE void MemoryUsage::
show_trend_ages() {
#ifdef DO_MEMORY_USAGE
get_global_ptr()->ns_show_trend_ages();
#endif
}
/**
@ -295,6 +387,7 @@ show_trend_ages() {
*/
INLINE MemoryUsage *MemoryUsage::
get_global_ptr() {
#ifdef DO_MEMORY_USAGE
#ifdef __GNUC__
// Tell the compiler that this is an unlikely branch.
if (__builtin_expect(_global_ptr == nullptr, 0)) {
@ -305,4 +398,7 @@ get_global_ptr() {
}
return _global_ptr;
#else
return nullptr;
#endif
}

View File

@ -12,9 +12,6 @@
*/
#include "memoryUsage.h"
#ifdef DO_MEMORY_USAGE
#include "memoryUsagePointers.h"
#include "trueClock.h"
#include "typedReferenceCount.h"
@ -45,16 +42,17 @@ double MemoryUsage::AgeHistogram::_cutoff[MemoryUsage::AgeHistogram::num_buckets
60.0,
};
/**
* Adds a single entry to the histogram.
*/
void MemoryUsage::TypeHistogram::
add_info(TypeHandle type, MemoryInfo *info) {
#ifdef DO_MEMORY_USAGE
_counts[type].add_info(info);
#endif
}
#ifdef DO_MEMORY_USAGE
// This class is a temporary class used only in TypeHistogram::show(), below,
// to sort the types in descending order by counts.
class TypeHistogramCountSorter {
@ -71,12 +69,14 @@ public:
MemoryUsagePointerCounts _count;
TypeHandle _type;
};
#endif
/**
* Shows the contents of the histogram to nout.
*/
void MemoryUsage::TypeHistogram::
show() const {
#ifdef DO_MEMORY_USAGE
// First, copy the relevant information to a vector so we can sort by
// counts. Don't use a pvector.
typedef vector<TypeHistogramCountSorter> CountSorter;
@ -99,6 +99,7 @@ show() const {
}
nout << " : " << (*vi)._count << "\n";
}
#endif
}
/**
@ -122,9 +123,11 @@ AgeHistogram() {
*/
void MemoryUsage::AgeHistogram::
add_info(double age, MemoryInfo *info) {
#ifdef DO_MEMORY_USAGE
int bucket = choose_bucket(age);
nassertv(bucket >= 0 && bucket < num_buckets);
_counts[bucket].add_info(info);
#endif
}
/**
@ -132,6 +135,7 @@ add_info(double age, MemoryInfo *info) {
*/
void MemoryUsage::AgeHistogram::
show() const {
#ifdef DO_MEMORY_USAGE
for (int i = 0; i < num_buckets - 1; i++) {
nout << _cutoff[i] << " to " << _cutoff[i + 1] << " seconds old : ";
_counts[i].output(nout);
@ -140,6 +144,7 @@ show() const {
nout << _cutoff[num_buckets - 1] << " seconds old and up : ";
_counts[num_buckets - 1].output(nout);
nout << "\n";
#endif
}
/**
@ -147,9 +152,11 @@ show() const {
*/
void MemoryUsage::AgeHistogram::
clear() {
#ifdef DO_MEMORY_USAGE
for (int i = 0; i < num_buckets; i++) {
_counts[i].clear();
}
#endif
}
/**
@ -157,6 +164,7 @@ clear() {
*/
int MemoryUsage::AgeHistogram::
choose_bucket(double age) const {
#ifdef DO_MEMORY_USAGE
for (int i = num_buckets - 1; i >= 0; i--) {
if (age >= _cutoff[i]) {
return i;
@ -164,6 +172,7 @@ choose_bucket(double age) const {
}
express_cat.error()
<< "No suitable bucket for age " << age << "\n";
#endif
return 0;
}
@ -173,6 +182,7 @@ choose_bucket(double age) const {
*/
void *MemoryUsage::
heap_alloc_single(size_t size) {
#ifdef DO_MEMORY_USAGE
void *ptr;
if (_recursion_protect) {
@ -202,6 +212,9 @@ heap_alloc_single(size_t size) {
}
return ptr;
#else
return MemoryHook::heap_alloc_single(size);
#endif
}
/**
@ -209,6 +222,7 @@ heap_alloc_single(size_t size) {
*/
void MemoryUsage::
heap_free_single(void *ptr) {
#ifdef DO_MEMORY_USAGE
if (_recursion_protect) {
if (express_cat.is_spam()) {
express_cat.spam()
@ -231,6 +245,9 @@ heap_free_single(void *ptr) {
MemoryHook::heap_free_single(ptr);
}
}
#else
MemoryHook::heap_free_single(ptr);
#endif
}
/**
@ -239,6 +256,7 @@ heap_free_single(void *ptr) {
*/
void *MemoryUsage::
heap_alloc_array(size_t size) {
#ifdef DO_MEMORY_USAGE
void *ptr;
if (_recursion_protect) {
@ -268,6 +286,9 @@ heap_alloc_array(size_t size) {
}
return ptr;
#else
return MemoryHook::heap_alloc_array(size);
#endif
}
/**
@ -275,6 +296,7 @@ heap_alloc_array(size_t size) {
*/
void *MemoryUsage::
heap_realloc_array(void *ptr, size_t size) {
#ifdef DO_MEMORY_USAGE
if (_recursion_protect) {
ptr = MemoryHook::heap_realloc_array(ptr, size);
if (express_cat.is_spam()) {
@ -303,6 +325,9 @@ heap_realloc_array(void *ptr, size_t size) {
}
return ptr;
#else
return MemoryHook::heap_realloc_array(ptr, size);
#endif
}
/**
@ -310,6 +335,7 @@ heap_realloc_array(void *ptr, size_t size) {
*/
void MemoryUsage::
heap_free_array(void *ptr) {
#ifdef DO_MEMORY_USAGE
if (_recursion_protect) {
if (express_cat.is_spam()) {
express_cat.spam()
@ -332,6 +358,9 @@ heap_free_array(void *ptr) {
MemoryHook::heap_free_array(ptr);
}
}
#else
MemoryHook::heap_free_array(ptr);
#endif
}
/**
@ -343,6 +372,7 @@ heap_free_array(void *ptr) {
*/
void MemoryUsage::
mark_pointer(void *ptr, size_t size, ReferenceCount *ref_ptr) {
#ifdef DO_MEMORY_USAGE
if (_recursion_protect || !_track_memory_usage) {
return;
}
@ -391,6 +421,7 @@ mark_pointer(void *ptr, size_t size, ReferenceCount *ref_ptr) {
// We're removing this pointer from use.
ns_remove_void_pointer(ptr);
}
#endif
}
#if (defined(WIN32_VC) || defined (WIN64_VC))&& defined(_DEBUG)
@ -430,7 +461,23 @@ win32_malloc_hook(int alloc_type, void *ptr,
*
*/
MemoryUsage::
MemoryUsage(const MemoryHook &copy) : MemoryHook(copy) {
MemoryUsage(const MemoryHook &copy) :
MemoryHook(copy),
_info_set_dirty(false),
_freeze_index(0),
_count(0),
_current_cpp_size(0),
_total_cpp_size(0),
_total_size(0),
_track_memory_usage(false),
_startup_track_memory_usage(false),
_count_memory_usage(false),
_report_memory_usage(false),
_report_memory_interval(0.0),
_last_report_time(0.0) {
#ifdef DO_MEMORY_USAGE
// We must get these variables here instead of in config_express.cxx,
// because we need to know it at static init time, and who knows when the
// code in config_express will be executed.
@ -456,9 +503,6 @@ MemoryUsage(const MemoryHook &copy) : MemoryHook(copy) {
("report-memory-interval", 5.0,
PRC_DESC("This is the interval, in seconds, for reports of currently allocated "
"memory, when report-memory-usage is true."));
_last_report_time = 0.0;
_count_memory_usage = false;
int64_t max_heap_size = ConfigVariableInt64
("max-heap-size", 0,
@ -480,13 +524,7 @@ MemoryUsage(const MemoryHook &copy) : MemoryHook(copy) {
_CrtSetAllocHook(&win32_malloc_hook);
_count_memory_usage = true;
#endif
_info_set_dirty = false;
_freeze_index = 0;
_count = 0;
_current_cpp_size = 0;
_total_cpp_size = 0;
_total_size = 0;
#endif // DO_MEMORY_USAGE
}
/**
@ -494,9 +532,16 @@ MemoryUsage(const MemoryHook &copy) : MemoryHook(copy) {
*/
void MemoryUsage::
init_memory_usage() {
#ifdef DO_MEMORY_USAGE
init_memory_hook();
_global_ptr = new MemoryUsage(*memory_hook);
memory_hook = _global_ptr;
#else
// If this gets called, we still need to initialize the global_ptr with a
// stub even if we don't compile with memory usage tracking enabled, for ABI
// stability. However, we won't replace the memory hook.
_global_ptr = new MemoryUsage(*memory_hook);
#endif
}
/**
@ -507,6 +552,7 @@ init_memory_usage() {
*/
void MemoryUsage::
overflow_heap_size() {
#ifdef DO_MEMORY_USAGE
MemoryHook::overflow_heap_size();
express_cat.error()
@ -524,6 +570,7 @@ overflow_heap_size() {
// Turn on spamful debugging.
_track_memory_usage = true;
_report_memory_usage = true;
#endif
}
/**
@ -531,12 +578,13 @@ overflow_heap_size() {
*/
void MemoryUsage::
ns_record_pointer(ReferenceCount *ptr) {
#ifdef DO_MEMORY_USAGE
if (_track_memory_usage) {
// We have to protect modifications to the table from recursive calls by
// toggling _recursion_protect while we adjust it.
_recursion_protect = true;
pair<Table::iterator, bool> insert_result =
_table.insert(Table::value_type((void *)ptr, (MemoryInfo *)NULL));
_table.insert(Table::value_type((void *)ptr, nullptr));
// This shouldn't fail.
assert(insert_result.first != _table.end());
@ -575,6 +623,61 @@ ns_record_pointer(ReferenceCount *ptr) {
}
}
}
#endif
}
/**
* Indicates that the given pointer has been recently allocated.
*/
void MemoryUsage::
ns_record_pointer(void *ptr, TypeHandle type) {
#ifdef DO_MEMORY_USAGE
if (_track_memory_usage) {
// We have to protect modifications to the table from recursive calls by
// toggling _recursion_protect while we adjust it.
_recursion_protect = true;
pair<Table::iterator, bool> insert_result =
_table.insert(Table::value_type(ptr, nullptr));
// This shouldn't fail.
assert(insert_result.first != _table.end());
if (insert_result.second) {
(*insert_result.first).second = new MemoryInfo;
_info_set_dirty = true;
++_count;
}
MemoryInfo *info = (*insert_result.first).second;
// We should already have a pointer, thanks to a previous call to
// mark_pointer().
nassertv(info->_void_ptr == ptr && info->_ref_ptr == nullptr);
info->_void_ptr = ptr;
info->_static_type = type;
info->_dynamic_type = type;
info->_time = TrueClock::get_global_ptr()->get_long_time();
info->_freeze_index = _freeze_index;
info->_flags |= MemoryInfo::F_reconsider_dynamic_type;
// We close the recursion_protect flag all the way down here, so that we
// also protect ourselves against a possible recursive call in
// TrueClock::get_global_ptr().
_recursion_protect = false;
if (_report_memory_usage) {
double now = TrueClock::get_global_ptr()->get_long_time();
if (now - _last_report_time > _report_memory_interval) {
_last_report_time = now;
express_cat.info()
<< "*** Current memory usage: " << get_total_size() << "\n";
show_current_types();
}
}
}
#endif
}
/**
@ -584,7 +687,8 @@ ns_record_pointer(ReferenceCount *ptr) {
* only that it's a "ReferenceCount".
*/
void MemoryUsage::
ns_update_type(ReferenceCount *ptr, TypeHandle type) {
ns_update_type(void *ptr, TypeHandle type) {
#ifdef DO_MEMORY_USAGE
if (_track_memory_usage) {
Table::iterator ti;
ti = _table.find(ptr);
@ -592,7 +696,7 @@ ns_update_type(ReferenceCount *ptr, TypeHandle type) {
if (_startup_track_memory_usage) {
express_cat.error()
<< "Attempt to update type to " << type << " for unrecorded pointer "
<< (void *)ptr << "!\n";
<< ptr << "!\n";
nassertv(false);
}
return;
@ -605,6 +709,7 @@ ns_update_type(ReferenceCount *ptr, TypeHandle type) {
consolidate_void_ptr(info);
}
#endif
}
/**
@ -614,7 +719,8 @@ ns_update_type(ReferenceCount *ptr, TypeHandle type) {
* the pointer as a TypedObject it doesn't need any more help.
*/
void MemoryUsage::
ns_update_type(ReferenceCount *ptr, TypedObject *typed_ptr) {
ns_update_type(void *ptr, TypedObject *typed_ptr) {
#ifdef DO_MEMORY_USAGE
if (_track_memory_usage) {
Table::iterator ti;
ti = _table.find(ptr);
@ -623,7 +729,7 @@ ns_update_type(ReferenceCount *ptr, TypedObject *typed_ptr) {
express_cat.error()
<< "Attempt to update type to " << typed_ptr->get_type()
<< " for unrecorded pointer "
<< (void *)ptr << "!\n";
<< ptr << "!\n";
}
return;
}
@ -634,6 +740,7 @@ ns_update_type(ReferenceCount *ptr, TypedObject *typed_ptr) {
consolidate_void_ptr(info);
}
#endif
}
/**
@ -641,6 +748,7 @@ ns_update_type(ReferenceCount *ptr, TypedObject *typed_ptr) {
*/
void MemoryUsage::
ns_remove_pointer(ReferenceCount *ptr) {
#ifdef DO_MEMORY_USAGE
if (_track_memory_usage) {
Table::iterator ti;
ti = _table.find(ptr);
@ -705,6 +813,7 @@ ns_remove_pointer(ReferenceCount *ptr) {
}
}
}
#endif
}
/**
@ -713,6 +822,7 @@ ns_remove_pointer(ReferenceCount *ptr) {
*/
void MemoryUsage::
ns_record_void_pointer(void *ptr, size_t size) {
#ifdef DO_MEMORY_USAGE
if (_track_memory_usage) {
if (express_cat.is_spam()) {
express_cat.spam()
@ -724,7 +834,7 @@ ns_record_void_pointer(void *ptr, size_t size) {
_recursion_protect = true;
pair<Table::iterator, bool> insert_result =
_table.insert(Table::value_type((void *)ptr, (MemoryInfo *)NULL));
_table.insert(Table::value_type((void *)ptr, nullptr));
assert(insert_result.first != _table.end());
@ -761,6 +871,7 @@ ns_record_void_pointer(void *ptr, size_t size) {
// TrueClock::get_global_ptr().
_recursion_protect = false;
}
#endif
}
/**
@ -768,6 +879,7 @@ ns_record_void_pointer(void *ptr, size_t size) {
*/
void MemoryUsage::
ns_remove_void_pointer(void *ptr) {
#ifdef DO_MEMORY_USAGE
if (_track_memory_usage) {
if (express_cat.is_spam()) {
express_cat.spam()
@ -823,6 +935,7 @@ ns_remove_void_pointer(void *ptr) {
_info_set_dirty = true;
delete info;
}
#endif
}
/**
@ -830,8 +943,12 @@ ns_remove_void_pointer(void *ptr) {
*/
int MemoryUsage::
ns_get_num_pointers() {
#ifdef DO_MEMORY_USAGE
nassertr(_track_memory_usage, 0);
return _count;
#else
return 0;
#endif
}
/**
@ -840,6 +957,7 @@ ns_get_num_pointers() {
*/
void MemoryUsage::
ns_get_pointers(MemoryUsagePointers &result) {
#ifdef DO_MEMORY_USAGE
nassertv(_track_memory_usage);
result.clear();
@ -857,6 +975,7 @@ ns_get_pointers(MemoryUsagePointers &result) {
now - info->_time);
}
}
#endif
}
/**
@ -865,6 +984,7 @@ ns_get_pointers(MemoryUsagePointers &result) {
*/
void MemoryUsage::
ns_get_pointers_of_type(MemoryUsagePointers &result, TypeHandle type) {
#ifdef DO_MEMORY_USAGE
nassertv(_track_memory_usage);
result.clear();
@ -886,6 +1006,7 @@ ns_get_pointers_of_type(MemoryUsagePointers &result, TypeHandle type) {
}
}
}
#endif
}
/**
@ -895,6 +1016,7 @@ ns_get_pointers_of_type(MemoryUsagePointers &result, TypeHandle type) {
void MemoryUsage::
ns_get_pointers_of_age(MemoryUsagePointers &result,
double from, double to) {
#ifdef DO_MEMORY_USAGE
nassertv(_track_memory_usage);
result.clear();
@ -915,6 +1037,7 @@ ns_get_pointers_of_age(MemoryUsagePointers &result,
}
}
}
#endif
}
/**
@ -935,6 +1058,7 @@ ns_get_pointers_of_age(MemoryUsagePointers &result,
*/
void MemoryUsage::
ns_get_pointers_with_zero_count(MemoryUsagePointers &result) {
#ifdef DO_MEMORY_USAGE
nassertv(_track_memory_usage);
result.clear();
@ -955,6 +1079,7 @@ ns_get_pointers_with_zero_count(MemoryUsagePointers &result) {
}
}
}
#endif
}
/**
@ -965,11 +1090,13 @@ ns_get_pointers_with_zero_count(MemoryUsagePointers &result) {
*/
void MemoryUsage::
ns_freeze() {
#ifdef DO_MEMORY_USAGE
_count = 0;
_current_cpp_size = 0;
_trend_types.clear();
_trend_ages.clear();
_freeze_index++;
#endif
}
/**
@ -977,6 +1104,7 @@ ns_freeze() {
*/
void MemoryUsage::
ns_show_current_types() {
#ifdef DO_MEMORY_USAGE
nassertv(_track_memory_usage);
TypeHistogram hist;
@ -994,6 +1122,7 @@ ns_show_current_types() {
}
hist.show();
_recursion_protect = false;
#endif
}
/**
@ -1002,7 +1131,9 @@ ns_show_current_types() {
*/
void MemoryUsage::
ns_show_trend_types() {
#ifdef DO_MEMORY_USAGE
_trend_types.show();
#endif
}
/**
@ -1010,6 +1141,7 @@ ns_show_trend_types() {
*/
void MemoryUsage::
ns_show_current_ages() {
#ifdef DO_MEMORY_USAGE
nassertv(_track_memory_usage);
AgeHistogram hist;
@ -1026,6 +1158,7 @@ ns_show_current_ages() {
hist.show();
_recursion_protect = false;
#endif
}
/**
@ -1037,6 +1170,8 @@ ns_show_trend_ages() {
_trend_ages.show();
}
#ifdef DO_MEMORY_USAGE
/**
* If the size information has not yet been determined for this pointer,
* checks to see if it has possibly been recorded under the TypedObject
@ -1126,5 +1261,4 @@ refresh_info_set() {
_info_set_dirty = false;
}
#endif // DO_MEMORY_USAGE

View File

@ -15,9 +15,6 @@
#define MEMORYUSAGE_H
#include "pandabase.h"
#ifdef DO_MEMORY_USAGE
#include "typedObject.h"
#include "memoryInfo.h"
#include "memoryUsagePointerCounts.h"
@ -33,18 +30,22 @@ class MemoryUsagePointers;
* every such object currently allocated.
*
* When compiled with NDEBUG set, this entire class does nothing and compiles
* to nothing.
* to a stub.
*/
class EXPCL_PANDAEXPRESS MemoryUsage : public MemoryHook {
public:
INLINE static bool get_track_memory_usage();
ALWAYS_INLINE static bool get_track_memory_usage();
INLINE static void record_pointer(ReferenceCount *ptr);
INLINE static void record_pointer(void *ptr, TypeHandle type);
INLINE static void update_type(ReferenceCount *ptr, TypeHandle type);
INLINE static void update_type(ReferenceCount *ptr, TypedObject *typed_ptr);
INLINE static void update_type(void *ptr, TypeHandle type);
INLINE static void remove_pointer(ReferenceCount *ptr);
public:
protected:
// These are not marked public, but they can be accessed via the MemoryHook
// base class.
virtual void *heap_alloc_single(size_t size);
virtual void heap_free_single(void *ptr);
@ -88,6 +89,19 @@ PUBLISHED:
INLINE static void show_current_ages();
INLINE static void show_trend_ages();
PUBLISHED:
MAKE_PROPERTY(tracking, is_tracking);
MAKE_PROPERTY(counting, is_counting);
MAKE_PROPERTY(current_cpp_size, get_current_cpp_size);
MAKE_PROPERTY(total_cpp_size, get_total_cpp_size);
MAKE_PROPERTY(panda_heap_single_size, get_panda_heap_single_size);
MAKE_PROPERTY(panda_heap_array_size, get_panda_heap_array_size);
MAKE_PROPERTY(panda_heap_overhead, get_panda_heap_overhead);
MAKE_PROPERTY(panda_mmap_size, get_panda_mmap_size);
MAKE_PROPERTY(external_size, get_external_size);
MAKE_PROPERTY(total_size, get_total_size);
protected:
virtual void overflow_heap_size();
@ -98,8 +112,9 @@ private:
static void init_memory_usage();
void ns_record_pointer(ReferenceCount *ptr);
void ns_update_type(ReferenceCount *ptr, TypeHandle type);
void ns_update_type(ReferenceCount *ptr, TypedObject *typed_ptr);
void ns_record_pointer(void *ptr, TypeHandle type);
void ns_update_type(void *ptr, TypeHandle type);
void ns_update_type(void *ptr, TypedObject *typed_ptr);
void ns_remove_pointer(ReferenceCount *ptr);
void ns_record_void_pointer(void *ptr, size_t size);
@ -120,8 +135,10 @@ private:
void ns_show_current_ages();
void ns_show_trend_ages();
#ifdef DO_MEMORY_USAGE
void consolidate_void_ptr(MemoryInfo *info);
void refresh_info_set();
#endif
static MemoryUsage *_global_ptr;
@ -196,6 +213,4 @@ private:
#include "memoryUsage.I"
#endif // DO_MEMORY_USAGE
#endif

View File

@ -12,9 +12,6 @@
*/
#include "memoryUsagePointerCounts.h"
#ifdef DO_MEMORY_USAGE
#include "memoryInfo.h"
/**
@ -22,6 +19,7 @@
*/
void MemoryUsagePointerCounts::
add_info(MemoryInfo *info) {
#ifdef DO_MEMORY_USAGE
_count++;
if (info->is_size_known()) {
@ -29,6 +27,7 @@ add_info(MemoryInfo *info) {
} else {
_unknown_size_count++;
}
#endif
}
/**
@ -36,6 +35,7 @@ add_info(MemoryInfo *info) {
*/
void MemoryUsagePointerCounts::
output(ostream &out) const {
#ifdef DO_MEMORY_USAGE
out << _count << " pointers";
if (_unknown_size_count < _count) {
out << ", ";
@ -48,6 +48,7 @@ output(ostream &out) const {
out << " (" << _unknown_size_count << " of unknown size)";
}
}
#endif
}
/**
@ -56,6 +57,7 @@ output(ostream &out) const {
*/
void MemoryUsagePointerCounts::
output_bytes(ostream &out, size_t size) {
#ifdef DO_MEMORY_USAGE
if (size < 4 * 1024) {
out << size << " bytes";
@ -65,6 +67,5 @@ output_bytes(ostream &out, size_t size) {
} else {
out << size / (1024 * 1024) << " Mb";
}
#endif
}
#endif // DO_MEMORY_USAGE

View File

@ -16,8 +16,6 @@
#include "pandabase.h"
#ifdef DO_MEMORY_USAGE
class MemoryInfo;
/**
@ -55,6 +53,4 @@ INLINE ostream &operator << (ostream &out, const MemoryUsagePointerCounts &c);
#include "memoryUsagePointerCounts.I"
#endif // DO_MEMORY_USAGE
#endif

View File

@ -12,9 +12,6 @@
*/
#include "memoryUsagePointers.h"
#ifdef DO_MEMORY_USAGE
#include "config_express.h"
#include "referenceCount.h"
#include "typedReferenceCount.h"
@ -38,7 +35,11 @@ MemoryUsagePointers::
*/
size_t MemoryUsagePointers::
get_num_pointers() const {
#ifdef DO_MEMORY_USAGE
return _entries.size();
#else
return 0;
#endif
}
/**
@ -46,21 +47,26 @@ get_num_pointers() const {
*/
ReferenceCount *MemoryUsagePointers::
get_pointer(size_t n) const {
nassertr(n < get_num_pointers(), NULL);
#ifdef DO_MEMORY_USAGE
nassertr(n < get_num_pointers(), nullptr);
return _entries[n]._ref_ptr;
#else
return nullptr;
#endif
}
/**
* Returns the nth pointer of the set, typecast to a TypedObject if possible.
* If the pointer is not a TypedObject or if the cast cannot be made, returns
* NULL.
* nullptr.
*/
TypedObject *MemoryUsagePointers::
get_typed_pointer(size_t n) const {
nassertr(n < get_num_pointers(), NULL);
#ifdef DO_MEMORY_USAGE
nassertr(n < get_num_pointers(), nullptr);
TypedObject *typed_ptr = _entries[n]._typed_ptr;
if (typed_ptr != (TypedObject *)NULL) {
if (typed_ptr != nullptr) {
return typed_ptr;
}
@ -85,7 +91,8 @@ get_typed_pointer(size_t n) const {
type.is_derived_from(TypedReferenceCount::get_class_type())) {
return (TypedReferenceCount *)ref_ptr;
}
return NULL;
#endif
return nullptr;
}
/**
@ -93,8 +100,12 @@ get_typed_pointer(size_t n) const {
*/
TypeHandle MemoryUsagePointers::
get_type(size_t n) const {
#ifdef DO_MEMORY_USAGE
nassertr(n < get_num_pointers(), TypeHandle::none());
return _entries[n]._type;
#else
return TypeHandle::none();
#endif
}
/**
@ -102,8 +113,12 @@ get_type(size_t n) const {
*/
string MemoryUsagePointers::
get_type_name(size_t n) const {
#ifdef DO_MEMORY_USAGE
nassertr(n < get_num_pointers(), "");
return get_type(n).get_name();
#else
return "";
#endif
}
/**
@ -113,8 +128,12 @@ get_type_name(size_t n) const {
*/
double MemoryUsagePointers::
get_age(size_t n) const {
#ifdef DO_MEMORY_USAGE
nassertr(n < get_num_pointers(), 0.0);
return _entries[n]._age;
#else
return 0.0;
#endif
}
/**
@ -122,7 +141,9 @@ get_age(size_t n) const {
*/
void MemoryUsagePointers::
clear() {
#ifdef DO_MEMORY_USAGE
_entries.clear();
#endif
}
/**
@ -130,7 +151,9 @@ clear() {
*/
void MemoryUsagePointers::
output(ostream &out) const {
#ifdef DO_MEMORY_USAGE
out << _entries.size() << " pointers.";
#endif
}
/**
@ -139,13 +162,12 @@ output(ostream &out) const {
void MemoryUsagePointers::
add_entry(ReferenceCount *ref_ptr, TypedObject *typed_ptr,
TypeHandle type, double age) {
#ifdef DO_MEMORY_USAGE
// We can't safely add pointers with a zero reference count. They might be
// statically-allocated or something, and if we try to add them they'll try
// to destruct when the PointerTo later goes away.
if (ref_ptr->get_ref_count() != 0) {
_entries.push_back(Entry(ref_ptr, typed_ptr, type, age));
}
#endif
}
#endif // DO_MEMORY_USAGE

View File

@ -15,9 +15,6 @@
#define MEMORYUSAGEPOINTERS_H
#include "pandabase.h"
#ifdef DO_MEMORY_USAGE
#include "typedObject.h"
#include "pointerTo.h"
#include "referenceCount.h"
@ -53,7 +50,9 @@ PUBLISHED:
string get_type_name(size_t n) const;
double get_age(size_t n) const;
#ifdef DO_MEMORY_USAGE
EXTENSION(PyObject *get_python_pointer(size_t n) const);
#endif
void clear();
@ -94,6 +93,4 @@ INLINE ostream &operator << (ostream &out, const MemoryUsagePointers &mup) {
#include "memoryUsagePointers.I"
#endif // MEMORY_USAGE_POINTERS
#endif

View File

@ -136,6 +136,7 @@ PUBLISHED:
void ls(ostream &out = cout) const;
static INLINE string get_magic_number();
MAKE_PROPERTY(magic_number, get_magic_number);
void set_header_prefix(const string &header_prefix);
INLINE const string &get_header_prefix() const;

View File

@ -109,6 +109,44 @@ rend() const {
return _vector.rend();
}
/**
* Returns the iterator that marks the first element in the ordered vector.
*/
template<class Key, class Compare, class Vector>
INLINE TYPENAME ordered_vector<Key, Compare, Vector>::CONST_ITERATOR ordered_vector<Key, Compare, Vector>::
cbegin() const {
return _vector.begin();
}
/**
* Returns the iterator that marks the end of the ordered vector.
*/
template<class Key, class Compare, class Vector>
INLINE TYPENAME ordered_vector<Key, Compare, Vector>::CONST_ITERATOR ordered_vector<Key, Compare, Vector>::
cend() const {
return _vector.end();
}
/**
* Returns the iterator that marks the first element in the ordered vector,
* when viewed in reverse order.
*/
template<class Key, class Compare, class Vector>
INLINE TYPENAME ordered_vector<Key, Compare, Vector>::CONST_REVERSE_ITERATOR ordered_vector<Key, Compare, Vector>::
crbegin() const {
return _vector.rbegin();
}
/**
* Returns the iterator that marks the end of the ordered vector, when viewed
* in reverse order.
*/
template<class Key, class Compare, class Vector>
INLINE TYPENAME ordered_vector<Key, Compare, Vector>::CONST_REVERSE_ITERATOR ordered_vector<Key, Compare, Vector>::
crend() const {
return _vector.rend();
}
/**
* Returns the nth element.
*/
@ -127,6 +165,54 @@ operator [] (TYPENAME ordered_vector<Key, Compare, Vector>::SIZE_TYPE n) const {
return _vector[n];
}
/**
* Returns a reference to the first element.
*/
template<class Key, class Compare, class Vector>
INLINE TYPENAME ordered_vector<Key, Compare, Vector>::REFERENCE ordered_vector<Key, Compare, Vector>::
front() {
#ifdef _DEBUG
assert(!_vector.empty());
#endif
return _vector[0];
}
/**
* Returns a const reference to the first element.
*/
template<class Key, class Compare, class Vector>
INLINE TYPENAME ordered_vector<Key, Compare, Vector>::CONST_REFERENCE ordered_vector<Key, Compare, Vector>::
front() const {
#ifdef _DEBUG
assert(!_vector.empty());
#endif
return _vector[0];
}
/**
* Returns a reference to the first element.
*/
template<class Key, class Compare, class Vector>
INLINE TYPENAME ordered_vector<Key, Compare, Vector>::REFERENCE ordered_vector<Key, Compare, Vector>::
back() {
#ifdef _DEBUG
assert(!_vector.empty());
#endif
return _vector[_vector.size() - 1];
}
/**
* Returns a const reference to the last element.
*/
template<class Key, class Compare, class Vector>
INLINE TYPENAME ordered_vector<Key, Compare, Vector>::CONST_REFERENCE ordered_vector<Key, Compare, Vector>::
back() const {
#ifdef _DEBUG
assert(!_vector.empty());
#endif
return _vector[_vector.size() - 1];
}
/**
* Returns the number of elements in the ordered vector.
*/
@ -530,6 +616,18 @@ push_back(const value_type &key) {
_vector.push_back(key);
}
/**
* Adds the new element to the end of the vector without regard for proper
* sorting. This is a bad idea to do except to populate the vector the first
* time; be sure to call sort() after you have added all the elements.
*/
template<class Key, class Compare, class Vector>
INLINE void ordered_vector<Key, Compare, Vector>::
push_back(value_type &&key) {
TAU_PROFILE("ordered_vector::push_back()", " ", TAU_USER);
_vector.push_back(move(key));
}
/**
* Removes the last element at the end of the vector.
*/

View File

@ -147,10 +147,21 @@ public:
INLINE CONST_REVERSE_ITERATOR rbegin() const;
INLINE CONST_REVERSE_ITERATOR rend() const;
INLINE CONST_ITERATOR cbegin() const;
INLINE CONST_ITERATOR cend() const;
INLINE CONST_REVERSE_ITERATOR crbegin() const;
INLINE CONST_REVERSE_ITERATOR crend() const;
// Random access.
INLINE reference operator [] (SIZE_TYPE n);
INLINE const_reference operator [] (SIZE_TYPE n) const;
INLINE reference front();
INLINE const_reference front() const;
INLINE reference back();
INLINE const_reference back() const;
// Size information.
INLINE SIZE_TYPE size() const;
INLINE SIZE_TYPE max_size() const;
@ -201,6 +212,7 @@ public:
bool verify_list_nonunique() const;
INLINE void push_back(const VALUE_TYPE &key);
INLINE void push_back(VALUE_TYPE &&key);
INLINE void pop_back();
INLINE void resize(SIZE_TYPE n);
INLINE void resize(SIZE_TYPE n, const VALUE_TYPE &value);

View File

@ -70,7 +70,7 @@ class PointerTo : public PointerToBase<T> {
public:
typedef TYPENAME PointerToBase<T>::To To;
PUBLISHED:
ALWAYS_INLINE CONSTEXPR PointerTo() NOEXCEPT DEFAULT_CTOR;
ALWAYS_INLINE_CONSTEXPR PointerTo() NOEXCEPT DEFAULT_CTOR;
ALWAYS_INLINE PointerTo(To *ptr) NOEXCEPT;
INLINE PointerTo(const PointerTo<T> &copy);
@ -133,7 +133,7 @@ class ConstPointerTo : public PointerToBase<T> {
public:
typedef TYPENAME PointerToBase<T>::To To;
PUBLISHED:
ALWAYS_INLINE CONSTEXPR ConstPointerTo() NOEXCEPT DEFAULT_CTOR;
ALWAYS_INLINE_CONSTEXPR ConstPointerTo() NOEXCEPT DEFAULT_CTOR;
ALWAYS_INLINE ConstPointerTo(const To *ptr) NOEXCEPT;
INLINE ConstPointerTo(const PointerTo<T> &copy);
INLINE ConstPointerTo(const ConstPointerTo<T> &copy);

View File

@ -141,7 +141,6 @@ reassign(const PointerToBase<To> &copy) {
}
}
#ifdef DO_MEMORY_USAGE
/**
* Ensures that the MemoryUsage record for the pointer has the right type of
* object, if we know the type ourselves.
@ -149,6 +148,7 @@ reassign(const PointerToBase<To> &copy) {
template<class T>
INLINE void PointerToBase<T>::
update_type(To *ptr) {
#ifdef DO_MEMORY_USAGE
if (MemoryUsage::get_track_memory_usage()) {
TypeHandle type = get_type_handle(To);
if (type == TypeHandle::none()) {
@ -159,9 +159,8 @@ update_type(To *ptr) {
MemoryUsage::update_type(ptr, type);
}
}
}
#endif // DO_MEMORY_USAGE
}
/**
* A convenient way to set the PointerTo object to NULL. (Assignment to a NULL

View File

@ -31,7 +31,7 @@ public:
typedef T To;
protected:
ALWAYS_INLINE CONSTEXPR PointerToBase() NOEXCEPT DEFAULT_CTOR;
ALWAYS_INLINE_CONSTEXPR PointerToBase() NOEXCEPT DEFAULT_CTOR;
INLINE PointerToBase(To *ptr);
INLINE PointerToBase(const PointerToBase<T> &copy);
INLINE ~PointerToBase();
@ -44,9 +44,7 @@ protected:
INLINE void reassign(To *ptr);
INLINE void reassign(const PointerToBase<To> &copy);
#ifdef DO_MEMORY_USAGE
INLINE void update_type(To *ptr);
#endif // DO_MEMORY_USAGE
// No assignment or retrieval functions are declared in PointerToBase,
// because we will have to specialize on const vs. non-const later.

View File

@ -89,7 +89,6 @@ reassign(const ThreadSafePointerToBase<To> &copy) {
reassign((To *)copy._void_ptr);
}
#ifdef DO_MEMORY_USAGE
/**
* Ensures that the MemoryUsage record for the pointer has the right type of
* object, if we know the type ourselves.
@ -97,6 +96,7 @@ reassign(const ThreadSafePointerToBase<To> &copy) {
template<class T>
void ThreadSafePointerToBase<T>::
update_type(To *ptr) {
#ifdef DO_MEMORY_USAGE
TypeHandle type = get_type_handle(To);
if (type == TypeHandle::none()) {
do_init_type(To);
@ -105,9 +105,8 @@ update_type(To *ptr) {
if (type != TypeHandle::none()) {
MemoryUsage::update_type(ptr, type);
}
}
#endif // DO_MEMORY_USAGE
}
/**
* A convenient way to set the ThreadSafePointerTo object to NULL. (Assignment

View File

@ -40,9 +40,7 @@ protected:
INLINE void reassign(To *ptr);
INLINE void reassign(const ThreadSafePointerToBase<To> &copy);
#ifdef DO_MEMORY_USAGE
void update_type(To *ptr);
#endif // DO_MEMORY_USAGE
// No assignment or retrieval functions are declared in
// ThreadSafePointerToBase, because we will have to specialize on const vs.

View File

@ -150,7 +150,16 @@ copy_file(VirtualFile *new_file) {
// Different mount point, or the mount doesn't support copying. Do it by
// hand.
ostream *out = new_file->open_write_file(false, true);
if (out == nullptr) {
return false;
}
istream *in = open_read_file(false);
if (in == nullptr) {
new_file->close_write_file(out);
new_file->delete_file();
return false;
}
static const size_t buffer_size = 4096;
char buffer[buffer_size];

View File

@ -1226,6 +1226,24 @@ do_get_file(const Filename &filename, int open_flags) const {
}
}
#if defined(_WIN32) && !defined(NDEBUG)
if (!found_file) {
// The file could not be found. Perhaps this is because the user passed
// in a Windows-style path where a Unix-style path was expected?
if (filename.length() > 2 && isalpha(filename[0]) && filename[1] == ':' &&
(filename[2] == '\\' || filename[2] == '/')) {
Filename corrected_fn = Filename::from_os_specific(filename);
if (corrected_fn.exists()) {
express_cat.warning()
<< "Filename uses Windows-style path: " << filename << "\n";
express_cat.warning()
<< " expected Unix-style path: " << corrected_fn << "\n";
}
}
}
#endif
return found_file;
}

View File

@ -10,37 +10,3 @@
* @author rdb
* @date 2014-06-27
*/
#ifndef OPENGLES_1
/**
* Returns true if the shader is "valid", ie, if the compilation was
* successful. The compilation could fail if there is a syntax error in the
* shader, or if the current video card isn't shader-capable, or if no shader
* languages are compiled into panda.
*/
INLINE bool CLP(CgShaderContext)::
valid() {
if (_shader->get_error_flag()) return false;
if (_shader->get_language() != Shader::SL_Cg) return false;
return (_cg_program != 0);
}
/**
* Returns true if the shader may need to access standard vertex attributes as
* passed by glVertexPointer and the like.
*/
INLINE bool CLP(CgShaderContext)::
uses_standard_vertex_arrays() {
return false;
}
/**
* Always true, for now.
*/
INLINE bool CLP(CgShaderContext)::
uses_custom_vertex_arrays() {
return true;
}
#endif // OPENGLES_1

View File

@ -357,6 +357,20 @@ release_resources() {
_glgsg->report_my_gl_errors();
}
/**
* Returns true if the shader is "valid", ie, if the compilation was
* successful. The compilation could fail if there is a syntax error in the
* shader, or if the current video card isn't shader-capable, or if no shader
* languages are compiled into panda.
*/
bool CLP(CgShaderContext)::
valid() {
if (_shader == nullptr || _shader->get_error_flag()) {
return false;
}
return (_cg_program != 0);
}
/**
* This function is to be called to enable a new shader. It also initializes
* all of the shader's input parameters.

View File

@ -33,25 +33,25 @@ public:
~CLP(CgShaderContext)();
ALLOC_DELETED_CHAIN(CLP(CgShaderContext));
INLINE bool valid(void);
void bind() OVERRIDE;
void unbind() OVERRIDE;
bool valid(void) override;
void bind() override;
void unbind() override;
void set_state_and_transform(const RenderState *state,
const TransformState *modelview_transform,
const TransformState *camera_transform,
const TransformState *projection_transform) OVERRIDE;
const TransformState *projection_transform) override;
void issue_parameters(int altered) OVERRIDE;
void issue_parameters(int altered) override;
void update_transform_table(const TransformTable *table);
void update_slider_table(const SliderTable *table);
void disable_shader_vertex_arrays() OVERRIDE;
bool update_shader_vertex_arrays(ShaderContext *prev, bool force) OVERRIDE;
void disable_shader_texture_bindings() OVERRIDE;
void update_shader_texture_bindings(ShaderContext *prev) OVERRIDE;
void disable_shader_vertex_arrays() override;
bool update_shader_vertex_arrays(ShaderContext *prev, bool force) override;
void disable_shader_texture_bindings() override;
void update_shader_texture_bindings(ShaderContext *prev) override;
INLINE bool uses_standard_vertex_arrays(void);
INLINE bool uses_custom_vertex_arrays(void);
bool uses_standard_vertex_arrays(void) override { return false; }
bool uses_custom_vertex_arrays(void) override { return true; }
// Special values for location to indicate conventional attrib slots.
enum ConventionalAttrib {
@ -95,10 +95,10 @@ public:
register_type(_type_handle, CLASSPREFIX_QUOTED "CgShaderContext",
ShaderContext::get_class_type());
}
virtual TypeHandle get_type() const OVERRIDE {
virtual TypeHandle get_type() const override {
return get_class_type();
}
virtual TypeHandle force_init_type() OVERRIDE {init_type(); return get_class_type();}
virtual TypeHandle force_init_type() override {init_type(); return get_class_type();}
private:
static TypeHandle _type_handle;

View File

@ -2135,7 +2135,7 @@ reset() {
_glGenerateMipmap = (PFNGLGENERATEMIPMAPPROC)
get_extension_func("glGenerateMipmap");
_glRenderbufferStorageMultisample = (PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC)
get_extension_func("glRenderbufferStorageMultisampleEXT");
get_extension_func("glRenderbufferStorageMultisample");
_glBlitFramebuffer = (PFNGLBLITFRAMEBUFFERPROC)
get_extension_func("glBlitFramebuffer");
@ -3934,7 +3934,6 @@ end_frame(Thread *current_thread) {
*/
bool CLP(GraphicsStateGuardian)::
begin_draw_primitives(const GeomPipelineReader *geom_reader,
const GeomMunger *munger,
const GeomVertexDataPipelineReader *data_reader,
bool force) {
#ifndef NDEBUG
@ -3953,7 +3952,7 @@ begin_draw_primitives(const GeomPipelineReader *geom_reader,
}
#endif
if (!GraphicsStateGuardian::begin_draw_primitives(geom_reader, munger, data_reader, force)) {
if (!GraphicsStateGuardian::begin_draw_primitives(geom_reader, data_reader, force)) {
return false;
}
nassertr(_data_reader != (GeomVertexDataPipelineReader *)NULL, false);
@ -4018,10 +4017,10 @@ begin_draw_primitives(const GeomPipelineReader *geom_reader,
GeomContext *gc = geom_reader->prepare_now(get_prepared_objects(), this);
nassertr(gc != (GeomContext *)NULL, false);
CLP(GeomContext) *ggc = DCAST(CLP(GeomContext), gc);
const CLP(GeomMunger) *gmunger = DCAST(CLP(GeomMunger), _munger);
//const CLP(GeomMunger) *gmunger = DCAST(CLP(GeomMunger), _munger);
UpdateSeq modified = max(geom_reader->get_modified(), _data_reader->get_modified());
if (ggc->get_display_list(_geom_display_list, gmunger, modified)) {
if (ggc->get_display_list(_geom_display_list, nullptr, modified)) {
// If it hasn't been modified, just play the display list again.
if (GLCAT.is_spam()) {
GLCAT.spam()

View File

@ -284,7 +284,6 @@ public:
virtual void end_frame(Thread *current_thread);
virtual bool begin_draw_primitives(const GeomPipelineReader *geom_reader,
const GeomMunger *munger,
const GeomVertexDataPipelineReader *data_reader,
bool force);
virtual bool draw_triangles(const GeomPrimitivePipelineReader *reader,

View File

@ -10,38 +10,3 @@
* @author jyelon
* @date 2005-09-01
*/
/**
* Returns true if the shader is "valid", ie, if the compilation was
* successful. The compilation could fail if there is a syntax error in the
* shader, or if the current video card isn't shader-capable, or if no shader
* languages are compiled into panda.
*/
INLINE bool CLP(ShaderContext)::
valid() {
if (_shader->get_error_flag()) return false;
if (_shader->get_language() != Shader::SL_GLSL) {
return false;
}
if (_glsl_program != 0) {
return true;
}
return false;
}
/**
* Returns true if the shader may need to access standard vertex attributes as
* passed by glVertexPointer and the like.
*/
INLINE bool CLP(ShaderContext)::
uses_standard_vertex_arrays() {
return _uses_standard_vertex_arrays;
}
/**
* Always true, for now.
*/
INLINE bool CLP(ShaderContext)::
uses_custom_vertex_arrays() {
return true;
}

View File

@ -1431,7 +1431,7 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) {
bind._arg[0] = NULL;
bind._dep[0] = Shader::SSD_general | Shader::SSD_transform;
bind._part[1] = Shader::SMO_mat_constant_x_attrib;
bind._arg[1] = InternalName::make("shadowViewMatrix");
bind._arg[1] = iname->get_parent()->append("shadowViewMatrix");
bind._dep[1] = Shader::SSD_general | Shader::SSD_shaderinputs | Shader::SSD_frame | Shader::SSD_view_transform;
} else {
bind._part[0] = Shader::SMO_mat_constant_x_attrib;
@ -1821,6 +1821,20 @@ release_resources() {
_glgsg->report_my_gl_errors();
}
/**
* Returns true if the shader is "valid", ie, if the compilation was
* successful. The compilation could fail if there is a syntax error in the
* shader, or if the current video card isn't shader-capable, or if no shader
* languages are compiled into panda.
*/
bool CLP(ShaderContext)::
valid() {
if (_shader->get_error_flag()) {
return false;
}
return (_glsl_program != 0);
}
/**
* This function is to be called to enable a new shader. It also initializes
* all of the shader's input parameters.
@ -2177,7 +2191,7 @@ update_slider_table(const SliderTable *table) {
*/
void CLP(ShaderContext)::
disable_shader_vertex_arrays() {
if (!valid()) {
if (_glsl_program == 0) {
return;
}
@ -2200,7 +2214,7 @@ disable_shader_vertex_arrays() {
*/
bool CLP(ShaderContext)::
update_shader_vertex_arrays(ShaderContext *prev, bool force) {
if (!valid()) {
if (_glsl_program == 0) {
return true;
}
@ -2373,7 +2387,7 @@ update_shader_vertex_arrays(ShaderContext *prev, bool force) {
*/
void CLP(ShaderContext)::
disable_shader_texture_bindings() {
if (!valid()) {
if (_glsl_program == 0) {
return;
}
@ -2473,7 +2487,7 @@ void CLP(ShaderContext)::
update_shader_texture_bindings(ShaderContext *prev) {
// if (prev) { prev->disable_shader_texture_bindings(); }
if (!valid()) {
if (_glsl_program == 0) {
return;
}

View File

@ -40,26 +40,30 @@ public:
void reflect_uniform(int i, char *name_buffer, GLsizei name_buflen);
bool get_sampler_texture_type(int &out, GLenum param_type);
INLINE bool valid(void);
void bind() OVERRIDE;
void unbind() OVERRIDE;
bool valid(void) override;
void bind() override;
void unbind() override;
void set_state_and_transform(const RenderState *state,
const TransformState *modelview_transform,
const TransformState *camera_transform,
const TransformState *projection_transform) OVERRIDE;
const TransformState *projection_transform) override;
void issue_parameters(int altered) OVERRIDE;
void issue_parameters(int altered) override;
void update_transform_table(const TransformTable *table);
void update_slider_table(const SliderTable *table);
void disable_shader_vertex_arrays() OVERRIDE;
bool update_shader_vertex_arrays(ShaderContext *prev, bool force) OVERRIDE;
void disable_shader_texture_bindings() OVERRIDE;
void update_shader_texture_bindings(ShaderContext *prev) OVERRIDE;
void update_shader_buffer_bindings(ShaderContext *prev) OVERRIDE;
void disable_shader_vertex_arrays() override;
bool update_shader_vertex_arrays(ShaderContext *prev, bool force) override;
void disable_shader_texture_bindings() override;
void update_shader_texture_bindings(ShaderContext *prev) override;
void update_shader_buffer_bindings(ShaderContext *prev) override;
INLINE bool uses_standard_vertex_arrays(void);
INLINE bool uses_custom_vertex_arrays(void);
bool uses_standard_vertex_arrays(void) override {
return _uses_standard_vertex_arrays;
}
bool uses_custom_vertex_arrays(void) override {
return true;
}
private:
bool _validated;
@ -128,10 +132,10 @@ public:
register_type(_type_handle, CLASSPREFIX_QUOTED "ShaderContext",
ShaderContext::get_class_type());
}
virtual TypeHandle get_type() const OVERRIDE {
virtual TypeHandle get_type() const override {
return get_class_type();
}
virtual TypeHandle force_init_type() OVERRIDE {init_type(); return get_class_type();}
virtual TypeHandle force_init_type() override {init_type(); return get_class_type();}
private:
static TypeHandle _type_handle;

View File

@ -683,6 +683,7 @@ unify_in_place(int max_indices, bool preserve_order) {
int num_vertices = copy_primitives * total_vertices_per_primitive;
nassertv(num_vertices > 0);
{
smaller->set_index_type(reader.get_index_type());
GeomVertexArrayDataHandle writer(smaller->modify_vertices(), current_thread);
writer.unclean_set_num_rows(num_vertices);
memcpy(writer.get_write_pointer(), ptr, stride * (size_t)(num_vertices - num_unused_vertices_per_primitive));
@ -1211,14 +1212,13 @@ prepare_now(PreparedGraphicsObjects *prepared_objects,
* is passed true, it will wait for the data to become resident if necessary.
*/
bool Geom::
draw(GraphicsStateGuardianBase *gsg, const GeomMunger *munger,
const GeomVertexData *vertex_data, bool force,
Thread *current_thread) const {
draw(GraphicsStateGuardianBase *gsg, const GeomVertexData *vertex_data,
bool force, Thread *current_thread) const {
GeomPipelineReader geom_reader(this, current_thread);
GeomVertexDataPipelineReader data_reader(vertex_data, current_thread);
data_reader.check_array_readers();
return geom_reader.draw(gsg, munger, &data_reader, force);
return geom_reader.draw(gsg, &data_reader, force);
}
/**
@ -1749,10 +1749,10 @@ check_valid(const GeomVertexDataPipelineReader *data_reader) const {
* The implementation of Geom::draw().
*/
bool GeomPipelineReader::
draw(GraphicsStateGuardianBase *gsg, const GeomMunger *munger,
draw(GraphicsStateGuardianBase *gsg,
const GeomVertexDataPipelineReader *data_reader, bool force) const {
PStatTimer timer(Geom::_draw_primitive_setup_pcollector);
bool all_ok = gsg->begin_draw_primitives(this, munger, data_reader, force);
bool all_ok = gsg->begin_draw_primitives(this, data_reader, force);
if (all_ok) {
Geom::Primitives::const_iterator pi;
for (pi = _cdata->_primitives.begin();

View File

@ -153,7 +153,6 @@ PUBLISHED:
public:
bool draw(GraphicsStateGuardianBase *gsg,
const GeomMunger *munger,
const GeomVertexData *vertex_data,
bool force, Thread *current_thread) const;
@ -429,7 +428,7 @@ public:
INLINE GeomContext *prepare_now(PreparedGraphicsObjects *prepared_objects,
GraphicsStateGuardianBase *gsg) const;
bool draw(GraphicsStateGuardianBase *gsg, const GeomMunger *munger,
bool draw(GraphicsStateGuardianBase *gsg,
const GeomVertexDataPipelineReader *data_reader,
bool force) const;

View File

@ -178,11 +178,9 @@ private:
static TypeHandle _texcoord_type_handle;
};
#ifdef DO_MEMORY_USAGE
// We can safely redefine this as a no-op.
template<>
INLINE void PointerToBase<InternalName>::update_type(To *ptr) {}
#endif
INLINE ostream &operator << (ostream &out, const InternalName &tcn);

View File

@ -327,3 +327,11 @@ INLINE void Material::
set_attrib_lock() {
_flags |= F_attrib_lock;
}
/**
*
*/
INLINE int Material::
get_flags() const {
return _flags;
}

View File

@ -128,6 +128,8 @@ PUBLISHED:
MAKE_PROPERTY(twoside, get_twoside, set_twoside);
public:
INLINE int get_flags() const;
enum Flags {
F_ambient = 0x001,
F_diffuse = 0x002,
@ -157,8 +159,6 @@ private:
int _flags;
friend class MaterialAttrib;
public:
static void register_with_read_factory();
virtual void write_datagram(BamWriter *manager, Datagram &me);

View File

@ -450,9 +450,11 @@ cp_dependency(ShaderMatInput inp) {
}
}
if ((inp == SMO_light_ambient) ||
(inp == SMO_light_source_i_attrib)) {
dep |= SSD_light;
if (inp == SMO_light_source_i_attrib) {
(inp == SMO_light_source_i_attrib) ||
(inp == SMO_light_source_i_packed)) {
dep |= SSD_light | SSD_frame;
if (inp == SMO_light_source_i_attrib ||
inp == SMO_light_source_i_packed) {
dep |= SSD_view_transform;
}
}
@ -465,7 +467,7 @@ cp_dependency(ShaderMatInput inp) {
(inp == SMO_apiview_clipplane_i)) {
dep |= SSD_clip_planes;
}
if (inp == SMO_texmat_i || inp == SMO_inv_texmat_i) {
if (inp == SMO_texmat_i || inp == SMO_inv_texmat_i || inp == SMO_texscale_i) {
dep |= SSD_tex_matrix;
}
if ((inp == SMO_window_size) ||
@ -483,7 +485,7 @@ cp_dependency(ShaderMatInput inp) {
(inp == SMO_apiclip_to_apiview)) {
dep |= SSD_projection;
}
if (inp == SMO_tex_is_alpha_i) {
if (inp == SMO_tex_is_alpha_i || inp == SMO_texcolor_i) {
dep |= SSD_texture | SSD_frame;
}
@ -734,6 +736,29 @@ compile_parameter(ShaderArgInfo &p, int *arg_dim) {
return true;
}
if (pieces[0] == "mat" && pieces[1] == "shadow") {
if ((!cp_errchk_parameter_words(p,3))||
(!cp_errchk_parameter_in(p)) ||
(!cp_errchk_parameter_uniform(p))||
(!cp_errchk_parameter_float(p,16,16))) {
return false;
}
ShaderMatSpec bind;
bind._id = p._id;
bind._piece = SMP_whole;
bind._func = SMF_compose;
bind._part[1] = SMO_light_source_i_attrib;
bind._arg[1] = InternalName::make("shadowViewMatrix");
bind._part[0] = SMO_view_to_apiview;
bind._arg[0] = NULL;
bind._index = atoi(pieces[2].c_str());
cp_optimize_mat_spec(bind);
_mat_spec.push_back(bind);
_mat_deps |= bind._dep[0] | bind._dep[1];
return true;
}
// Implement some macros. Macros work by altering the contents of the
// 'pieces' array, and then falling through.
@ -833,7 +858,13 @@ compile_parameter(ShaderArgInfo &p, int *arg_dim) {
ShaderMatSpec bind;
bind._id = p._id;
bind._piece = SMP_whole;
bind._func = SMF_compose;
bind._part[1] = SMO_light_source_i_attrib;
bind._arg[1] = InternalName::make("shadowViewMatrix");
bind._part[0] = SMO_view_to_apiview;
bind._arg[0] = NULL;
bind._index = atoi(pieces[2].c_str());
int next = 1;
pieces.push_back("");
@ -958,6 +989,30 @@ compile_parameter(ShaderArgInfo &p, int *arg_dim) {
bind._arg[0] = NULL;
bind._part[1] = SMO_identity;
bind._arg[1] = NULL;
} else if (pieces[1].compare(0, 5, "light") == 0) {
if (!cp_errchk_parameter_float(p,16,16)) {
return false;
}
bind._id = p._id;
bind._piece = SMP_transpose;
bind._func = SMF_first;
bind._part[0] = SMO_light_source_i_packed;
bind._arg[0] = NULL;
bind._part[1] = SMO_identity;
bind._arg[1] = NULL;
bind._index = atoi(pieces[1].c_str() + 5);
} else if (pieces[1].compare(0, 5, "lspec") == 0) {
if (!cp_errchk_parameter_float(p,3,4)) {
return false;
}
bind._id = p._id;
bind._piece = SMP_row3;
bind._func = SMF_first;
bind._part[0] = SMO_light_source_i_attrib;
bind._arg[0] = InternalName::make("specular");
bind._part[1] = SMO_identity;
bind._arg[1] = NULL;
bind._index = atoi(pieces[1].c_str() + 5);
} else {
cp_report_error(p,"Unknown attr parameter.");
return false;
@ -1094,6 +1149,52 @@ compile_parameter(ShaderArgInfo &p, int *arg_dim) {
return true;
}
if (pieces[0] == "texscale") {
if ((!cp_errchk_parameter_words(p,2))||
(!cp_errchk_parameter_in(p)) ||
(!cp_errchk_parameter_uniform(p))||
(!cp_errchk_parameter_float(p,3,4))) {
return false;
}
ShaderMatSpec bind;
bind._id = p._id;
bind._piece = SMP_row3;
bind._func = SMF_first;
bind._part[0] = SMO_texscale_i;
bind._arg[0] = NULL;
bind._part[1] = SMO_identity;
bind._arg[1] = NULL;
bind._index = atoi(pieces[1].c_str());
cp_optimize_mat_spec(bind);
_mat_spec.push_back(bind);
_mat_deps |= bind._dep[0] | bind._dep[1];
return true;
}
if (pieces[0] == "texcolor") {
if ((!cp_errchk_parameter_words(p,2))||
(!cp_errchk_parameter_in(p)) ||
(!cp_errchk_parameter_uniform(p))||
(!cp_errchk_parameter_float(p,3,4))) {
return false;
}
ShaderMatSpec bind;
bind._id = p._id;
bind._piece = SMP_row3;
bind._func = SMF_first;
bind._part[0] = SMO_texcolor_i;
bind._arg[0] = NULL;
bind._part[1] = SMO_identity;
bind._arg[1] = NULL;
bind._index = atoi(pieces[1].c_str());
cp_optimize_mat_spec(bind);
_mat_spec.push_back(bind);
_mat_deps |= bind._dep[0] | bind._dep[1];
return true;
}
if (pieces[0] == "plane") {
if ((!cp_errchk_parameter_words(p,2))||
(!cp_errchk_parameter_in(p)) ||
@ -1233,9 +1334,9 @@ compile_parameter(ShaderArgInfo &p, int *arg_dim) {
}
ShaderTexSpec bind;
bind._id = p._id;
bind._name = InternalName::make(pieces[1])->append("shadowMap");
bind._stage = -1;
bind._part = STO_named_input;
bind._name = nullptr;
bind._stage = atoi(pieces[1].c_str());
bind._part = STO_light_i_shadow_map;
switch (p._type) {
case SAT_sampler2d: bind._desired_type = Texture::TT_2d_texture; break;
case SAT_sampler_cube: bind._desired_type = Texture::TT_cube_map; break;

View File

@ -202,6 +202,17 @@ public:
// Hack for text rendering. Don't use in user shaders.
SMO_tex_is_alpha_i,
SMO_transform_i,
SMO_slider_i,
SMO_light_source_i_packed,
// Texture scale component of texture matrix.
SMO_texscale_i,
// Color of an M_blend texture stage.
SMO_texcolor_i,
SMO_INVALID
};

View File

@ -201,6 +201,8 @@ PUBLISHED:
MAKE_PROPERTY(tex_view_offset, get_tex_view_offset, set_tex_view_offset);
MAKE_PROPERTY(default, get_default);
public:
INLINE static UpdateSeq get_sort_seq();

View File

@ -43,6 +43,7 @@ PUBLISHED:
INLINE static void set_mode(Mode mode);
INLINE static Mode get_mode();
MAKE_PROPERTY(mode, get_mode, set_mode);
INLINE static int garbage_collect();
INLINE static void list_contents(ostream &out);

View File

@ -64,6 +64,7 @@ PUBLISHED:
INLINE static SimpleLru *get_global_lru(RamClass rclass);
INLINE static SimpleLru *get_pending_lru();
INLINE static VertexDataSaveFile *get_save_file();
MAKE_PROPERTY(save_file, get_save_file);
INLINE bool save_to_disk();

View File

@ -198,7 +198,6 @@ public:
// friends of this class.
virtual bool begin_draw_primitives(const GeomPipelineReader *geom_reader,
const GeomMunger *munger,
const GeomVertexDataPipelineReader *data_reader,
bool force)=0;
virtual bool draw_triangles(const GeomPrimitivePipelineReader *reader, bool force)=0;

View File

@ -83,11 +83,9 @@ private:
static TypeHandle _type_handle;
};
#ifdef DO_MEMORY_USAGE
// We can safely redefine this as a no-op.
template<>
INLINE void PointerToBase<GeometricBoundingVolume>::update_type(To *ptr) {}
#endif
#include "geometricBoundingVolume.I"

View File

@ -136,6 +136,23 @@ PUBLISHED:
void reset_bound(const NodePath &rel_to);
PUBLISHED:
MAKE_PROPERTY(curve, get_curve, set_curve);
MAKE_PROPERTY(render_mode, get_render_mode, set_render_mode);
MAKE_PROPERTY(uv_mode, get_uv_mode, set_uv_mode);
MAKE_PROPERTY(uv_direction, get_uv_direction, set_uv_direction);
MAKE_PROPERTY(uv_scale, get_uv_scale, set_uv_scale);
MAKE_PROPERTY(normal_mode, get_normal_mode, set_normal_mode);
MAKE_PROPERTY(tube_up, get_tube_up, set_tube_up);
MAKE_PROPERTY(use_vertex_color, get_use_vertex_color, set_use_vertex_color);
MAKE_PROPERTY(vertex_color_dimension, get_vertex_color_dimension);
MAKE_PROPERTY(num_subdiv, get_num_subdiv, set_num_subdiv);
MAKE_PROPERTY(num_slices, get_num_slices, set_num_slices);
MAKE_PROPERTY(use_vertex_thickness, get_use_vertex_thickness, set_use_vertex_thickness);
MAKE_PROPERTY(vertex_thickness_dimension, get_vertex_thickness_dimension);
MAKE_PROPERTY(thickness, get_thickness, set_thickness);
MAKE_PROPERTY2(matrix, has_matrix, get_matrix, set_matrix, clear_matrix);
protected:
virtual void compute_internal_bounds(CPT(BoundingVolume) &internal_bounds,
int &internal_vertices,

View File

@ -94,22 +94,6 @@ get_hash_impl() const {
return hash;
}
/**
*
*/
CPT(RenderAttrib) AlphaTestAttrib::
get_auto_shader_attrib_impl(const RenderState *state) const {
// This is only important if the shader subsumes the alpha test, which only
// happens if there is an AuxBitplaneAttrib with ABO_glow.
const AuxBitplaneAttrib *aux;
if (!state->get_attrib(aux) ||
(aux->get_outputs() & AuxBitplaneAttrib::ABO_glow) == 0) {
return nullptr;
} else {
return this;
}
}
/**
* Tells the BamReader how to create objects of type AlphaTestAttrib.
*/

View File

@ -46,7 +46,6 @@ public:
protected:
virtual int compare_to_impl(const RenderAttrib *other) const;
virtual size_t get_hash_impl() const;
virtual CPT(RenderAttrib) get_auto_shader_attrib_impl(const RenderState *state) const;
private:
PandaCompareFunc _mode;
@ -59,6 +58,7 @@ PUBLISHED:
virtual int get_slot() const {
return get_class_slot();
}
MAKE_PROPERTY(class_slot, get_class_slot);
public:
static void register_with_read_factory();

View File

@ -75,6 +75,7 @@ PUBLISHED:
virtual int get_slot() const {
return get_class_slot();
}
MAKE_PROPERTY(class_slot, get_class_slot);
public:
static void register_with_read_factory();

View File

@ -65,6 +65,7 @@ PUBLISHED:
virtual int get_slot() const {
return get_class_slot();
}
MAKE_PROPERTY(class_slot, get_class_slot);
public:
static void register_with_read_factory();

View File

@ -97,14 +97,6 @@ get_hash_impl() const {
return hash;
}
/**
*
*/
CPT(RenderAttrib) AuxBitplaneAttrib::
get_auto_shader_attrib_impl(const RenderState *state) const {
return this;
}
/**
* Tells the BamReader how to create objects of type AuxBitplaneAttrib.
*/

Some files were not shown because too many files have changed in this diff Show More