ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/common/arch.C
(Generate patch)

Comparing deliantra/server/common/arch.C (file contents):
Revision 1.72 by root, Wed Apr 2 11:13:51 2008 UTC vs.
Revision 1.73 by root, Sun Apr 20 00:44:12 2008 UTC

1/* 1/*
2 * This file is part of Deliantra, the Roguelike Realtime MMORPG. 2 * This file is part of Deliantra, the Roguelike Realtime MMORPG.
3 * 3 *
4 * Copyright (©) 2005,2006,2007 Marc Alexander Lehmann / Robin Redeker / the Deliantra team 4 * Copyright (©) 2005,2006,2007,2008 Marc Alexander Lehmann / Robin Redeker / the Deliantra team
5 * Copyright (©) 2002,2007 Mark Wedel & Crossfire Development Team 5 * Copyright (©) 2002,2007 Mark Wedel & Crossfire Development Team
6 * Copyright (©) 1992,2007 Frank Tore Johansen 6 * Copyright (©) 1992,2007 Frank Tore Johansen
7 * 7 *
8 * Deliantra is free software: you can redistribute it and/or modify 8 * Deliantra is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by 9 * it under the terms of the GNU General Public License as published by
28#include <loader.h> 28#include <loader.h>
29 29
30#include <tr1/functional> 30#include <tr1/functional>
31#include <tr1/unordered_map> 31#include <tr1/unordered_map>
32 32
33/* The naming of these functions is really poor - they are all
34 * pretty much named '.._arch_...', but they may more may not
35 * return archetypes. Some make the arch_to_object call, and thus
36 * return an object. Perhaps those should be called 'archob' functions
37 * to denote they return an object derived from the archetype.
38 * MSW 2003-04-29
39 */
40
41archetype *loading_arch; // ugly flag to object laoder etc. to suppress/request special processing 33archetype *loading_arch; // ugly flag to object laoder etc. to suppress/request special processing
34archetype *archetype::empty;
42 35
43// the hashtable 36// the hashtable
44typedef std::tr1::unordered_map 37typedef std::tr1::unordered_map
45 < 38 <
46 const char *, 39 const char *,
50 slice_allocator< std::pair<const char *const, arch_ptr> > 43 slice_allocator< std::pair<const char *const, arch_ptr> >
51 > HT; 44 > HT;
52 45
53static HT ht (5000); 46static HT ht (5000);
54archvec archetypes; 47archvec archetypes;
48
49// the vector of other_arch references to be resolved
50static std::vector< std::pair<arch_ptr *, shstr> > postponed_arch_ref;
51// the vector of loaded but not yet committed archetypes
52static std::vector<archetype *> postponed_arch;
55 53
56/** 54/**
57 * GROS - This function retrieves an archetype given the name that appears 55 * GROS - This function retrieves an archetype given the name that appears
58 * during the game (for example, "writing pen" instead of "stylus"). 56 * during the game (for example, "writing pen" instead of "stylus").
59 * It does not use the hashtable system, but browse the whole archlist each time. 57 * It does not use the hashtable system, but browse the whole archlist each time.
276 return 0; 274 return 0;
277} 275}
278 276
279archetype::archetype (const char *name) 277archetype::archetype (const char *name)
280{ 278{
281 stub = true;
282 arch = this; 279 arch = this;
283 this->archname = this->name = this->name_pl = name; 280 this->archname = this->name = this->name_pl = name;
284} 281}
285 282
286archetype::~archetype () 283archetype::~archetype ()
323 else 320 else
324 return i->second; 321 return i->second;
325} 322}
326 323
327archetype * 324archetype *
328archetype::get (const char *name)
329{
330 if (!name)
331 {
332 LOG (llevError, "null archetype requested\n");
333 name = "(null)";
334 }
335
336 if (loading_arch && !strcmp (&loading_arch->archname, name))
337 return loading_arch;
338
339 archetype *at = find (name);
340
341 if (!at)
342 {
343 at = new archetype (name);
344 at->link ();
345 }
346
347 return at;
348}
349
350archetype *
351archetype::read (object_thawer &f) 325archetype::read (object_thawer &f)
352{ 326{
353 assert (f.kw == KW_object); 327 assert (f.kw == KW_object);
354 328
355 std::vector<archetype *> parts; 329 std::vector<archetype *> parts;
356 330
357 coroapi::cede_to_tick (); 331 coroapi::cede_to_tick ();
358 332
359 for (;;) 333 for (;;)
360 { 334 {
361 // the archetype might have been referenced earlier
362 // so try to find an existing stub archetype first
363 archetype *at = find (f.get_str ()); 335 archetype *at = new archetype (f.get_str ());
364
365 if (!at || !at->stub)
366 at = new archetype (f.get_str ());
367 336
368 f.next (); 337 f.next ();
369 338
370#if 0 339#if 0
371 // implementing it here in the server does neither allow multiple inheritence 340 // implementing it here in the server does neither allow multiple inheritence
434 &new_part->archname, &((archetype *)old_part->head_ ())->archname); 403 &new_part->archname, &((archetype *)old_part->head_ ())->archname);
435 goto fail; 404 goto fail;
436 } 405 }
437 } 406 }
438 407
439 // deactivate existing archetype
440 for (archetype *at = old_head; at; at = (archetype *)at->more)
441 at->unlink ();
442
443 // assemble new chain 408 // assemble new chain
444 new_head->min_x = new_head->max_x = new_head->x; 409 new_head->min_x = new_head->max_x = new_head->x;
445 new_head->min_y = new_head->max_y = new_head->y; 410 new_head->min_y = new_head->max_y = new_head->y;
446 411
447 archetype *less = new_head; 412 archetype *less = new_head;
465 at->head = new_head; 430 at->head = new_head;
466 less->more = at; 431 less->more = at;
467 less = at; 432 less = at;
468 } 433 }
469 434
470 // now activate it 435 postponed_arch.insert (postponed_arch.end (), parts.begin (), parts.end ());
471 for (auto (p, parts.begin ()); p != parts.end (); ++p)
472 {
473 archetype *at = *p;
474 at->stub = false;
475 at->link ();
476 }
477 436
478 return new_head; 437 return new_head;
479 } 438 }
480 439
481fail: 440fail:
483 (*p)->destroy (true); 442 (*p)->destroy (true);
484 443
485 return 0; 444 return 0;
486} 445}
487 446
488/*
489 * Initialize global archtype pointers:
490 */
491void 447void
492init_archetype_pointers () 448archetype::postpone_arch_ref (arch_ptr &ref, const_utf8_string other_arch)
493{ 449{
494 ring_arch = archetype::find ("ring"); 450 ref = 0;
495 amulet_arch = archetype::find ("amulet"); 451 postponed_arch_ref.push_back (std::pair<arch_ptr *, shstr>(&ref, shstr (other_arch)));
496 staff_arch = archetype::find ("staff"); 452}
497 crown_arch = archetype::find ("crown"); 453
498 empty_archetype = archetype::find ("empty_archetype"); 454void
455archetype::commit_load ()
456{
457 // unlink old archetypes and link in new ones */
458 for (auto (p, postponed_arch.begin ()); p != postponed_arch.end (); ++p)
459 {
460 archetype *at = *p;
461
462 if (archetype *old = find (at->archname))
463 old->unlink ();
464
465 at->link ();
466 }
467
468 postponed_arch.clear ();
469
470 // now resolve arch references
471 for (auto (p, postponed_arch_ref.begin ()); p != postponed_arch_ref.end (); ++p)
472 {
473 arch_ptr *ap = p->first;
474 archetype *at = find (p->second);
475
476 if (!at)
477 LOG (llevError, "unable to resolve postponed arch reference to '%s'", &p->second);
478
479 *ap = at;
480 }
481
482 postponed_arch_ref.clear ();
483
484 empty = find (shstr_empty_archetype);
499} 485}
500 486
501/* 487/*
502 * Creates and returns a new object which is a copy of the given archetype. 488 * Creates and returns a new object which is a copy of the given archetype.
503 * This function returns NULL on failure. 489 * This function returns NULL on failure.

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines