… | |
… | |
345 | |
345 | |
346 | { |
346 | { |
347 | archetype *head = parts.front ().first; |
347 | archetype *head = parts.front ().first; |
348 | |
348 | |
349 | // check that all archetypes belong to the same object or are heads |
349 | // check that all archetypes belong to the same object or are heads |
350 | for (AUTODECL (p, parts.begin ()); p != parts.end (); ++p) |
350 | for (auto (p, parts.begin ()); p != parts.end (); ++p) |
351 | { |
351 | { |
352 | archetype *at = p->first; |
352 | archetype *at = p->first; |
353 | |
353 | |
354 | if (at->head != head && at->head) |
354 | if (at->head != head && at->head) |
355 | { |
355 | { |
… | |
… | |
377 | overwrite (head, parts.front ().second); |
377 | overwrite (head, parts.front ().second); |
378 | head->tail_x = 0; |
378 | head->tail_x = 0; |
379 | head->tail_y = 0; |
379 | head->tail_y = 0; |
380 | |
380 | |
381 | // link into list of heads, if not already there |
381 | // link into list of heads, if not already there |
382 | if (!head->next) |
382 | if (!head->linked) |
383 | { |
383 | { |
|
|
384 | head->linked = true; |
384 | head->next = first_archetype; |
385 | head->next = first_archetype; |
385 | first_archetype = head; |
386 | first_archetype = head; |
386 | } |
387 | } |
387 | |
388 | |
388 | // reassemble new chain |
389 | // reassemble new chain |
389 | archetype *prev = head; |
390 | archetype *prev = head; |
390 | for (AUTODECL (p, parts.begin () + 1); p != parts.end (); ++p) |
391 | for (auto (p, parts.begin () + 1); p != parts.end (); ++p) |
391 | { |
392 | { |
392 | archetype *at = p->first; |
393 | archetype *at = p->first; |
393 | overwrite (at, p->second); |
394 | overwrite (at, p->second); |
394 | |
395 | |
395 | if (at->clone.x > head->tail_x) head->tail_x = at->clone.x; |
396 | if (at->clone.x > head->tail_x) head->tail_x = at->clone.x; |
… | |
… | |
405 | } |
406 | } |
406 | |
407 | |
407 | return true; |
408 | return true; |
408 | |
409 | |
409 | fail: |
410 | fail: |
410 | for (AUTODECL (p, parts.begin ()); p != parts.end (); ++p) |
411 | for (auto (p, parts.begin ()); p != parts.end (); ++p) |
411 | p->second->destroy (true); |
412 | p->second->destroy (true); |
412 | |
413 | |
413 | return false; |
414 | return false; |
414 | } |
415 | } |
415 | |
416 | |
… | |
… | |
530 | |
531 | |
531 | return arch_to_object (at); |
532 | return arch_to_object (at); |
532 | } |
533 | } |
533 | |
534 | |
534 | /* |
535 | /* |
535 | * Hash-function used by the arch-hashtable. |
|
|
536 | */ |
|
|
537 | |
|
|
538 | unsigned long |
|
|
539 | hasharch (const char *str, int tablesize) |
|
|
540 | { |
|
|
541 | unsigned long hash = 0; |
|
|
542 | unsigned int i = 0; |
|
|
543 | const char *p; |
|
|
544 | |
|
|
545 | /* use the one-at-a-time hash function, which supposedly is |
|
|
546 | * better than the djb2-like one used by perl5.005, but |
|
|
547 | * certainly is better then the bug used here before. |
|
|
548 | * see http://burtleburtle.net/bob/hash/doobs.html |
|
|
549 | */ |
|
|
550 | for (p = str; i < MAXSTRING && *p; p++, i++) |
|
|
551 | { |
|
|
552 | hash += *p; |
|
|
553 | hash += hash << 10; |
|
|
554 | hash ^= hash >> 6; |
|
|
555 | } |
|
|
556 | |
|
|
557 | hash += hash << 3; |
|
|
558 | hash ^= hash >> 11; |
|
|
559 | hash += hash << 15; |
|
|
560 | |
|
|
561 | return hash % tablesize; |
|
|
562 | } |
|
|
563 | |
|
|
564 | /* |
|
|
565 | * Finds, using the hashtable, which archetype matches the given name. |
536 | * Finds, using the hashtable, which archetype matches the given name. |
566 | * returns a pointer to the found archetype, otherwise NULL. |
537 | * returns a pointer to the found archetype, otherwise NULL. |
567 | */ |
538 | */ |
568 | archetype * |
539 | archetype * |
569 | archetype::find (const char *name) |
540 | archetype::find (const char *name) |
570 | { |
541 | { |
571 | if (!name) |
542 | if (!name) |
572 | return 0; |
543 | return 0; |
573 | |
544 | |
574 | AUTODECL (i, ht.find (name)); |
545 | auto (i, ht.find (name)); |
575 | |
546 | |
576 | if (i == ht.end ()) |
547 | if (i == ht.end ()) |
577 | return 0; |
548 | return 0; |
578 | else |
549 | else |
579 | return i->second; |
550 | return i->second; |