Author Topic: Timers question  (Read 9842 times)

asandler

  • Senior Community Member
  • Posts: 299
  • Hero Points: 27
Timers question
« on: March 02, 2008, 10:09:39 am »
I have a form and a event table for the form. In one of the key press handlers I create a timer with _set_timer(). Once it expires it is calling a callback function that I provide. The problem is that when I try to access the form from the callback function I get an error stating control (the form) referenced, but does not exist. Any ideas?

Graeme

  • Senior Community Member
  • Posts: 2320
  • Hero Points: 305
Re: Timers question
« Reply #1 on: March 02, 2008, 11:07:58 am »
Hi

You need to call _find_formobj('name-of-form') to get the window id of the form  - if it exists.  If the form doesn't already exist you can create it using show
      show('-xy ' :+ form_name);

Then you can call _find_formobj to get its window id.  Using the window id you can access the properties of the form.

Graeme

asandler

  • Senior Community Member
  • Posts: 299
  • Hero Points: 27
Re: Timers question
« Reply #2 on: March 02, 2008, 11:30:18 am »
Thanks Graeme, it helped.
Now I am facing another problem. I am trying to reference static variable defined in the module from the callback and get "This property or method is not allowed on this object". Can you (or anyone else) explain what's the problem? This seems to be a scoping issue. If so, I'll continue encountering problems of this kind unless I'll find a way to fix this once and for all. Is it possible?

hs2

  • Senior Community Member
  • Posts: 2737
  • Hero Points: 288
Re: Timers question
« Reply #3 on: March 02, 2008, 12:51:07 pm »
Hi Alexander,
in ols I'm using this method:
Code: [Select]
static void UpdateTimerCallback ( int ols_wid )
{
   _kill_timer ( _ols_UpdateTimerId ); _ols_UpdateTimerId = -1;
   orig_wid := p_window_id;
   p_window_id = ols_wid;
   _update_tree ();
   p_window_id = orig_wid;
}
static void update_tree ()
{
   if ( _ols_UpdateTimerId != -1 ) _kill_timer ( _ols_UpdateTimerId ); _ols_UpdateTimerId = -1;
   _ols_UpdateTimerId = _set_timer ( OLS_UPDATE_SYMBOLS_TIME, UpdateTimerCallback, p_active_form.p_window_id );
}
Using the window id as argument to the callback eliminates the need of finding the form.
And 'p_window_id = ols_wid;' in the callback sets the 'scope' properly.
Good luck,
HS2

asandler

  • Senior Community Member
  • Posts: 299
  • Hero Points: 27
Re: Timers question
« Reply #4 on: March 03, 2008, 10:28:46 am »
Thanks hs2. It's a really nice and elegant way to avoid doing _find_formobj(). BUT I am afraid it doesn't solve the problem. The problem is with accessing static variable and as it seems, no matter how you restore active form object, statics remain out of scope.

hs2

  • Senior Community Member
  • Posts: 2737
  • Hero Points: 288
Re: Timers question
« Reply #5 on: March 03, 2008, 12:01:49 pm »
Hi Alexander, I wonder what's causing the scope issue in your case.. Could you post an example showing the problem ? HS2

asandler

  • Senior Community Member
  • Posts: 299
  • Hero Points: 27
Re: Timers question
« Reply #6 on: March 03, 2008, 12:42:15 pm »
@HS2
Sure. I am working on a new version of open_project_file. Here's the relevant portion of the code. See my comments below.

static int opf_tree_entries = 0;
.
.
.
void opf_update_tree( _str pattern )
{
   int idx;

   for (idx = 1; idx <= opf_tree_entries; idx++) {
      if (_TreeGetCaption( idx ) == "") {
         continue;
      }

      if (!opf_string_match( pattern, _TreeGetCaption( idx ), 1 )) {
         _TreeSetInfo( idx, -1, -1, -1, TREENODE_HIDDEN );
      } else {
         _TreeSetInfo( idx, -1, -1, -1, 0 );
      }
   }
}

void opf_timer_cb( int win_id )
{
   int cur_window;

   cur_window = p_window_id;
   p_window_id = win_id;

   opf_update_tree( opf_file_name.p_caption );
   _kill_timer( opf_timer_handle );

   p_window_id = cur_window;
}

void opf_on_key()
{
   key := event2name( last_event( null, true ) );
   opf_file_name.p_caption = opf_file_name.p_caption""key;

   _kill_timer( opf_timer_handle );
   opf_timer_handle = _set_timer( 100, opf_timer_cb, p_active_form.p_window_id );
}

