Runtime errors when making new application from FeedbackDemo

Forum for software developers to discuss BCI2000 software development
Locked
bburgess
Posts: 7
Joined: 08 Jun 2011, 15:46

Runtime errors when making new application from FeedbackDemo

Post by bburgess » 12 Jul 2011, 12:46

Hey everyone, I am trying to make a new application filter using the FeedbackDemoTask as a model. I am simply trying to get my skeleton code to work (code pared down from feedback demo), and it compiles fine but I get run-time errors at the initialization stage. Here's where it says things go awry:

Code: Select all

void
BalloonTask::OnInitialize( const SignalProperties& /*Input*/ )
{
  mpForm->move( Parameter( "WindowLeft" ), Parameter( "WindowTop" ) ); //Or any other line involving Qt classes.
/*...other stuff involving mpForm, mpLabel, etc...*/
}
Up to this point in the code my header and cpp files are nearly identical (I changed the parameters/state declarations). All declarations and initializations are identical (declare a generic class in the header and initialize to various Qt classes in the initialization list in the constructor). After doing some sleuthing it seems that using any of the mpLabel, mpForm, mpSceneView, etc. objects in the initialization stage or afterward will crash my program, but clearly not the FeedbackDemo. It would be worth noting that the constructor accesses and changes these variables.

I am fairly new to c++ so if there' something obvious I am missing please help!

griffin.milsap
Posts: 58
Joined: 08 Jun 2009, 12:42

Re: Runtime errors when making new application from Feedback

Post by griffin.milsap » 12 Jul 2011, 13:56

Hello and welcome to the forums!

What sort of runtime errors are you seeing? Are they BCI2000 errors (Parameter related) or are they actual runtime crashes?

You said that the code is pretty much skeleton code; could you post a simple example of what's actually breaking?

-Griff

bburgess
Posts: 7
Joined: 08 Jun 2011, 15:46

Re: Runtime errors when making new application from Feedback

Post by bburgess » 12 Jul 2011, 14:25

They're actual crashes (win32 exceptions in the operator log). I'm not sure exactly how much I should post but here are the relevant things:

Header file:

Code: Select all

#ifndef BALLOON_TASK_H
#define BALLOON_TASK_H

#include "FeedbackTask.h"
#include "TrialStatistics.h"

class BalloonTask : public FeedbackTask
{
 public:
  BalloonTask();
  virtual ~BalloonTask();

 private:
  // Events to be handled by FeedbackTask descendants.
  //  Events triggered by the GenericFilter interface
  virtual void OnPreflight( const SignalProperties& Input ) const;
  virtual void OnInitialize( const SignalProperties& Input );
  virtual void OnStartRun();
  virtual void OnStopRun();
  virtual void OnHalt();
  //  Events triggered during the course of a trial
  virtual void OnTrialBegin();
  virtual void OnTrialEnd();
  virtual void OnFeedbackBegin();
  virtual void OnFeedbackEnd();
  //  Dispatching of the input signal.
  //  Each call to GenericSignal::Process() is dispatched to one of these
  //  events, depending on the phase in the sequence.
  //  There, each handler function corresponds to a phase.
  //  If a handler sets the "progress" argument to true, the application's
  //  state will switch to the next phase.
  virtual void DoPreRun(       const GenericSignal&, bool& doProgress );
  virtual void DoPreFeedback(  const GenericSignal&, bool& doProgress );
  virtual void DoFeedback(     const GenericSignal&, bool& doProgress );
  virtual void DoPostFeedback( const GenericSignal&, bool& doProgress );
  virtual void DoITI(          const GenericSignal&, bool& doProgress );

  void SetLabel(const char* text, RGBColor &color);
  template <class T>
  void ShuffleList(int times, T list[]);

 private:
  
  int   mRunCount,
        mTrialCount;
  float mCursorPosX,
        mCursorPosY,
        mCursorSpeedX,
        mCursorSpeedY;

  TrialStatistics mTrialStatistics;

  class QWidget* mpForm;
  class QGraphicsScene* mpScene;
  class QGraphicsView* mpSceneView;
  class QGraphicsTextItem* mpLabel;
  class QGraphicsRectItem* mpTarget;
  class QGraphicsEllipseItem* mpCursor;
};

#endif // BALLOON_TASK_H
The constructor for BalloonTask:

Code: Select all

BalloonTask::BalloonTask()
: mRunCount( 0 ),
  mTrialCount( 0 ),
  mCursorPosX( 0.0 ),
  mCursorPosY( 0.0 ),
  mCursorSpeedX( 0.0 ),
  mCursorSpeedY( 0.0 ),
  mpForm( new QWidget() ),
  mpScene( new QGraphicsScene() ),
  mpSceneView( new QGraphicsView( mpForm ) ),
  mpLabel( new QGraphicsTextItem() ),
  mpTarget( new QGraphicsRectItem() ),
  mpCursor( new QGraphicsEllipseItem() )
{


 BEGIN_PARAMETER_DEFINITIONS

   "Application:BalloonTask float NumberOfDanger= 50.0 50.0 0.0 100.0 // The percentage of trials which have a dangerous balloon",
   "Application:BalloonTask float ChanceForNormal= 75.0 75.0 0.0 100.0 // The percent chance a normal balloon will give money",
   "Application:BalloonTask float ChanceForDanger= 20.0 20.0 0.0 100.0 // The percent chance a danger balloon will give money",
   "Application:BalloonTask int MaxConsecRuns= 3 3 1 % // The maximum number of consecutive identical trials",

 END_PARAMETER_DEFINITIONS
 

 BEGIN_STATE_DEFINITIONS
 
   "BalloonCode   16 0 0 0",
   "TrialType      1 0 0 0", // 0: No danger balloon 1: Danger balloon present
   
 END_STATE_DEFINITIONS
 
  mpForm->setWindowFlags( Qt::FramelessWindowHint );
  mpScene->setBackgroundBrush( QBrush( Qt::black ) );
  mpSceneView->setScene( mpScene );
  mpSceneView->setVerticalScrollBarPolicy( Qt::ScrollBarAlwaysOff );
  mpSceneView->setHorizontalScrollBarPolicy( Qt::ScrollBarAlwaysOff );
  mpSceneView->show();

  mpScene->addItem( mpLabel );
  mpLabel->show();

  mpScene->addItem( mpTarget );
  mpTarget->setPen( Qt::NoPen );
  mpTarget->hide();

  mpScene->addItem( mpCursor );
  mpCursor->setPen( Qt::NoPen );
  mpCursor->hide();

  mpForm->hide();
}
And the preflight and initialize:

