Exemple #1
0
bool Glulxe::init_dispatch() {
	int ix;

	/* Set up the game-ID hook. (This is ifdeffed because not all Glk
	   libraries have this call.) */
#ifdef GI_DISPA_GAME_ID_AVAILABLE
	gidispatch_set_game_id_hook(&get_game_id);
#endif /* GI_DISPA_GAME_ID_AVAILABLE */

	/* Allocate the class hash tables. */
	num_classes = gidispatch_count_classes();
	classes = (classtable_t **)glulx_malloc(num_classes  * sizeof(classtable_t *));
	if (!classes)
		return false;

	for (ix = 0; ix < num_classes; ix++) {
		classes[ix] = new_classtable((glulx_random() % (uint)(101)) + 1);
		if (!classes[ix])
			return false;
	}

	/* Set up the two callbacks. */
	gidispatch_set_object_registry(&classtable_register, &classtable_unregister);
	gidispatch_set_retained_registry(&retained_register, &retained_unregister);

	/* If the library supports autorestore callbacks, set those up too.
	   (These are only used in iosglk, currently.) */
#ifdef GIDISPATCH_AUTORESTORE_REGISTRY
	gidispatch_set_autorestore_registry(&glulxe_array_locate, &glulxe_array_restore);
#endif /* GIDISPATCH_AUTORESTORE_REGISTRY */

	return true;
}
Exemple #2
0
/* git_init_dispatch():
   Set up the class hash tables and other startup-time stuff.
*/
int git_init_dispatch()
{
  int ix;
  
  /* What with one thing and another, this *could* be called more than
     once. We only need to allocate the tables once. */
  if (git_classes)
      return TRUE;
  
  /* Set up the game-ID hook. (This is ifdeffed because not all Glk
     libraries have this call.) */
#ifdef GI_DISPA_GAME_ID_AVAILABLE
  gidispatch_set_game_id_hook(&get_game_id);
#endif /* GI_DISPA_GAME_ID_AVAILABLE */
    
  /* Allocate the class hash tables. */
  num_classes = gidispatch_count_classes();
  git_classes = (classtable_t **)glulx_malloc(num_classes 
    * sizeof(classtable_t *));
  if (!git_classes)
    return FALSE;
    
  for (ix=0; ix<num_classes; ix++) {
    git_classes[ix] = new_classtable((glulx_random() % (glui32)(101)) + 1);
    if (!git_classes[ix])
      return FALSE;
  }
    
  /* Set up the two callbacks. */
  gidispatch_set_object_registry(&glulxe_classtable_register, 
    &glulxe_classtable_unregister);
  gidispatch_set_retained_registry(&glulxe_retained_register, 
    &glulxe_retained_unregister);
  
  return TRUE;
}
Exemple #3
0
static glui32 classes_iter(glk_object_save_t **objs)
{
    classtable_t *ctab;
    classref_t *cref;
    glui32 num_classes;
    glui32 i,j,ct = 0;
    glk_object_save_t *o = NULL, *cur;

    window_t  *win;
    stream_t *str_cur = glk_stream_get_current();

    if (!objs)
        return 0;

    *objs = NULL;

    num_classes = gidispatch_count_classes();
    ct = 0;
    for (i = 0; i < num_classes; i++) { // iterate everything quickly
        if ((ctab = classes[i])) {
            for (j = 0; j < CLASSHASH_SIZE; j++) {
                cref = ctab->bucket[j];
                for ( ; cref; cref = cref->next) {
                    if (i == 0) {
                        window_t *win = (window_t *)cref->obj;
                        win->store = 0;
                    } else if (i == 1) {
                        stream_t *str = (stream_t *)cref->obj;
                        str->store = 0;
                    }
                    ct++;
                }
            }
        }
    }
    if (!ct) return 0;

    // add entries for windows with styles/pair info + the two general styles
    win = NULL;
    while ((win = gli_window_iterate_backward(win, NULL))) {
        if (win->type == wintype_TextBuffer || win->type == wintype_TextGrid
                || win->type == wintype_Pair || win->type == wintype_Graphics)
            ct++;
    }
    // leave off the last 2 in the event of no styles in use!
    if (gli_window_has_stylehints())
        ct += 2;

    o = glulx_malloc(sizeof(glk_object_save_t) * ct);
    if (!o) return 0;

    ct = 0;
    win = NULL;
    while ((win = gli_window_iterate_backward(win, NULL))) {
        cur = o + ct;
        memset(cur, 0, sizeof(glk_object_save_t));

        cur->type = gidisp_Class_Window;
        cur->id = classes_find_id_for_object(0, win);

        saveWin(win, &cur->obj.win);
        //!!!cur->obj.win = *win;
        win->store = TRUE;
        cur->iscurrent = FALSE; //(win == win_cur);
        classes_normalize_pointers(cur);

        ct++;
        // get stream for window
        if ((win->type == wintype_TextBuffer) || (win->type == wintype_TextGrid)) {

            // write STREAM chunk
            cur = o + ct;
            memset(cur, 0, sizeof(glk_object_save_t));

            cur->type = gidisp_Class_Stream;
            cur->id = classes_find_id_for_object(1, win->str);
            //!!!cur->obj.str = *win->str;

            saveStream(win->str, &cur->obj.str);
            win->str->store = TRUE;
            cur->iscurrent = (win->str == str_cur);
            classes_normalize_pointers(cur);
            ct++;

            // write STYLE chunk
            cur = o + ct;
            memset(cur, 0, sizeof(glk_object_save_t));

            cur->type = type_Style;
            cur->id = classes_find_id_for_object(0, win);

            GLK_STYLE_HINTS hints[style_NUMSTYLES];

            gli_window_get_stylehints(win, hints);
            memcpy(cur->obj.style, hints, sizeof(GLK_STYLE_HINTS) * style_NUMSTYLES);

            ct++;
        } else if (win->type == wintype_Pair) {
            window_pair_t *pairwin = (window_pair_t*)win->data;

            // write PAIR chunk
            cur = o + ct;
            memset(cur, 0, sizeof(glk_object_save_t));

            cur->type = type_Pair;
            cur->id = classes_find_id_for_object(0, win);

            //!!!cur->obj.pair = *((window_pair_t *)win->data);
            saveWinPair(pairwin, &cur->obj.pair);

            // set the children to their ids so we can find the pair on reload
            cur->obj.pair.child1 = classes_find_id_for_object(gidisp_Class_Window, pairwin->child1);
            cur->obj.pair.child2 = classes_find_id_for_object(gidisp_Class_Window, pairwin->child2);
            //!!!classes_normalize_pointers(cur);

            ct++;
        } else if (win->type == wintype_Graphics) {
            // write GRAPHICS chunk
            cur = o + ct;
            memset(cur, 0, sizeof(glk_object_save_t));

            cur->type = type_Graphics;
            cur->id = classes_find_id_for_object(0, win);

            saveWinGfx((window_graphics_t *)win->data, &cur->obj.gfx);
            ct++;
        }
    }
    // now, iterate other classes; window streams should have already been accounted for, but we check this
    for (i = 0; i < num_classes; i++) {
        if ((ctab = classes[i])) {
            for (j = 0; j < CLASSHASH_SIZE; j++) {
                cref = ctab->bucket[j];
                for ( ; cref; cref = cref->next) {
                    if (i == 0) { // windows
                        window_t *win = (window_t *)cref->obj;

                        if (!win->store) {
                            cur = o + ct;
                            memset(cur, 0, sizeof(glk_object_save_t));

                            cur->type = i;
                            cur->id = cref->id;
                        }
                    } else {
                        if (i == 1) { // streams
                            stream_t *str = (stream_t *)cref->obj;

                            if (!str->store) {
                                cur = o + ct;
                                memset(cur, 0, sizeof(glk_object_save_t));
                                cur->type = i;
                                cur->id = cref->id;

                                //!!!cur->obj.str = *str;
                                saveStream(str, &cur->obj.str);
                                cur->iscurrent = (str == str_cur);
                                classes_normalize_pointers(cur);
                                ct++;
                            }
                        } else if (i == 2) {
                            fileref_t *fref = (fileref_t *)cref->obj;

                            cur = o + ct;
                            memset(cur, 0, sizeof(glk_object_save_t));
                            cur->type = i;
                            cur->id = cref->id;

                            //!!!cur->obj.fref = *fref;
                            saveFRef(fref, &cur->obj.fref);
                            classes_normalize_pointers(cur);
                            ct++;
                        } else if (i == 3) { // won't happen here
                            ;
                        }
                    }
                }
            }
        }
    }
    // 2 general styles

    if (gli_window_has_stylehints()) {
        GLK_STYLE_HINTS hints[style_NUMSTYLES];

        cur = o + ct;
        memset(cur, 0, sizeof(glk_object_save_t));
        cur->type = type_Style;
        cur->id = STYLEHINT_TEXT_BUFFER;

        gli_window_get_stylehints((winid_t)STYLEHINT_TEXT_BUFFER, hints);

        memcpy(cur->obj.style, hints, sizeof(GLK_STYLE_HINTS) * style_NUMSTYLES);
        ct++;

        cur = o + ct;
        memset(cur, 0, sizeof(glk_object_save_t));
        cur->type = type_Style;
        cur->id = STYLEHINT_TEXT_GRID;

        gli_window_get_stylehints((winid_t)STYLEHINT_TEXT_GRID, hints);

        memcpy(cur->obj.style, hints, sizeof(GLK_STYLE_HINTS) * style_NUMSTYLES);
        ct++;
    }

    *objs = o;
    return ct;
}