It starts with opf_on_key() setting the timer. Next, callback function opf_timer_cb() called followed by opf_update_tree() call.
I get an error in opf_update_tree() - for (idx = 1; idx <= opf_tree_entries; idx++) { line
It states it doesn't know what's opf_tree_entries, which is a static variable defined and initialized earlier in the code.

If it will help, I'll post the whole file.
Thanks a lot for help!

hs2

  • Senior Community Member
  • Posts: 2737
  • Hero Points: 288
Re: Timers question
« Reply #7 on: March 03, 2008, 01:27:17 pm »
Hmm - looks good so far and should work - strange..
Just a few remarks: 'opf_timer_cb' and 'opf_update_tree' could be 'static'.
You should first stop the timer in the tímer callback before doing anything else.
I can't remember why but I've explicitely specified the tree control in update tree function.
e.g. opf_update_tree: <tree control>._TreeGetCaption()
I'd propose to specify: #pragma option(strict,on) at the beginning of the module. This helps a lot writing correct code !
Sorry, that's not much help at the moment.
Good luck,
HS2

asandler

  • Senior Community Member
  • Posts: 299
  • Hero Points: 27
Re: Timers question
« Reply #8 on: March 03, 2008, 01:44:50 pm »
@HS2
This is really strange, but doing <tree control>._TreeGetCaption() did solve the problem. I am speechless :D
Again, thanks for help.

hs2

  • Senior Community Member
  • Posts: 2737
  • Hero Points: 288
Re: Timers question
« Reply #9 on: March 03, 2008, 01:57:31 pm »
Indeed ! I knew that there was a special reason for doing so, but I couldn't remember.
The reported error seems unrelated to the causing problem - maybe a problem with the Slick-C interpreter ? But this is up to the experts.
HS2

MindprisM

  • Senior Community Member
  • Posts: 127
  • Hero Points: 8
Re: Timers question
« Reply #10 on: July 22, 2013, 11:55:27 am »
SE17

Is there a problem with idx = opf_files._TreeGetNextIndex( idx, "H" );
The call no longer gets hiddens, and its signature shows no param for that.

MindprisM

  • Senior Community Member
  • Posts: 127
  • Hero Points: 8
Re: Timers question
« Reply #11 on: July 22, 2013, 12:16:53 pm »
Fixup for this:

Code: [Select]
static typeless tree_indexes[];
void parse_project( int xml, int index, _str basic_name )
{
   int idx;
   int child;
   int how;
   _str name;

   if (index < 0)
      return;

   idx = index;
   int idx2;

   do {
      if ((_xmlcfg_get_name( xml, idx ) == "F") && (_xmlcfg_get_attribute( xml, idx, "N", "" ) != "")) {
         name = _xmlcfg_get_attribute( xml, idx, "N", "" );
         //fixup+
         int idxx=_TreeAddItem( 0,
                       name,
                       TREE_ADD_AS_CHILD,
                       _pic_doc_w,
                       _pic_doc_w,
                       -1 );
         tree_indexes[tree_indexes._length()]=idxx;
         //fixup-
      }

      child = _xmlcfg_get_first_child( xml, idx );
      if (child >= 0)
         parse_project( xml, child, "" );

      idx2 = idx;
      idx = _xmlcfg_get_next_sibling( xml, idx );
   } while (idx >= 0);
}

void opf_files.on_create()
{
   int xml_id = 0;
   int no_files = 0;
   int i;

   if (preparse_project( &xml_id )) {
      _message_box( "Failed to load project file..." );
      close_form();
   }

   no_files = project_find_files( xml_id, 0 );
   //fixup+
   typeless aa[];
   tree_indexes=aa;
   //fixup-
   parse_project( xml_id, no_files, "" );
   sort_tree( 0 );

   forget_project( xml_id );

   // Workaround for tree font issue. Credit goes to HS2!
   opf_setEditFont( opf_files, opf_tree_font );

   _str font_name = '';
   opf_getEditFont( opf_tree_font, font_name );
   opf_files.p_font_name = font_name;
}

void opf_update_tree( _str pattern ){
  //fixup+
   int idx = 0;
   int x=0;
    for (x = 0; x <= tree_indexes._length()-1; x++) {
      idx=tree_indexes[x];
      if (opf_files._TreeGetCaption( idx ) == "") {
         continue;
      }
      if (!opf_string_match( pattern, opf_files._TreeGetCaption( idx ) )) {
         opf_files._TreeSetInfo( idx, -1, -1, -1, TREENODE_HIDDEN );
      } else {
         opf_files._TreeSetInfo( idx, -1, -1, -1, 0 );
      }
   }
   opf_files._TreeRefresh();
  //fixup-
}