Code: Select all

void
BalloonTask::OnPreflight( const SignalProperties& Input) const
{
  Parameter( "WindowHeight" );
  Parameter( "WindowWidth" );
  Parameter( "WindowLeft" );
  Parameter( "WindowTop" );

  if( Parameter( "FeedbackDuration" ).InSampleBlocks() <= 0 )
    bcierr << "FeedbackDuration must be greater 0" << endl;

  Parameter( "NumberOfTrials");

  if( Parameter( "NumberOfTrials" )<Parameter( "MaxConsecRuns" ) )
    bcierr << "Must have more total trials than maximum identical trials" << endl;

  if( Parameter("LogKeyboard") == 0)
	  bcierr << "Turn on keyboard logging to continue. Please restart with command line argument --LogKeyboard=1" << endl;
}


void
BalloonTask::OnInitialize( const SignalProperties& /*Input*/ )
{
  bcidbg << "Started OnInitialize succesfully" << endl;
  mpForm->move( Parameter( "WindowLeft" ), Parameter( "WindowTop" ) );
  bcidbg << "Can move mpForm" << endl;
  mpForm->resize( Parameter( "WindowWidth" ), Parameter( "WindowHeight" ) );
  bcidbg << "Got past mpForm" << endl;
  mpSceneView->resize( Parameter( "WindowWidth" ), Parameter( "WindowHeight" ) );
  mpSceneView->setSceneRect( 0, 0, Parameter( "WindowWidth"), Parameter( "WindowHeight" ) );
  mpSceneView->setVerticalScrollBarPolicy( Qt::ScrollBarAlwaysOff );
  mpSceneView->setHorizontalScrollBarPolicy( Qt::ScrollBarAlwaysOff );
  mpSceneView->show();
  bcidbg << "Got past mpSceneView" << endl;

  RGBColor textColor( RGBColor::Green );
  SetLabel(LocalizableString( "Timeout" ), textColor);

  bcidbg << "Got past SetLabel" << endl;

  mpForm->show();

  int numDanger = Parameter("NumberOfTrials")*Parameter("NumberOfDanger")/100;
  for(int i=0;i<numDanger;i++){
	  trialList[i]=1;
  }
  for(int i=numDanger+1;i<Parameter("NumberOfTrials");i++){
	  trialList[i]=0;
  }

}
The code crashes as soon as it gets to OnInitialize. I was able to find this out via printing to the operator log, more specifically, I never see the "Can move mpForm" statement show up.

I am going to go copy over the FeedbackDemo code cleanly in case I missed something vital.

griffin.milsap
Posts: 58
Joined: 08 Jun 2009, 12:42

Re: Runtime errors when making new application from Feedback

Post by griffin.milsap » 12 Jul 2011, 15:50

Code: Select all

  class QWidget* mpForm;
  class QGraphicsScene* mpScene;
  class QGraphicsView* mpSceneView;
  class QGraphicsTextItem* mpLabel;
  class QGraphicsRectItem* mpTarget;
  class QGraphicsEllipseItem* mpCursor;
This should probably be written as:

Code: Select all

  QWidget* mpForm;
  QGraphicsScene* mpScene;
  QGraphicsView* mpSceneView;
  QGraphicsTextItem* mpLabel;
  QGraphicsRectItem* mpTarget;
  QGraphicsEllipseItem* mpCursor;
With required #includes or forward declarations as necessary at the top of your C++/Header file.

Another thing to watch out for is to delete your dynamically allocated objects (allocated with new) in your destructor if they're allocated in your constructor.

What do the exceptions read? Are they access violations (attempting to access 0x00000000), or are they missing symbol errors?

Hope that helps!

-Griff

bburgess
Posts: 7
Joined: 08 Jun 2011, 15:46

Re: Runtime errors when making new application from Feedback

Post by bburgess » 14 Jul 2011, 12:18

To anyone interested:

The clean copy over worked. I still don't know where I went wrong. That mysterious

Code: Select all

class QGraphicsView*
etc... code is still there and apparently functional.

griffin.milsap
Posts: 58
Joined: 08 Jun 2009, 12:42

Re: Runtime errors when making new application from Feedback

Post by griffin.milsap » 18 Jul 2011, 11:48

Glad to hear you figured it out.

By declaring your objects that way in your class, you've essentially "forward declared" that those classes exist. So long as your class only contains pointers to those objects, you can get away with a forward declaration (in fact, you're encouraged to forward declare to decrease compile time).

Technically, any problems you would meet with forward declaring those classes would be encountered at link time -- if the symbols weren't found. There was really nothing wrong with the code you posted, but I figured you might be experiencing a weird linker bug where it linked the executable and didn't have the symbols it needed (perhaps it was expecting to dynamically load them at program start). I thought your crashes might be from missing symbol exceptions.

Apparently you've figured it out though. Good to hear!

-Griff

Locked

Who is online

Users browsing this forum: No registered users and 1 guest