new CTask for debugging on Linux

This commit is contained in:
Joe Shochet 2004-09-03 23:59:09 +00:00
parent 3706822aae
commit 14bcc223a0
11 changed files with 296 additions and 16 deletions

View File

@ -8,7 +8,7 @@
#define BUILDING_DLL BUILDING_DIRECT #define BUILDING_DLL BUILDING_DIRECT
#define COMPONENT_LIBS \ #define COMPONENT_LIBS \
directbase dcparser showbase deadrec directd interval distributed directbase dcparser showbase deadrec directd interval distributed task
#define OTHER_LIBS \ #define OTHER_LIBS \
panda:m \ panda:m \

View File

@ -108,16 +108,16 @@ class DistributedSmoothNodeBase:
if stagger: if stagger:
delay = randFloat(period) delay = randFloat(period)
taskMgr.doMethodLater(self.__broadcastPeriod + delay, taskMgr.doMethodLater(self.__broadcastPeriod + delay,
self.posHprBroadcast, taskName) self.__posHprBroadcast, taskName)
def posHprBroadcast(self, task): def __posHprBroadcast(self, task):
# TODO: we explicitly stagger the initial task timing in # TODO: we explicitly stagger the initial task timing in
# startPosHprBroadcast; we should at least make an effort to keep # startPosHprBroadcast; we should at least make an effort to keep
# this task accurately aligned with its period and starting time. # this task accurately aligned with its period and starting time.
self.d_broadcastPosHpr() self.d_broadcastPosHpr()
taskName = self.taskName("sendPosHpr") taskName = self.taskName("sendPosHpr")
taskMgr.doMethodLater(self.__broadcastPeriod, taskMgr.doMethodLater(self.__broadcastPeriod,
self.posHprBroadcast, taskName) self.__posHprBroadcast, taskName)
return Task.done return Task.done
def d_broadcastPosHpr_FULL(self): def d_broadcastPosHpr_FULL(self):

View File

@ -7,9 +7,18 @@
#define DIR_TYPE metalib #define DIR_TYPE metalib
#define BUILDING_DLL BUILDING_DIRECT #define BUILDING_DLL BUILDING_DIRECT
#define OTHER_LIBS \
pandaexpress:m \
dconfig:c dtoolconfig:m \
dtoolutil:c dtoolbase:c dtool:m
#begin metalib_target #begin metalib_target
#define TARGET heapq #define TARGET heapq
#define SOURCES heapq.c #define LOCAL_LIBS \
task
#define SOURCES heapq.cxx
#end metalib_target #end metalib_target

View File

