Commit 4fa7211c authored by Russ Fish's avatar Russ Fish

. Try to fix memory over-run when reading experiments after the first.

   This sometimes results in wonky, skewed viewing transforms.
   - Add hvkill function instead of depending on HyperViewer clean-out code.
   - Improve string handling, remove all fixed-size buffers.
   - Keep label truncation from segmentation violation with a wonky transform.

 . OpenDialog initialization: focus and load text from command-line args.

 . Fix a platform-dependent bug in LabelsMode, resulting from changing it from
   a dropdown to a choice type widget in wxGlade.  Failed to work on Windows.
parent e9a68681
......@@ -740,6 +740,7 @@ NAMESPACEHACK
#include "HypView.h"
extern HypView *hvmain(int,char *[],int,int,int);
extern void hvkill(HypView *);
extern int hvReadFile(char *,int,int);
extern char *getSelected();
extern char *getGraphCenter();
......@@ -838,7 +839,7 @@ static PyObject *_wrap_hvmain(PyObject *self, PyObject *args) {
}
}
result = (HypView *)hvmain(arg1,arg2,arg3,arg4,arg5);
//printf("hvmain %d 0x%x\n", result, result);
resultobj = SWIG_NewPointerObj((void *) result, SWIGTYPE_p_HypView, 0);
return resultobj;
fail:
......@@ -846,6 +847,23 @@ static PyObject *_wrap_hvmain(PyObject *self, PyObject *args) {
}
static PyObject *_wrap_hvkill(PyObject *self, PyObject *args) {
PyObject *resultobj;
HypView *arg1 = (HypView *) 0 ;
PyObject * obj0 = 0 ;
if(!PyArg_ParseTuple(args,(char *)"O:hvkill",&obj0)) goto fail;
if ((SWIG_ConvertPtr(obj0,(void **) &arg1, SWIGTYPE_p_HypView,SWIG_POINTER_EXCEPTION | 0 )) == -1) SWIG_fail;
//printf("hvkill %d 0x%x\n", arg1, arg1);
hvkill(arg1);
Py_INCREF(Py_None); resultobj = Py_None;
return resultobj;
fail:
return NULL;
}
static PyObject *_wrap_hvReadFile(PyObject *self, PyObject *args) {
PyObject *resultobj;
char *arg1 ;
......@@ -3221,6 +3239,7 @@ static PyObject * HypView_swigregister(PyObject *self, PyObject *args) {
}
static PyMethodDef SwigMethods[] = {
{ (char *)"hvmain", _wrap_hvmain, METH_VARARGS },
{ (char *)"hvkill", _wrap_hvkill, METH_VARARGS },
{ (char *)"hvReadFile", _wrap_hvReadFile, METH_VARARGS },
{ (char *)"getSelected", _wrap_getSelected, METH_VARARGS },
{ (char *)"getGraphCenter", _wrap_getGraphCenter, METH_VARARGS },
......
......@@ -51,7 +51,8 @@ NAMESPACEHACK
}
// It's easier to return the pointer to the HypView object rather than access the global.
extern HypView *hvmain(int argc, char *argv[], int window, int width, int height);
extern HypView *hvmain(int argc, char *argv[], int window, int width, int height);
extern void hvkill(HypView *hv);
//extern int hvmain(int argc, char *argv[]);
//%include "cpointer.i"
//%pointer_class(HypView,hvp)
......
......@@ -51,7 +51,8 @@ NAMESPACEHACK
}
// It's easier to return the pointer to the HypView object rather than access the global.
extern HypView *hvmain(int argc, char *argv[], int window, int width, int height);
extern HypView *hvmain(int argc, char *argv[], int window, int width, int height);
extern void hvkill(HypView *hv);
//extern int hvmain(int argc, char *argv[]);
//%include "cpointer.i"
//%pointer_class(HypView,hvp)
......
......@@ -33,6 +33,8 @@ del types
hvmain = _hv.hvmain
hvkill = _hv.hvkill
hvReadFile = _hv.hvReadFile
getSelected = _hv.getSelected
......
......@@ -84,6 +84,7 @@ class OpenDialogUI(wxDialog):
# begin wxGlade: OpenDialogUI.__set_properties
self.SetTitle("Open HyperViewer Data")
self.SetSize((387, 310))
self.FileToOpen.SetFocus()
# end wxGlade
def __do_layout(self):
......@@ -155,7 +156,7 @@ class hvFrameUI(wxFrame):
self.DrawLinks = wxCheckBox(self.Controls, -1, "Draw links")
self.KeepAspect = wxCheckBox(self.Controls, -1, "Keep aspect")
self.LabelToRight = wxCheckBox(self.Controls, -1, "Label to right")
self.LabelsMode = wxChoice(self.Controls, -1, choices=["None", "Short", "Long"], style=wxCB_DROPDOWN)
self.LabelsMode = wxChoice(self.Controls, -1, choices=["None", "Short", "Long"])
self.label_3 = wxStaticText(self.Controls, -1, " Labels")
self.CountGenNode = wxSpinCtrl(self.Controls, -1, "30", min=1, max=30)
self.label_4 = wxStaticText(self.Controls, -1, " Node depth")
......
<?xml version="1.0"?>
<!-- generated by wxGlade 0.3.1 on Fri Jul 30 09:08:36 2004 -->
<!-- generated by wxGlade 0.3.1 on Mon Aug 2 10:20:56 2004 -->
<application path="hvFrameUI.py" name="hvGui" class="hvApp" option="0" language="python" top_window="" encoding="US-ASCII" use_gettext="0" overwrite="0">
<object class="hvFrameUI" name="MainWindow" base="EditFrame">
......@@ -275,7 +275,7 @@
<object class="sizeritem">
<border>0</border>
<option>0</option>
<object class="wxChoice" name="LabelsMode" base="EditComboBox">
<object class="wxChoice" name="LabelsMode" base="EditChoice">
<selection>2</selection>
<choices>
<choice>None</choice>
......@@ -421,6 +421,7 @@
<option>0</option>
<object class="wxTextCtrl" name="FileToOpen" base="EditTextCtrl">
<style>wxTE_PROCESS_ENTER</style>
<focused>1</focused>
</object>
</object>
<object class="sizeritem">
......
......@@ -15,6 +15,8 @@
// hvmain.cpp - hypview for SWIG into _hv.so, based on hypviewer/examples/glut/main.cpp .
#include <stdio.h>
#include <memory>
#include <string>
#include <iostream>
NAMESPACEHACK
......@@ -42,28 +44,28 @@ extern "C" {
#include "HypData.h"
#include "HypNode.h"
char prevsel[1024];
HypView *hv;
//char prevsel[1024];
string prevsel;
auto_ptr<HypView> hv;
char *getSelected(){
return prevsel;
char const *getSelected(){
return prevsel.c_str();
}
// I guess I don't know how to handle a "string" returned by the SWIG Python wrapper...
char *getGraphCenter(){
string * result = new string(hv->getGraphCenter());
return (char *)result->c_str();
char * getGraphCenter(){
return const_cast<char *>(hv->getGraphCenter().c_str());
}
void selectCB(const string & id, int shift, int control) {
//printf("selectCB id=%s, prevsel=%s\n", id.c_str(), prevsel);
//printf("selectCB id=%s, prevsel=%s\n", id.c_str(), prevsel.c_str());
//cerr << "selectCB id=" << id.c_str() << ", prevsel=" << prevsel << endl;
hv->setSelected(id, 1);
hv->setSelected(prevsel, 0);
hv->gotoNode(id, HV_ANIMATE);
hv->drawFrame();
hv->idle(1);
strncpy(prevsel, id.c_str(), sizeof(prevsel));
prevsel = id;
}
void display() { hv->drawFrame(); }
......@@ -117,8 +119,9 @@ void keyboard(unsigned char key, int /*x*/, int /*y*/) {
void PrintAllocations()
{
if (hv)
delete(hv);
// if (hv)
// delete(hv);
hv.reset(NULL);
cerr << "HypNode objects not destroyed: " << HypNode::NumObjects() << endl;
cerr << "HypLink objects not destroyed: " << HypLink::NumObjects() << endl;
return;
......@@ -127,6 +130,10 @@ void PrintAllocations()
#if 0
int main(int argc, char *argv[]) {
#else
void hvkill(HypView * /*hv*/) {
// delete( hv );
}
HypView *hvmain(int argc, char *argv[], int window, int width, int height) {
#endif
char *fname;
......@@ -160,11 +167,11 @@ HypView *hvmain(int argc, char *argv[], int window, int width, int height) {
#endif
#ifndef WIN32
hv = new HypView();
hv.reset(new HypView());
#else
HWND hWnd = (HWND)window;
HDC hdc = ::GetDC(hWnd);
hv = new HypView(hdc, hWnd);
hv.reset(new HypView(hdc, hWnd));
HGLRC ctx = wglCreateContext(hdc);
if (!ctx) {
printf("wglCreateContext Failed\n");
......@@ -180,8 +187,10 @@ HypView *hvmain(int argc, char *argv[], int window, int width, int height) {
inFile.close();
#endif
#ifndef WIN32
//printf("hvmain width=%d, height=%d\n", width, height);
hv->afterRealize();
#else
//printf("hvmain ctx=0x%x, width=%d, height=%d\n", width, height);
hv->afterRealize(ctx, width, height);
#endif
hv->setSphere(1);
......@@ -242,15 +251,19 @@ HypView *hvmain(int argc, char *argv[], int window, int width, int height) {
glutReshapeFunc(reshape);
glutMainLoop();
delete(hv);
// delete(hv);
PrintAllocations();
return 0;
// free(fname);
#else
return hv;
return hv.get();
#endif
}
int hvReadFile(char *fname, int width, int height) {
ifstream inFile(fname);
if (!inFile) {
......
......@@ -42,7 +42,7 @@ class hvApp(wxApp):
def OnInit(self):
# Given command-line argument(s), attempt to read in a topology.
filename = project = None
filename = filearg = project = experiment = root = None
# Any dash argument prints a usage message and exits.
if len(sys.argv) == 2 and sys.argv[1][0] == '-':
print '''Hyperviewer usage:
......@@ -60,7 +60,7 @@ class hvApp(wxApp):
# One command-line argument: read from a .hyp file.
# (File/experiment input is also in the OnOpenFile and OnOpenExperiment methods.)
elif len(sys.argv) == 2:
filename = sys.argv[1]
filename = filearg = sys.argv[1]
print "Reading file:", filename
pass
......@@ -88,6 +88,18 @@ class hvApp(wxApp):
self.openDialog.app = self
self.usageDialog = UsageDialogUI(None, -1, "HyperViewer Usage")
# Initialize the text fields in the File/Open dialog.
if filearg:
self.openDialog.FileToOpen.SetValue(filearg)
if project:
self.openDialog.ProjectName.SetValue(project)
if experiment:
self.openDialog.ExperimentName.SetValue(experiment)
self.openDialog.ExperimentName.SetFocus()
if root:
self.openDialog.ExperimentRoot.SetValue(root)
# Make it visible.
self.frame.Show()
self.SetTopWindow(self.frame)
......@@ -181,9 +193,20 @@ class hvFrame(hvFrameUI):
width, height = self.hypView.GetSizeTuple()
# Instantiate and initialize the SWIG'ed C++ HypView object, loading graph data.
if self.vwr is not None:
# Give up on hvReadFile; the cleanup logic is busted. Always make a new HypView.
##print "hvkill", self.vwr
hv.hvkill(self.vwr)
# This is *really* evil... It fails every other time, so do it twice.
self.vwr = hv.hvmain([str(name), str(file)], # Must be non-unicode strings.
window, width, height) # Win32 needs the window info.
hv.hvkill(self.vwr)
self.vwr = None
self.vwr = hv.hvmain([str(name), str(file)], # Must be non-unicode strings.
window, width, height) # Win32 needs the window info.
if self.vwr is None: # Must have been a problem....
if self.vwr is None: # Must have been a problem....
return False
# Initial drawing.
......
......@@ -621,6 +621,7 @@ public:
//--------------------------------------------------------------------------
void setLabelPos(double x, double y, double z)
{
//cerr << "setLabelPos " << x << ", " << y << ", " << z << endl;
label.x = x;
label.y = y;
label.z = z;
......
......@@ -440,7 +440,6 @@ void HypGraph::loadSpanGraph(istream & flat)
HypNode *current = NULL;
HypNode *descend = NULL;
string id, type, mainid, line;
char buf[1024];
string token;
StringArray groups;
int level;
......@@ -456,9 +455,7 @@ void HypGraph::loadSpanGraph(istream & flat)
// parse line
linecount++;
buf[0] = '\0';
flat.getline(buf,1024,'\n');
line = string(buf);
getline(flat, line);
if (line.length() <= 1)
continue;
......
......@@ -34,6 +34,8 @@
// Contractor/manufacturer is Silicon Graphics, Inc., 2011 N.
// Shoreline Blvd. Mountain View, CA 94039-7311.
#include <sstream>
#include <string>
NAMESPACEHACK
......@@ -362,14 +364,14 @@ void HypNode::layoutT() {
string HypNode::save(int lev) {
string str;
string tab;
char t1[32], t2[32];
ostringstream outerLevStream, outerEnabledStream;
int i;
for (i = -2; i < lev; i++) tab = tab + " ";
tab = "";
sprintf(t1, "%d ", lev);
sprintf(t2, " %d ", this->getEnabled());
str = str + tab + t1 + theurl + t2;
outerLevStream << lev;
outerEnabledStream << this->getEnabled();
str = str + tab + outerLevStream.str() + theurl + outerEnabledStream.str();
for (i = 0; i < thegroups.size(); i++) {
str = str + " " + thegroups[i];
}
......@@ -381,10 +383,11 @@ string HypNode::save(int lev) {
tab = tab + " ";
tab = "";
for (i = 0; i < outgoing.size(); i++) {
sprintf(t1, "%d ", lev+1);
sprintf(t2, " %d ", outgoing[i]->getEnabled());
ostringstream levStream, enabledStream;
levStream << lev + 1;
enabledStream << outgoing[i]->getEnabled();
HypNode *n = outgoing[i]->getChild();
str = str + tab + t1 + outgoing[i]->getChildId() + t2;
str = str + tab + levStream.str() + outgoing[i]->getChildId() + enabledStream.str();
for (int j = 0; j < thegroups.size(); j++)
str = str + " " + n->thegroups[j];
str.append("\n");
......
......@@ -38,6 +38,7 @@
NAMESPACEHACK
#include <stdio.h>
//#include <unistd.h>
#ifdef WIN32
# include <sys/timeb.h>
......@@ -284,12 +285,13 @@ void HypViewer::newLayout() {
void HypViewer::afterRealize()
{
glGetIntegerv ( GL_VIEWPORT, vp ); /* get viewport size */
//printf("GLUT afterRealize vp=[%d %d %d %d], labelscaledsize=%g\n", vp[0], vp[1], vp[2], vp[3], labelscaledsize );
resetLabelSize();
glInit();
drawStringInit();
idleFunc(1);
}
#endif // HYPGLUT
#ifdef WIN32
......@@ -349,6 +351,7 @@ void HypViewer::sphereInit()
//----------------------------------------------------------------------------
void HypViewer::glInit()
{
//printf("glInit\n");
int i, j;
framePrepare();
glClearColor(hd->colorBack[0], hd->colorBack[1], hd->colorBack[2], 1.0);
......@@ -746,7 +749,8 @@ void HypViewer::drawNode(HypNode *n)
memcpy(&glm[4],T.T[1],sizeof(double)*4);
memcpy(&glm[8],T.T[2],sizeof(double)*4);
memcpy(&glm[12],T.T[3],sizeof(double)*4);
//printf("glm\n"); for(int i=0;i<16;i++){printf(" %f", glm[i]); if(i%4==3)printf("\n");}
// glMultMatrixd((double*)T.T);
glMultMatrixd(glm);
......@@ -881,12 +885,15 @@ void HypViewer::drawLabel(HypNode *n)
str = n->getLongLabel().c_str();
if ( (len = strlen(str)) < 1) return;
int labw = drawStringWidth(str);
int charwidth = labw/len;
// this is strange, but needed to work on weevil.
// remove next three lines after upgrade weevil to 6.2
// if (n->getHighlighted()) lab.z = 0.0;
// glColor3f(hd->colorLabel[0], hd->colorLabel[1], hd->colorLabel[2]);
// glBegin(GL_TRIANGLE_STRIP);
// glEnd();
if (n->getHighlighted())
glColor3f(hd->colorLabel[0], hd->colorLabel[1], hd->colorLabel[2]);
else
......@@ -896,15 +903,31 @@ void HypViewer::drawLabel(HypNode *n)
if (labeltoright) {
labl = 0.0;
labr = labw;
if ( lab.x > vp[3] )
return; // Entirely off the right side of the viewport.
} else {
labl = -labw;
labr = 0.0;
if (lab.x+labl < 0.0) {
if ( lab.x - charwidth < 0.0 )
return; // Entirely off the left side of the viewport.
if (lab.x+labl < 0.0) {
// GL won't display string if beginning is to left of window border:
// truncate the requisite number of chars from the front
int truncamt = (int) ((lab.x+labl)*len/labw);
str += -truncamt;
labl = -lab.x;
int truncamt = (int) ((lab.x-labw)/charwidth);
/* fprintf(stderr,"drawLabel str=%s, len=%d, truncamt=%d, labl=%f, lab.x=%f\n",
str, len, truncamt, labl, lab.x); /**/
// Beware of hugely negative lab.x due to busted transform.
if ( truncamt < 0 && abs(truncamt) < len && truncamt != 0x80000000 ) {
//fprintf(stderr," str=%s\n", str);
//const char * ostr = str;
str += -truncamt;
labl = -lab.x;
//fprintf(stderr, " str=%s\n", str);
}
else
return;
}
}
glBegin(GL_TRIANGLE_STRIP);
......@@ -1679,6 +1702,8 @@ void HypViewer::resetLabelSize()
scaledvp = vp[2];
}
labelscaledsize = hd->labelsize*(scaledvp/1000.0);
//printf("resetLabelSize vp=[%d %d %d %d], labelscaledsize=%g\n", vp[0], vp[1], vp[2], vp[3], labelscaledsize );
}
......@@ -1987,6 +2012,8 @@ int HypViewer::flashLink(HypNode *fromnode, HypNode *tonode)
{
#ifndef PyHack
glutPostRedisplay();
#else
drawFrame();
#endif
return;
}
......@@ -2126,9 +2153,7 @@ void HypViewer::frameEnd() {
void HypViewer::idleCont() {
/*
if (idleframe == 1) {
char s[256];
sprintf(s, "idle cont\n");
OutputDebugString(s);
OutputDebugString("idle cont\n");
InvalidateRect(win,NULL,FALSE);
} else {
ValidateRect(win,NULL);
......
......@@ -743,6 +743,7 @@ NAMESPACEHACK
#include "HypView.h"
extern HypView *hvmain(int,char *[],int,int,int);
extern void hvkill(HypView *);
extern int hvReadFile(char *,int,int);
extern char *getSelected();
extern char *getGraphCenter();
......@@ -849,6 +850,22 @@ static PyObject *_wrap_hvmain(PyObject *self, PyObject *args) {
}
static PyObject *_wrap_hvkill(PyObject *self, PyObject *args) {
PyObject *resultobj;
HypView *arg1 = (HypView *) 0 ;
PyObject * obj0 = 0 ;
if(!PyArg_ParseTuple(args,(char *)"O:hvkill",&obj0)) goto fail;
if ((SWIG_ConvertPtr(obj0,(void **) &arg1, SWIGTYPE_p_HypView,SWIG_POINTER_EXCEPTION | 0 )) == -1) SWIG_fail;
hvkill(arg1);
Py_INCREF(Py_None); resultobj = Py_None;
return resultobj;
fail:
return NULL;
}
static PyObject *_wrap_hvReadFile(PyObject *self, PyObject *args) {
PyObject *resultobj;
char *arg1 ;
......@@ -3280,6 +3297,7 @@ static PyObject * HypView_swigregister(PyObject *self, PyObject *args) {
}
static PyMethodDef SwigMethods[] = {
{ (char *)"hvmain", _wrap_hvmain, METH_VARARGS },
{ (char *)"hvkill", _wrap_hvkill, METH_VARARGS },
{ (char *)"hvReadFile", _wrap_hvReadFile, METH_VARARGS },
{ (char *)"getSelected", _wrap_getSelected, METH_VARARGS },
{ (char *)"getGraphCenter", _wrap_getGraphCenter, METH_VARARGS },
......
......@@ -33,13 +33,15 @@ del types
hvmain = _hv.hvmain
hvReadFile = _hv.hvReadFile
hvkill = _hv.hvkill
selectCB = _hv.selectCB
hvReadFile = _hv.hvReadFile
getSelected = _hv.getSelected
getGraphCenter = _hv.getGraphCenter
selectCB = _hv.selectCB
class HypView(_object):
__swig_setmethods__ = {}
__setattr__ = lambda self, name, value: _swig_setattr(self, HypView, name, value)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment