It should return true when the mouse is over the window, and false when it is not. It works for me in pview. Are you sure the mouse is over the window?
!!! bringing up old topic, I know, but it is needed. !!!
Hey David, this is for you, in C++ the mwatcher node, retrieved using the method you’ve given is not tracking mouse movement.
has_mouse appears to be reporting correctly. get_mouse_x() and get_mouse_y() do not.
Is there another step being missed here? Some initialization or something?
it also causes an unhandled exception, looks like panda is trying to work with an object that is null on the close_framework() call.
This only happens when trying to access the mouse, and seems only to happen when the mouse goes outside the window while the program is running. It doesn’t matter if the mouse returns or not before program close.
mouseWatcher = (MouseWatcher*)window->get_mouse().node();
// bla bla bla - other setup etc
// inside of main loop
if (mouseWatcher->has_mouse())
{
LPoint2f mpos = mouseWatcher->get_mouse();
// do something with mpos.get_x() and mpos.get_y()
}
I don’t get any crashes in the close_framework call. You might want to also put pointer != null checks before the has_mouse() call.
The NULL is coming from framework_close() which means Panda is referencing a NULL object.
If I was, it would crash on my code.
Nah, the problem is somewhere underneath.
get_mouse_x() and get_mouse_y() both use the _mouse variable which is what get_mouse() returns anyway, so its all the same thing.
Can you move the mouse outside the program, then return to the window then close it and see if you get the exception?
Noticed this in the source:
////////////////////////////////////////////////////////////////////
// Function: WindowFramework::get_mouse
// Access: Public
// Description: Returns the node in the data graph corresponding to
// the mouse associated with this window.
////////////////////////////////////////////////////////////////////
NodePath WindowFramework::
get_mouse() {
if (_mouse.is_empty()) {
NodePath mouse = _panda_framework->get_mouse(_window);
// Create a MouseWatcher to filter the mouse input. We do this
// mainly so we can constrain the mouse input to our particular
// display region, if we have one. This means the node we return
// from get_mouse() is actually a MouseWatcher, but since it
// presents the same interface as a Mouse, no one should mind.
// Another advantage to using a MouseWatcher is that the PGTop of
// aspect2d likes it better.
PT(MouseWatcher) mw = new MouseWatcher("watcher");
mw->set_display_region(_display_region_3d);
_mouse = mouse.attach_new_node(mw);
}
return _mouse;
}
but where is it deleted? Still looking…
I noticed the panda framework has a get_mouse and a remove_mouse, shouldn’t the window framework always work off of this mouse?
AsyncTask::DoneStatus ctank::tankUpdateTask(GenericAsyncTask* task, void* data)
{
// NOTE: Left and right components move opposite of each other, so in order
// to have them go the same direction, one is the inverse of the other.
// This is because of the way the wheels and tracks were modelled, one side
// is dupes of the other, in order to save time. Modelling each wheel
// and track from scratch would make me go insane.
ctank* tank = (ctank*)data;
NodePath track;
NodePathCollection npc;
// Turret rotation by mouse
WindowFramework* window = getWindow();
PandaNode *mouse_node = window->get_mouse().node();
PT(MouseWatcher) mwatcher = DCAST(MouseWatcher, mouse_node);
if(mwatcher->has_mouse())
{
LPoint2f mouse = mwatcher->get_mouse();
static int omx = mouse.get_x();
static int omy = mouse.get_y();
int mx = mouse.get_x();
int my = mouse.get_y();
int diffx = mx - omx;
if(diffx != 0)
{
NodePath turret = tank->getActor().find("*/Turret");
turret.set_h(turret.get_h() - diffx);
}
omx = mx;
omy = my;
}
Looks like window is bad when it crashes. But the task shouldn’t be getting called on close_framework() should it?
Hmm, looks like close_framework() doesn’t explicitly stop the task manager or remove any tasks, so it’s still possible for a task to be invoked after close_framework() has been called, depending on your task loop.
IIRC, from tracking something else down, that the tasks are queued up and do get played back even after the framework is stopped. So the workaround is to set a “teardown” flag that bypasses the task functions.
Also, is your ctank::tankUpdateTask declared as static? What is your getWindow() function doing?
(Plus it’s C++, you should be checking your pointers for null, always.)
The task was a static method, but I’ve since removed it from the class making it a stand-alone function.
In the Panda source I see that tasks have been PT()'d so I PT()'d all my tasks as well. However, this is not reflected in the online manual.
Other than that, I don’t know what’s going on here. This access violation b.s. has gotta be something else. It’s not making any sense, and the fact that any auto watch and local watch values are all turd-pie & tail-up when the violation occurs makes me wonder…
I’m gonna remove some memory see if that new stuff is bad.
I created a side project, can still get it to crash, this time it points me to the PointerTo class Reassign method, and the copy value seems valid
///////////////////////////////////////////////////////////////////////////////
// panda.cpp
// author: mss
//
//#include "global.h" // -- you wont need this.
PandaFramework framework;
PT(WindowFramework) window = NULL;
EventHandler *eventHandler = EventHandler::get_global_event_handler();
PT(AsyncTaskManager) taskMgr = AsyncTaskManager::get_global_ptr();
PT(ClockObject) globalClock = ClockObject::get_global_clock();
NodePath pandaCamera;
//
// A generic task
//
AsyncTask::DoneStatus mouseTask(GenericAsyncTask* task, void* data)
{
PT(MouseWatcher) mWatcher = DCAST(MouseWatcher, window->get_mouse().node());
if(mWatcher->has_mouse())
{
printf("%f, %f\n", mWatcher->get_mouse_x(), mWatcher->get_mouse_y());
}
return AsyncTask::DS_cont;
}
//
// Panda Tasks
//
AsyncTask::DoneStatus IntervalManagerTask(GenericAsyncTask* task, void* data)
{
CIntervalManager::get_global_ptr()->step();
return AsyncTask::DS_cont;
}
//
// Global Panda Objects Accessors
//
PT(ClockObject) getClock(void)
{
return globalClock;
}
PT(AsyncTaskManager) getTaskMgr(void)
{
return taskMgr;
}
PT(WindowFramework) getWindow(void)
{
return window;
}
PandaFramework* getPanda(void)
{
return &framework;
}
EventHandler* getEventHandler(void)
{
return eventHandler;
}
//
// Other..
//
// TODO: Add other (misc) stuff here.
//
// Custom Setup & Shutdown Functions
//
void Setup(void)
{
PT(GenericAsyncTask) intervalTask =
new GenericAsyncTask("Updates the Interval Manager", &IntervalManagerTask, NULL);
// Add Interval Manager Task
taskMgr->add(intervalTask);
PT(GenericAsyncTask) genericTask =
new GenericAsyncTask("Mouse Check", &mouseTask, NULL);
// Add a generic Task (tests mouse)
taskMgr->add(genericTask);
}
void Shutdown(void)
{
}
//
// Start Function
//
void start(char** vargs, int cargs)
{
// Open the Framework
framework.open_framework(cargs, vargs);
// Open the Window
framework.set_window_title("Hello World!");
window = framework.open_window();
// Verify window has opened successfully
if(window != NULL)
{
// Must call this to enable keyboard input.
window->enable_keyboard();
// Set the camera.
pandaCamera = window->get_camera_group();
// Any extra custom setup.
Setup();
// Main loop
framework.main_loop();
// Any extra custom shutdown stuff.
Shutdown();
// Close the framework
framework.close_framework();
}
}
inside the PointerTo<> class, at reassign… the thing is I don’t know where its coming from because the stack trace is all panda dll’s and all variable watches are bogus/dirty info, and I can’t build panda in debug cuz I don’t have the windows framework and it seems microsoft is not giiving it out for windows xp. :\ uhg. such a dirty dirty job. I hate programming, I’m just addicted to it.
Of course, if you’re building all of Panda yourself, you can use any version of MSVS; it doesn’t necessarily have to be 2008. (But it still helps to use 2008, because of the precompiled thirdparty libraries. If you use a different compiler version, you might have to rebuild all of these libraries, which is an enormous pain.)