@ -7,6 +7,7 @@
*/ */
#include <Python.h> #include <Python.h>
#include "cTask.h"
/* Prototypes */ /* Prototypes */
static PyObject * heappush(PyObject *self, PyObject *args); static PyObject * heappush(PyObject *self, PyObject *args);
@ -124,15 +125,36 @@ _siftdown(PyObject *list, int startpos, int pos) {
int parentpos, cmp; int parentpos, cmp;
newitem = PySequence_GetItem(list,pos); newitem = PySequence_GetItem(list,pos);
PyObject *newitemCTask_this = PyObject_GetAttrString(newitem, "this");
nassertr(newitemCTask_this != NULL, false);
CTask *newitemCTask = (CTask *)PyInt_AsLong(newitemCTask_this);
Py_DECREF(newitemCTask_this);
while (pos > startpos) { while (pos > startpos) {
parentpos = (pos - 1) >> 1; parentpos = (pos - 1) >> 1;
parent = PyList_GetItem(list,parentpos); parent = PyList_GetItem(list,parentpos);
/*
cmp = PyObject_RichCompareBool(parent,newitem,Py_LE); cmp = PyObject_RichCompareBool(parent,newitem,Py_LE);
if (cmp > 0) if (cmp > 0)
break; break;
else if (cmp < 0) else if (cmp < 0)
return -1; return -1;
*/
PyObject *parentCTask_this = PyObject_GetAttrString(parent, "this");
nassertr(parentCTask_this != NULL, false);
CTask *parentCTask = (CTask *)PyInt_AsLong(parentCTask_this);
Py_DECREF(parentCTask_this);
if (parentCTask->get_wake_time() <= newitemCTask->get_wake_time()) {
break;
} else {
return -1;
}
Py_INCREF(parent); Py_INCREF(parent);
PyList_SetItem(list,pos,parent); PyList_SetItem(list,pos,parent);
pos = parentpos; pos = parentpos;
@ -155,13 +177,34 @@ _siftup(PyObject *list, int pos) {
while (childpos < endpos) { while (childpos < endpos) {
rightpos = childpos + 1; rightpos = childpos + 1;
child = PySequence_Fast_GET_ITEM(list,childpos); child = PySequence_Fast_GET_ITEM(list,childpos);
PyObject *childCTask_this = PyObject_GetAttrString(child, "this");
nassertr(childCTask_this != NULL, false);
CTask *childCTask = (CTask *)PyInt_AsLong(childCTask_this);
Py_DECREF(childCTask_this);
if (rightpos < endpos) { if (rightpos < endpos) {
right = PySequence_Fast_GET_ITEM(list,rightpos); right = PySequence_Fast_GET_ITEM(list,rightpos);
PyObject *rightCTask_this = PyObject_GetAttrString(right, "this");
nassertr(rightCTask_this != NULL, false);
CTask *rightCTask = (CTask *)PyInt_AsLong(rightCTask_this);
Py_DECREF(rightCTask_this);
/*
cmp = PyObject_RichCompareBool(right,child,Py_LE); cmp = PyObject_RichCompareBool(right,child,Py_LE);
if (cmp > 0) if (cmp > 0)
childpos = rightpos; childpos = rightpos;
else if (cmp < 0) else if (cmp < 0)
return -1; return -1;
*/
if (rightCTask->get_wake_time() <= childCTask->get_wake_time()) {
childpos = rightpos;
} else {
return -1;
}
} }
child = PySequence_GetItem(list,childpos); child = PySequence_GetItem(list,childpos);
PyList_SetItem(list,pos,child); PyList_SetItem(list,pos,child);

View File

@ -0,0 +1,17 @@
#begin lib_target
#define TARGET task
#define LOCAL_LIBS \
directbase
#define OTHER_LIBS \
panda
#define SOURCES \
config_task.cxx config_task.h \
cTask.h cTask.I cTask.cxx
#define INSTALL_HEADERS \
config_task.h \
cTask.h cTask.I
#define IGATESCAN all
#end lib_target

View File

@ -5,7 +5,8 @@
# subset of PandaModules that we know is available immediately. # subset of PandaModules that we know is available immediately.
# Methods that require more advanced C++ methods may import the # Methods that require more advanced C++ methods may import the
# appropriate files within their own scope. # appropriate files within their own scope.
from pandac.libpandaexpressModules import * # from pandac.libpandaexpressModules import *
from pandac.libdirectModules import *
from direct.directnotify.DirectNotifyGlobal import * from direct.directnotify.DirectNotifyGlobal import *
from direct.showbase.PythonUtil import * from direct.showbase.PythonUtil import *
@ -63,9 +64,14 @@ def print_exc_plus():
except: except:
print "<ERROR WHILE PRINTING VALUE>" print "<ERROR WHILE PRINTING VALUE>"
class Task: # Here we inherit from CTask so that we can drop the expensive work
# that the task does down into C++. The main reason to do this is
# to move the compare operator for the heapq data structure.
class Task(CTask):
count = 0 count = 0
def __init__(self, callback, priority = 0): def __init__(self, callback, priority = 0):
CTask.__init__(self)
# Unique ID for each task # Unique ID for each task
self.id = Task.count self.id = Task.count
Task.count += 1 Task.count += 1
@ -79,16 +85,14 @@ class Task:
self.runningTotal = 0.0 self.runningTotal = 0.0
self.pstats = None self.pstats = None
self.extraArgs = None self.extraArgs = None
# Used for doLaters
self.wakeTime = 0.0
# Used for putting into the doLaterList # Used for putting into the doLaterList
# the heapq calls __cmp__ via the rich compare function # the heapq calls __cmp__ via the rich compare function
def __cmp__(self, other): def __cmp__(self, other):
if isinstance(other, Task): if isinstance(other, Task):
if self.wakeTime < other.wakeTime: if self.getWakeTime() < other.getWakeTime():
return -1 return -1
elif self.wakeTime > other.wakeTime: elif self.getWakeTime() > other.getWakeTime():
return 1 return 1
# If the wakeTimes happen to be the same, just # If the wakeTimes happen to be the same, just
# sort them based on id # sort them based on id
@ -386,7 +390,7 @@ class TaskManager:
continue continue
# If the time now is less than the start of the doLater + delay # If the time now is less than the start of the doLater + delay
# then we are not ready yet, continue to next one # then we are not ready yet, continue to next one
elif task.time < dl.wakeTime: elif task.time < dl.getWakeTime():
# Since the list is sorted, the first one we get to, that # Since the list is sorted, the first one we get to, that
# is not ready to go, we can return # is not ready to go, we can return
break break
@ -423,7 +427,7 @@ class TaskManager:
# have been synced since the start of this frame # have been synced since the start of this frame
currentTime = globalClock.getFrameTime() currentTime = globalClock.getFrameTime()
# Cache the time we should wake up for easier sorting # Cache the time we should wake up for easier sorting
task.wakeTime = currentTime + delayTime task.setWakeTime(currentTime + delayTime)
# Push this onto the doLaterList. The heap maintains the sorting. # Push this onto the doLaterList. The heap maintains the sorting.
heappush(self.__doLaterList, task) heappush(self.__doLaterList, task)
if self.fVerbose: if self.fVerbose:
@ -853,7 +857,7 @@ class TaskManager:
sortedDoLaterList.sort() sortedDoLaterList.sort()
sortedDoLaterList.reverse() sortedDoLaterList.reverse()
for task in sortedDoLaterList: for task in sortedDoLaterList:
remainingTime = ((task.wakeTime) - self.currentTime) remainingTime = ((task.getWakeTime()) - self.currentTime)
if task.isRemoved(): if task.isRemoved():
taskName = '(R)' + task.name taskName = '(R)' + task.name
else: else:

38
direct/src/task/cTask.I Executable file
View File

@ -0,0 +1,38 @@
// Filename: cTask.I
// Created by: Administrator (03Sep04)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
//
// All use of this software is subject to the terms of the Panda 3d
// Software license. You should have received a copy of this license
// along with this source code; you will also find a current copy of
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
//
// To contact the maintainers of this program write to
// panda3d-general@lists.sourceforge.net .
//
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
// Function: CTask::set_wake_time
// Access: Published
// Description: Sets the wake time of this task (for doLaters)
////////////////////////////////////////////////////////////////////
INLINE void CTask::
set_wake_time(float wake_time) {
_wake_time = wake_time;
}
////////////////////////////////////////////////////////////////////
// Function: CTask::get_wake_time
// Access: Published
// Description: Returns wake time of this task (for doLaters)
////////////////////////////////////////////////////////////////////
INLINE float CTask::
get_wake_time() const {
return _wake_time;
}

31
direct/src/task/cTask.cxx Executable file
View File

@ -0,0 +1,31 @@
// Filename: cTask.cxx
// Created by: Administrator (03Sep04)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
//
// All use of this software is subject to the terms of the Panda 3d
// Software license. You should have received a copy of this license
// along with this source code; you will also find a current copy of
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
//
// To contact the maintainers of this program write to
// panda3d-general@lists.sourceforge.net .
//
////////////////////////////////////////////////////////////////////
#include "cTask.h"
TypeHandle CTask::_type_handle;
CTask::
CTask() {
_wake_time = 0.0;
}
CTask::
~CTask() {
}

59
direct/src/task/cTask.h Executable file
View File

@ -0,0 +1,59 @@
// Filename: cTask.h
// Created by: Shochet (03Sep04)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
//
// All use of this software is subject to the terms of the Panda 3d
// Software license. You should have received a copy of this license
// along with this source code; you will also find a current copy of
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
//
// To contact the maintainers of this program write to
// panda3d-general@lists.sourceforge.net .
//
////////////////////////////////////////////////////////////////////
#ifndef CTASK_H
#define CTASK_H
#include "directbase.h"
#include "typedReferenceCount.h"
#include "config_task.h"
class EXPCL_DIRECT CTask : public TypedReferenceCount {
PUBLISHED:
CTask();
~CTask();
INLINE void set_wake_time(float wake_time);
INLINE float get_wake_time() const;
public:
static TypeHandle get_class_type() {
return _type_handle;
}
static void init_type() {
TypedReferenceCount::init_type();
register_type(_type_handle, "CTask",
TypedReferenceCount::get_class_type());
}
virtual TypeHandle get_type() const {
return get_class_type();
}
virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
private:
float _wake_time;
static TypeHandle _type_handle;
};
#include "cTask.I"
#endif

49
direct/src/task/config_task.cxx Executable file
View File

@ -0,0 +1,49 @@
// Filename: config_task.cxx
// Created by: Administrator (03Sep04)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
//
// All use of this software is subject to the terms of the Panda 3d
// Software license. You should have received a copy of this license
// along with this source code; you will also find a current copy of
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
//
// To contact the maintainers of this program write to
// panda3d-general@lists.sourceforge.net .
//
////////////////////////////////////////////////////////////////////
#include "config_task.h"
#include "cTask.h"
#include "dconfig.h"
Configure(config_task);
NotifyCategoryDef(task, "");
ConfigureFn(config_task) {
init_libtask();
}
////////////////////////////////////////////////////////////////////
// Function: init_libtask
// Description: Initializes the library. This must be called at
// least once before any of the functions or classes in
// this library can be used. Normally it will be
// called by the static initializers and need not be
// called explicitly, but special cases exist.
////////////////////////////////////////////////////////////////////
void
init_libtask() {
static bool initialized = false;
if (initialized) {
return;
}
initialized = true;
CTask::init_type();
}

30
direct/src/task/config_task.h Executable file
View File

@ -0,0 +1,30 @@
// Filename: config_task.h
// Created by: Shochet (03Sep04)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
//
// All use of this software is subject to the terms of the Panda 3d
// Software license. You should have received a copy of this license
// along with this source code; you will also find a current copy of
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
//
// To contact the maintainers of this program write to
// panda3d-general@lists.sourceforge.net .
//
////////////////////////////////////////////////////////////////////
#ifndef CONFIG_TASK_H
#define CONFIG_TASK_H
#include "directbase.h"
#include "notifyCategoryProxy.h"
#include "dconfig.h"
NotifyCategoryDecl(task, EXPCL_DIRECT, EXPTP_DIRECT);
extern EXPCL_DIRECT void init_libtask();
#endif