Merge branch 'master' into deploy-ng
This commit is contained in:
commit
ebe2588a50
|
|
@ -10,7 +10,7 @@ __all__ = ['indent',
|
|||
'bound', 'clamp', 'lerp', 'average', 'addListsByValue',
|
||||
'boolEqual', 'lineupPos', 'formatElapsedSeconds', 'solveQuadratic',
|
||||
'findPythonModule', 'mostDerivedLast',
|
||||
'weightedChoice', 'randFloat', 'normalDistrib',
|
||||
'clampScalar', 'weightedChoice', 'randFloat', 'normalDistrib',
|
||||
'weightedRand', 'randUint31', 'randInt32',
|
||||
'SerialNumGen', 'serialNum', 'uniqueName', 'Enum', 'Singleton',
|
||||
'SingletonError', 'printListEnum', 'safeRepr',
|
||||
|
|
@ -178,27 +178,6 @@ class Queue:
|
|||
def __len__(self):
|
||||
return len(self.__list)
|
||||
|
||||
if __debug__ and __name__ == '__main__':
|
||||
q = Queue()
|
||||
assert q.isEmpty()
|
||||
q.clear()
|
||||
assert q.isEmpty()
|
||||
q.push(10)
|
||||
assert not q.isEmpty()
|
||||
q.push(20)
|
||||
assert not q.isEmpty()
|
||||
assert len(q) == 2
|
||||
assert q.front() == 10
|
||||
assert q.back() == 20
|
||||
assert q.top() == 10
|
||||
assert q.top() == 10
|
||||
assert q.pop() == 10
|
||||
assert len(q) == 1
|
||||
assert not q.isEmpty()
|
||||
assert q.pop() == 20
|
||||
assert len(q) == 0
|
||||
assert q.isEmpty()
|
||||
|
||||
|
||||
def indent(stream, numIndents, str):
|
||||
"""
|
||||
|
|
@ -1130,6 +1109,23 @@ def findPythonModule(module):
|
|||
|
||||
return None
|
||||
|
||||
def clampScalar(value, a, b):
|
||||
# calling this ought to be faster than calling both min and max
|
||||
if a < b:
|
||||
if value < a:
|
||||
return a
|
||||
elif value > b:
|
||||
return b
|
||||
else:
|
||||
return value
|
||||
else:
|
||||
if value < b:
|
||||
return b
|
||||
elif value > a:
|
||||
return a
|
||||
else:
|
||||
return value
|
||||
|
||||
def weightedChoice(choiceList, rng=random.random, sum=None):
|
||||
"""given a list of (weight, item) pairs, chooses an item based on the
|
||||
weights. rng must return 0..1. if you happen to have the sum of the
|
||||
|
|
@ -2313,36 +2309,6 @@ def flywheel(*args, **kArgs):
|
|||
pass
|
||||
return flywheel
|
||||
|
||||
if __debug__ and __name__ == '__main__':
|
||||
f = flywheel(['a','b','c','d'], countList=[11,20,3,4])
|
||||
obj2count = {}
|
||||
for obj in f:
|
||||
obj2count.setdefault(obj, 0)
|
||||
obj2count[obj] += 1
|
||||
assert obj2count['a'] == 11
|
||||
assert obj2count['b'] == 20
|
||||
assert obj2count['c'] == 3
|
||||
assert obj2count['d'] == 4
|
||||
|
||||
f = flywheel([1,2,3,4], countFunc=lambda x: x*2)
|
||||
obj2count = {}
|
||||
for obj in f:
|
||||
obj2count.setdefault(obj, 0)
|
||||
obj2count[obj] += 1
|
||||
assert obj2count[1] == 2
|
||||
assert obj2count[2] == 4
|
||||
assert obj2count[3] == 6
|
||||
assert obj2count[4] == 8
|
||||
|
||||
f = flywheel([1,2,3,4], countFunc=lambda x: x, scale = 3)
|
||||
obj2count = {}
|
||||
for obj in f:
|
||||
obj2count.setdefault(obj, 0)
|
||||
obj2count[obj] += 1
|
||||
assert obj2count[1] == 1 * 3
|
||||
assert obj2count[2] == 2 * 3
|
||||
assert obj2count[3] == 3 * 3
|
||||
assert obj2count[4] == 4 * 3
|
||||
|
||||
if __debug__:
|
||||
def quickProfile(name="unnamed"):
|
||||
|
|
@ -2687,11 +2653,36 @@ def unescapeHtmlString(s):
|
|||
result += char
|
||||
return result
|
||||
|
||||
if __debug__ and __name__ == '__main__':
|
||||
assert unescapeHtmlString('asdf') == 'asdf'
|
||||
assert unescapeHtmlString('as+df') == 'as df'
|
||||
assert unescapeHtmlString('as%32df') == 'as2df'
|
||||
assert unescapeHtmlString('asdf%32') == 'asdf2'
|
||||
class PriorityCallbacks:
|
||||
""" manage a set of prioritized callbacks, and allow them to be invoked in order of priority """
|
||||
def __init__(self):
|
||||
self._callbacks = []
|
||||
|
||||
def clear(self):
|
||||
del self._callbacks[:]
|
||||
|
||||
def add(self, callback, priority=None):
|
||||
if priority is None:
|
||||
priority = 0
|
||||
callbacks = self._callbacks
|
||||
lo = 0
|
||||
hi = len(callbacks)
|
||||
while lo < hi:
|
||||
mid = (lo + hi) // 2
|
||||
if priority < callbacks[mid][0]:
|
||||
hi = mid
|
||||
else:
|
||||
lo = mid + 1
|
||||
item = (priority, callback)
|
||||
callbacks.insert(lo, item)
|
||||
return item
|
||||
|
||||
def remove(self, item):
|
||||
self._callbacks.remove(item)
|
||||
|
||||
def __call__(self):
|
||||
for priority, callback in self._callbacks:
|
||||
callback()
|
||||
|
||||
builtins.Functor = Functor
|
||||
builtins.Stack = Stack
|
||||
|
|
|
|||
|
|
@ -615,6 +615,7 @@ if (COMPILER == "MSVC"):
|
|||
PkgDisable("EGL")
|
||||
PkgDisable("CARBON")
|
||||
PkgDisable("COCOA")
|
||||
DefSymbol("FLEX", "YY_NO_UNISTD_H")
|
||||
if (PkgSkip("PYTHON")==0):
|
||||
IncDirectory("ALWAYS", SDK["PYTHON"] + "/include")
|
||||
LibDirectory("ALWAYS", SDK["PYTHON"] + "/libs")
|
||||
|
|
@ -890,7 +891,7 @@ if (COMPILER=="GCC"):
|
|||
SmartPkgEnable("EIGEN", "eigen3", (), ("Eigen/Dense",), target_pkg = 'ALWAYS')
|
||||
SmartPkgEnable("ARTOOLKIT", "", ("AR"), "AR/ar.h")
|
||||
SmartPkgEnable("FCOLLADA", "", ChooseLib(fcollada_libs, "FCOLLADA"), ("FCollada", "FCollada/FCollada.h"))
|
||||
SmartPkgEnable("ASSIMP", "assimp", ("assimp"), "assimp")
|
||||
SmartPkgEnable("ASSIMP", "", ("assimp"), "assimp")
|
||||
SmartPkgEnable("FFMPEG", ffmpeg_libs, ffmpeg_libs, ("libavformat/avformat.h", "libavcodec/avcodec.h", "libavutil/avutil.h"))
|
||||
SmartPkgEnable("SWSCALE", "libswscale", "libswscale", ("libswscale/swscale.h"), target_pkg = "FFMPEG", thirdparty_dir = "ffmpeg")
|
||||
SmartPkgEnable("SWRESAMPLE","libswresample", "libswresample", ("libswresample/swresample.h"), target_pkg = "FFMPEG", thirdparty_dir = "ffmpeg")
|
||||
|
|
@ -1460,7 +1461,7 @@ def CompileBison(wobj, wsrc, opts):
|
|||
CopyFile(wdsth, GetOutputDir()+"/tmp/"+ifile+".h")
|
||||
|
||||
# Finally, compile the generated source file.
|
||||
CompileCxx(wobj,wdstc,opts)
|
||||
CompileCxx(wobj, wdstc, opts + ["FLEX"])
|
||||
|
||||
########################################################################
|
||||
##
|
||||
|
|
|
|||
|
|
@ -1052,7 +1052,7 @@ BulletPersistentManifold *BulletWorld::
|
|||
get_manifold(int idx) const {
|
||||
LightMutexHolder holder(get_global_lock());
|
||||
|
||||
nassertr(idx < get_num_manifolds(), NULL);
|
||||
nassertr(idx < _dispatcher->getNumManifolds(), NULL);
|
||||
|
||||
btPersistentManifold *ptr = _dispatcher->getManifoldByIndexInternal(idx);
|
||||
return (ptr) ? new BulletPersistentManifold(ptr) : NULL;
|
||||
|
|
@ -1186,7 +1186,12 @@ tick_callback(btDynamicsWorld *world, btScalar timestep) {
|
|||
CallbackObject *obj = w->_tick_callback_obj;
|
||||
if (obj) {
|
||||
BulletTickCallbackData cbdata(timestep);
|
||||
// Release the global lock that we are holding during the tick callback
|
||||
// and allow interactions with bullet world in the user callback
|
||||
get_global_lock().release();
|
||||
obj->do_callback(&cbdata);
|
||||
// Acquire the global lock again and protect the execution
|
||||
get_global_lock().acquire();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -426,6 +426,23 @@ get_max_updates_per_second() const {
|
|||
return _max_updates_per_second;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies the Content-Type header, useful for applications that require
|
||||
* different types of content, such as JSON.
|
||||
*/
|
||||
INLINE void HTTPChannel::
|
||||
set_content_type(string content_type) {
|
||||
_content_type = content_type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value of the Content-Type header.
|
||||
*/
|
||||
INLINE string HTTPChannel::
|
||||
get_content_type() const {
|
||||
return _content_type;
|
||||
}
|
||||
|
||||
/**
|
||||
* This may be called immediately after a call to get_document() or some
|
||||
* related function to specify the expected size of the document we are
|
||||
|
|
|
|||
|
|
@ -100,6 +100,7 @@ HTTPChannel(HTTPClient *client) :
|
|||
_response_type = RT_none;
|
||||
_http_version = _client->get_http_version();
|
||||
_http_version_string = _client->get_http_version_string();
|
||||
_content_type = "application/x-www-form-urlencoded";
|
||||
_state = S_new;
|
||||
_done_state = S_new;
|
||||
_started_download = false;
|
||||
|
|
@ -3624,7 +3625,7 @@ make_header() {
|
|||
|
||||
if (!_body.empty()) {
|
||||
stream
|
||||
<< "Content-Type: application/x-www-form-urlencoded\r\n"
|
||||
<< "Content-Type: " << _content_type << "\r\n"
|
||||
<< "Content-Length: " << _body.length() << "\r\n";
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -143,6 +143,9 @@ PUBLISHED:
|
|||
INLINE void set_max_updates_per_second(double max_updates_per_second);
|
||||
INLINE double get_max_updates_per_second() const;
|
||||
|
||||
INLINE void set_content_type(string content_type);
|
||||
INLINE string get_content_type() const;
|
||||
|
||||
INLINE void set_expected_file_size(size_t file_size);
|
||||
streamsize get_file_size() const;
|
||||
INLINE bool is_file_size_known() const;
|
||||
|
|
@ -336,6 +339,7 @@ private:
|
|||
string request_path;
|
||||
string _header;
|
||||
string _body;
|
||||
string _content_type;
|
||||
bool _want_ssl;
|
||||
bool _proxy_serves_document;
|
||||
bool _proxy_tunnel_now;
|
||||
|
|
|
|||
|
|
@ -477,6 +477,7 @@ do_remove(AsyncTask *task, bool upon_death) {
|
|||
{
|
||||
int index = find_task_on_heap(_sleeping, task);
|
||||
nassertr(index != -1, false);
|
||||
PT(AsyncTask) hold_task = task;
|
||||
_sleeping.erase(_sleeping.begin() + index);
|
||||
make_heap(_sleeping.begin(), _sleeping.end(), AsyncTaskSortWakeTime());
|
||||
cleanup_task(task, upon_death, false);
|
||||
|
|
@ -486,6 +487,7 @@ do_remove(AsyncTask *task, bool upon_death) {
|
|||
case AsyncTask::S_active:
|
||||
{
|
||||
// Active, but not being serviced, easy.
|
||||
PT(AsyncTask) hold_task = task;
|
||||
int index = find_task_on_heap(_active, task);
|
||||
if (index != -1) {
|
||||
_active.erase(_active.begin() + index);
|
||||
|
|
@ -769,7 +771,6 @@ cleanup_task(AsyncTask *task, bool upon_death, bool clean_exit) {
|
|||
}
|
||||
|
||||
nassertv(task->_chain == this);
|
||||
PT(AsyncTask) hold_task = task;
|
||||
|
||||
task->_state = AsyncTask::S_inactive;
|
||||
task->_chain = nullptr;
|
||||
|
|
|
|||
|
|
@ -138,35 +138,45 @@ get_datagram(Datagram &data) {
|
|||
return true;
|
||||
}
|
||||
|
||||
streamsize num_bytes = (streamsize)num_bytes_32;
|
||||
size_t num_bytes = (size_t)num_bytes_32;
|
||||
if (num_bytes_32 == (uint32_t)-1) {
|
||||
// Another special case for a value larger than 32 bits.
|
||||
num_bytes = reader.get_uint64();
|
||||
}
|
||||
uint64_t num_bytes_64 = reader.get_uint64();
|
||||
|
||||
// Make sure we have a reasonable datagram size for putting into memory.
|
||||
nassertr(num_bytes == (size_t)num_bytes, false);
|
||||
if (_in->fail() || _in->eof()) {
|
||||
_error = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
num_bytes = (size_t)num_bytes_64;
|
||||
|
||||
// Make sure we have a reasonable datagram size for putting into memory.
|
||||
if (num_bytes_64 != (uint64_t)num_bytes) {
|
||||
_error = true;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Now, read the datagram itself. We construct an empty datagram, use
|
||||
// pad_bytes to make it big enough, and read *directly* into the datagram's
|
||||
// internal buffer. Doing this saves us a copy operation.
|
||||
data = Datagram();
|
||||
|
||||
streamsize bytes_read = 0;
|
||||
size_t bytes_read = 0;
|
||||
while (bytes_read < num_bytes) {
|
||||
streamsize bytes_left = num_bytes - bytes_read;
|
||||
size_t bytes_left = num_bytes - bytes_read;
|
||||
|
||||
// Hold up a second - datagrams >4MB are pretty large by bam/network
|
||||
// standards. Let's take it 4MB at a time just in case the length is
|
||||
// corrupt, so we don't allocate potentially a few GBs of RAM only to
|
||||
// find a truncated file.
|
||||
bytes_left = min(bytes_left, (streamsize)4*1024*1024);
|
||||
bytes_left = min(bytes_left, (size_t)4*1024*1024);
|
||||
|
||||
PTA_uchar buffer = data.modify_array();
|
||||
buffer.resize(buffer.size() + bytes_left);
|
||||
unsigned char *ptr = &buffer.p()[bytes_read];
|
||||
|
||||
_in->read((char *)ptr, bytes_left);
|
||||
_in->read((char *)ptr, (streamsize)bytes_left);
|
||||
if (_in->fail() || _in->eof()) {
|
||||
_error = true;
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -78,8 +78,8 @@ extract_record(FltRecordReader &reader) {
|
|||
bool FltBeadID::
|
||||
extract_ancillary(FltRecordReader &reader) {
|
||||
if (reader.get_opcode() == FO_long_id) {
|
||||
vector_uchar s = reader.get_iterator().get_remaining_bytes();
|
||||
_id.assign((const char *)s.data(), strnlen((const char *)s.data(), s.size()));
|
||||
DatagramIterator &di = reader.get_iterator();
|
||||
_id = di.get_fixed_string(di.get_remaining_size());
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -621,8 +621,8 @@ extract_record(FltRecordReader &) {
|
|||
bool FltRecord::
|
||||
extract_ancillary(FltRecordReader &reader) {
|
||||
if (reader.get_opcode() == FO_comment) {
|
||||
vector_uchar s = reader.get_iterator().get_remaining_bytes();
|
||||
_comment.assign((const char *)s.data(), strnlen((const char *)s.data(), s.size()));
|
||||
DatagramIterator &di = reader.get_iterator();
|
||||
_comment = di.get_fixed_string(di.get_remaining_size());
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -88,8 +88,8 @@ def test_minkowski_sum_shape():
|
|||
assert type(shape) is type(shape2)
|
||||
assert shape.margin == shape2.margin
|
||||
assert shape.name == shape2.name
|
||||
assert shape.transform_a.compare_to(shape2.transform_a, True) == 0
|
||||
assert shape.transform_b.compare_to(shape2.transform_b, True) == 0
|
||||
assert shape.transform_a.mat.compare_to(shape2.transform_a.mat, 0.001) == 0
|
||||
assert shape.transform_b.mat.compare_to(shape2.transform_b.mat, 0.001) == 0
|
||||
assert type(shape.shape_a) == type(shape2.shape_a)
|
||||
assert type(shape.shape_b) == type(shape2.shape_b)
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,105 @@
|
|||
from direct.showbase import PythonUtil
|
||||
|
||||
|
||||
def test_queue():
|
||||
q = PythonUtil.Queue()
|
||||
assert q.isEmpty()
|
||||
q.clear()
|
||||
assert q.isEmpty()
|
||||
q.push(10)
|
||||
assert not q.isEmpty()
|
||||
q.push(20)
|
||||
assert not q.isEmpty()
|
||||
assert len(q) == 2
|
||||
assert q.front() == 10
|
||||
assert q.back() == 20
|
||||
assert q.top() == 10
|
||||
assert q.top() == 10
|
||||
assert q.pop() == 10
|
||||
assert len(q) == 1
|
||||
assert not q.isEmpty()
|
||||
assert q.pop() == 20
|
||||
assert len(q) == 0
|
||||
assert q.isEmpty()
|
||||
|
||||
|
||||
def test_flywheel():
|
||||
f = PythonUtil.flywheel(['a','b','c','d'], countList=[11,20,3,4])
|
||||
obj2count = {}
|
||||
for obj in f:
|
||||
obj2count.setdefault(obj, 0)
|
||||
obj2count[obj] += 1
|
||||
assert obj2count['a'] == 11
|
||||
assert obj2count['b'] == 20
|
||||
assert obj2count['c'] == 3
|
||||
assert obj2count['d'] == 4
|
||||
|
||||
f = PythonUtil.flywheel([1,2,3,4], countFunc=lambda x: x*2)
|
||||
obj2count = {}
|
||||
for obj in f:
|
||||
obj2count.setdefault(obj, 0)
|
||||
obj2count[obj] += 1
|
||||
assert obj2count[1] == 2
|
||||
assert obj2count[2] == 4
|
||||
assert obj2count[3] == 6
|
||||
assert obj2count[4] == 8
|
||||
|
||||
f = PythonUtil.flywheel([1,2,3,4], countFunc=lambda x: x, scale = 3)
|
||||
obj2count = {}
|
||||
for obj in f:
|
||||
obj2count.setdefault(obj, 0)
|
||||
obj2count[obj] += 1
|
||||
assert obj2count[1] == 1 * 3
|
||||
assert obj2count[2] == 2 * 3
|
||||
assert obj2count[3] == 3 * 3
|
||||
assert obj2count[4] == 4 * 3
|
||||
|
||||
|
||||
def test_unescape_html_string():
|
||||
assert PythonUtil.unescapeHtmlString('asdf') == 'asdf'
|
||||
assert PythonUtil.unescapeHtmlString('as+df') == 'as df'
|
||||
assert PythonUtil.unescapeHtmlString('as%32df') == 'as2df'
|
||||
assert PythonUtil.unescapeHtmlString('asdf%32') == 'asdf2'
|
||||
|
||||
|
||||
def test_priority_callbacks():
|
||||
l = []
|
||||
def a(l=l):
|
||||
l.append('a')
|
||||
def b(l=l):
|
||||
l.append('b')
|
||||
def c(l=l):
|
||||
l.append('c')
|
||||
|
||||
pc = PythonUtil.PriorityCallbacks()
|
||||
pc.add(a)
|
||||
pc()
|
||||
assert l == ['a']
|
||||
|
||||
del l[:]
|
||||
bItem = pc.add(b)
|
||||
pc()
|
||||
assert 'a' in l
|
||||
assert 'b' in l
|
||||
assert len(l) == 2
|
||||
|
||||
del l[:]
|
||||
pc.remove(bItem)
|
||||
pc()
|
||||
assert l == ['a']
|
||||
|
||||
del l[:]
|
||||
pc.add(c, 2)
|
||||
bItem = pc.add(b, 10)
|
||||
pc()
|
||||
assert l == ['a', 'c', 'b']
|
||||
|
||||
del l[:]
|
||||
pc.remove(bItem)
|
||||
pc()
|
||||
assert l == ['a', 'c']
|
||||
|
||||
del l[:]
|
||||
pc.clear()
|
||||
pc()
|
||||
assert len(l) == 0
|
||||
Loading…
Reference in New Issue