Beispiel #1
0
void THDRegisterCudaStream(cudaStream_t stream) {
  streamIdMap.emplace(stream, nextStreamId++);
}
Beispiel #2
0
namespace pyston {

using namespace pyston::assembler;

// TODO not right place for this...
int64_t ICInvalidator::version() {
    return cur_version;
}

void ICInvalidator::addDependent(ICSlotInfo* entry_info) {
    dependents.insert(entry_info);
}

void ICInvalidator::invalidateAll() {
    cur_version++;
    for (std::unordered_set<ICSlotInfo*>::iterator it = dependents.begin(), end = dependents.end();
            it != end; ++it) {
        (*it)->clear();
    }
    dependents.clear();
}



void ICSlotInfo::clear() {
    ic->clear(this);
}

ICSlotRewrite::ICSlotRewrite(ICInfo* ic, const char* debug_name) : ic(ic), debug_name(debug_name) {
    buf = (uint8_t*)malloc(ic->getSlotSize());
    assembler = new Assembler(buf, ic->getSlotSize());
    assembler->nop();

    if (VERBOSITY()) printf("starting %s icentry\n", debug_name);
}

ICSlotRewrite::~ICSlotRewrite() {
    delete assembler;
    free(buf);
}

void ICSlotRewrite::commit(uint64_t decision_path, CommitHook *hook) {
    bool still_valid = true;
    for (int i = 0; i < dependencies.size(); i++) {
        int orig_version = dependencies[i].second;
        ICInvalidator *invalidator = dependencies[i].first;
        if (orig_version != invalidator->version()) {
            still_valid = false;
            break;
        }
    }
    if (!still_valid) {
        if (VERBOSITY()) printf("not committing %s icentry since a dependency got updated before commit\n", debug_name);
        return;
    }

    ICSlotInfo *ic_entry = ic->pickEntryForRewrite(decision_path, debug_name);
    if (ic_entry == NULL)
        return;

    for (int i = 0; i < dependencies.size(); i++) {
        ICInvalidator *invalidator = dependencies[i].first;
        invalidator->addDependent(ic_entry);
    }

    uint8_t* slot_start = (uint8_t*)ic->start_addr + ic_entry->idx * ic->getSlotSize();
    uint8_t* continue_point = (uint8_t*)ic->continue_addr;

    hook->finishAssembly(continue_point - slot_start);

    assert(assembler->isExactlyFull());

    //if (VERBOSITY()) printf("Commiting to %p-%p\n", start, start + ic->slot_size);
    memcpy(slot_start, buf, ic->getSlotSize());

    llvm::sys::Memory::InvalidateInstructionCache(slot_start, ic->getSlotSize());
}

void ICSlotRewrite::addDependenceOn(ICInvalidator &invalidator) {
    dependencies.push_back(std::make_pair(&invalidator, invalidator.version()));
}

int ICSlotRewrite::getSlotSize() {
    return ic->getSlotSize();
}

int ICSlotRewrite::getFuncStackSize() {
    return ic->stack_info.stack_size;
}

int ICSlotRewrite::getScratchRbpOffset() {
    assert(ic->stack_info.has_scratch);
    assert(ic->stack_info.scratch_bytes);
    return ic->stack_info.scratch_rbp_offset;
}

int ICSlotRewrite::getScratchBytes() {
    assert(ic->stack_info.has_scratch);
    assert(ic->stack_info.scratch_bytes);
    return ic->stack_info.scratch_bytes;
}

assembler::GenericRegister ICSlotRewrite::returnRegister() {
    return ic->return_register;
}



ICSlotRewrite* ICInfo::startRewrite(const char* debug_name) {
    return new ICSlotRewrite(this, debug_name);
}

ICSlotInfo* ICInfo::pickEntryForRewrite(uint64_t decision_path, const char* debug_name) {
    for (int i = 0; i < getNumSlots(); i++) {
        SlotInfo &sinfo = slots[i];
        if (!sinfo.is_patched) {
            if (VERBOSITY()) {
                printf("committing %s icentry to unused slot %d at %p\n", debug_name, i, start_addr);
            }

            sinfo.is_patched = true;
            sinfo.decision_path = decision_path;
            return &sinfo.entry;
        }
    }

    for (int i = 0; i < getNumSlots(); i++) {
        SlotInfo &sinfo = slots[i];
        if (sinfo.is_patched && sinfo.decision_path != decision_path) {
            continue;
        }

        if (VERBOSITY()) {
            printf("committing %s icentry to in-use slot %d at %p\n", debug_name, i, start_addr);
        }

        sinfo.is_patched = true;
        sinfo.decision_path = decision_path;
        return &sinfo.entry;
    }
    if (VERBOSITY()) printf("not committing %s icentry since it is not compatible (%lx)\n", debug_name, decision_path);
    return NULL;
}



ICInfo::ICInfo(void* start_addr, void* continue_addr, StackInfo stack_info, int num_slots, int slot_size, llvm::CallingConv::ID calling_conv, const std::unordered_set<int> &live_outs, assembler::GenericRegister return_register) : stack_info(stack_info), num_slots(num_slots), slot_size(slot_size), calling_conv(calling_conv), live_outs(live_outs.begin(), live_outs.end()), return_register(return_register), start_addr(start_addr), continue_addr(continue_addr) {
    for (int i = 0; i < num_slots; i++) {
        slots.push_back(SlotInfo(this, i));
    }
}

static std::unordered_map<void*, ICInfo*> ics_by_return_addr;
void registerCompiledPatchpoint(uint8_t* start_addr, PatchpointSetupInfo* pp, StackInfo stack_info, std::unordered_set<int> live_outs) {
    int size = pp->totalSize();
    uint8_t* end_addr = start_addr + size;
    void* slowpath_addr = end_addr;

    uint8_t* rtn_addr;

    assembler::GenericRegister return_register;
    assert(pp->getCallingConvention() == llvm::CallingConv::C || pp->getCallingConvention() == llvm::CallingConv::PreserveAll);
    if (pp->hasReturnValue()) {
        static const int DWARF_RAX = 0;
        // It's possible that the return value doesn't get used, in which case
        // we can avoid copying back into RAX at the end
        if (live_outs.count(DWARF_RAX)) {
            live_outs.erase(DWARF_RAX);
        }

        // TODO we only need to do this if 0 was in live_outs, since if it wasn't, that indicates
        // the return value won't be used and we can optimize based on that.
        return_register = assembler::RAX;
    }

    if (pp->getCallingConvention() != llvm::CallingConv::C) {
        uint8_t* slowpath_start = start_addr + pp->num_slots * pp->slot_size;
        rtn_addr = initializePatchpoint2(start_addr, slowpath_start, (uint8_t*)end_addr, stack_info, live_outs);
    } else {
        //for (int regnum : live_outs) {
            //// LLVM has a bug where it incorrectly determines the set of liveouts;
            //// so far it only seems to add additional ones to the set, which should 
            //// hopefully be safe.
            //// Otherwise, I'd like to test here that it's only the registers
            //// that we'd expect to be saved...
            //ASSERT(regnum == 0 || regnum == 3 || regnum == 6 || regnum == 12 || regnum == 13 || regnum == 14 || regnum == 15 || regnum == 7, "%d", regnum);
        //}

        initializePatchpoint(start_addr, size);
        rtn_addr = end_addr;
    }

    // we can let the user just slide down the nop section, but instead
    // emit jumps to the end.
    // Not sure if this is worth it or not?
    for (int i = 0; i < pp->num_slots; i++) {
        uint8_t* start = start_addr + i * pp->slot_size;
        //std::unique_ptr<MCWriter> writer(createMCWriter(start, pp->slot_size * (pp->num_slots - i), 0));
        //writer->emitNop();
        //writer->emitGuardFalse();

        std::unique_ptr<Assembler> writer(new Assembler(start, pp->slot_size));
        writer->nop();
        //writer->trap();
        writer->jmp(JumpDestination::fromStart(pp->slot_size * (pp->num_slots - i)));
    }

    ics_by_return_addr[rtn_addr] = new ICInfo(start_addr, end_addr, stack_info, pp->num_slots, pp->slot_size, pp->getCallingConvention(), live_outs, return_register);
}

ICInfo* getICInfo(void* rtn_addr) {
    std::unordered_map<void*, ICInfo*>::iterator it = ics_by_return_addr.find(rtn_addr);
    if (it == ics_by_return_addr.end())
        return NULL;
    return it->second;
}

void ICInfo::clear(ICSlotInfo* icentry) {
    assert(icentry);

    uint8_t* start = (uint8_t*)start_addr + icentry->idx * getSlotSize();

    if (VERBOSITY()) printf("clearing patchpoint %p, slot at %p\n", start_addr, start);

    std::unique_ptr<Assembler> writer(new Assembler(start, getSlotSize()));
    writer->nop();
    writer->jmp(JumpDestination::fromStart(getSlotSize()));
    //std::unique_ptr<MCWriter> writer(createMCWriter(start, getSlotSize(), 0));
    //writer->emitNop();
    //writer->emitGuardFalse();

    //writer->endWithSlowpath();
    llvm::sys::Memory::InvalidateInstructionCache(start, getSlotSize());
}

}
Beispiel #3
0
		Obj * get(const Util::StringIdentifier & id)const{
			const auto it = map_idToObj.find(id);
			return it==map_idToObj.end() ? nullptr : it->second.get();
		}
Beispiel #4
0
 bool is_member(std::string name)
 {
     return stringTextureMap.find(name) != std::end(name);
 }
 inline const int index(const W& word) {
   return (word_idx.find(word) == word_idx.end()) ? 0 : word_idx[word];
 }
Beispiel #6
0
void BakerCLI::bakeFile(QUrl inputUrl, const QString& outputPath, const QString& type) {

    // if the URL doesn't have a scheme, assume it is a local file
    if (inputUrl.scheme() != "http" && inputUrl.scheme() != "https" && inputUrl.scheme() != "ftp" && inputUrl.scheme() != "file") {
        inputUrl = QUrl::fromLocalFile(inputUrl.toString());
    }

    qDebug() << "Baking file type: " << type;

    static const QString MODEL_EXTENSION { "fbx" };
    static const QString SCRIPT_EXTENSION { "js" };

    // check what kind of baker we should be creating
    bool isFBX = type == MODEL_EXTENSION;
    bool isScript = type == SCRIPT_EXTENSION;

    // If the type doesn't match the above, we assume we have a texture, and the type specified is the
    // texture usage type (albedo, cubemap, normals, etc.)
    auto url = inputUrl.toDisplayString();
    auto idx = url.lastIndexOf('.');
    auto extension = idx >= 0 ? url.mid(idx + 1).toLower() : "";
    bool isSupportedImage = QImageReader::supportedImageFormats().contains(extension.toLatin1());

    _outputPath = outputPath;

    // create our appropiate baker
    if (isFBX) {
        _baker = std::unique_ptr<Baker> {
            new FBXBaker(inputUrl,
                         []() -> QThread* { return Oven::instance().getNextWorkerThread(); },
                         outputPath)
        };
        _baker->moveToThread(Oven::instance().getNextWorkerThread());
    } else if (isScript) {
        _baker = std::unique_ptr<Baker> { new JSBaker(inputUrl, outputPath) };
        _baker->moveToThread(Oven::instance().getNextWorkerThread());
    } else if (isSupportedImage) {
        static const std::unordered_map<QString, image::TextureUsage::Type> STRING_TO_TEXTURE_USAGE_TYPE_MAP {
            { "default", image::TextureUsage::DEFAULT_TEXTURE },
            { "strict", image::TextureUsage::STRICT_TEXTURE },
            { "albedo", image::TextureUsage::ALBEDO_TEXTURE },
            { "normal", image::TextureUsage::NORMAL_TEXTURE },
            { "bump", image::TextureUsage::BUMP_TEXTURE },
            { "specular", image::TextureUsage::SPECULAR_TEXTURE },
            { "metallic", image::TextureUsage::METALLIC_TEXTURE },
            { "roughness", image::TextureUsage::ROUGHNESS_TEXTURE },
            { "gloss", image::TextureUsage::GLOSS_TEXTURE },
            { "emissive", image::TextureUsage::EMISSIVE_TEXTURE },
            { "cube", image::TextureUsage::CUBE_TEXTURE },
            { "occlusion", image::TextureUsage::OCCLUSION_TEXTURE },
            { "scattering", image::TextureUsage::SCATTERING_TEXTURE },
            { "lightmap", image::TextureUsage::LIGHTMAP_TEXTURE },
        };

        auto it = STRING_TO_TEXTURE_USAGE_TYPE_MAP.find(type);
        if (it == STRING_TO_TEXTURE_USAGE_TYPE_MAP.end()) {
            qCDebug(model_baking) << "Unknown texture usage type:" << type;
            QCoreApplication::exit(OVEN_STATUS_CODE_FAIL);
        }
        _baker = std::unique_ptr<Baker> { new TextureBaker(inputUrl, it->second, outputPath) };
        _baker->moveToThread(Oven::instance().getNextWorkerThread());
    } else {
        qCDebug(model_baking) << "Failed to determine baker type for file" << inputUrl;
        QCoreApplication::exit(OVEN_STATUS_CODE_FAIL);
        return;
    }

    // invoke the bake method on the baker thread
    QMetaObject::invokeMethod(_baker.get(), "bake");

    // make sure we hear about the results of this baker when it is done
    connect(_baker.get(), &Baker::finished, this, &BakerCLI::handleFinishedBaker);
}
Beispiel #7
0
intptr_t CustomMemFree(void* allocator, void* pointer)
{
	intptr_t retval = g_origMemFree(allocator, pointer);

	/*if (pointer != nullptr && *g_unsafePointerLoc)
	{
		size_t allocSize = 0;

		if (g_unsafeStack.size() == 0)
		{
			{
				std::unique_lock<std::mutex> lock(g_allocMutex);

				auto it = g_allocData.find(pointer);

				if (it != g_allocData.end())
				{
					allocSize = it->second;
					g_allocData.erase(it);
				}
			}

			if (**(void***)g_unsafePointerLoc >= pointer && **(void***)g_unsafePointerLoc < ((char*)pointer + allocSize))
			{
				std::vector<uintptr_t> stackList(96);

				uintptr_t* stack = (uintptr_t*)_AddressOfReturnAddress();

				for (int i = 0; i < stackList.size(); i++)
				{
					stackList[i] = stack[i];
				}

				g_unsafeStack = stackList;
			}
		}

	}*/

	if (/*!g_didLevelFree && */pointer != nullptr)
	{
		//std::unique_lock<std::mutex> lock(g_allocMutex);
		EnterCriticalSection(&g_allocCS);

		uintptr_t ptr = (uintptr_t)pointer;

		auto it = g_allocData.find(ptr);

		if (it != g_allocData.end())
		{
			size_t allocSize = it->second;

			g_allocStuff.erase({ ptr, allocSize });

			if (allocSize >= 8)
			{
				if (*(uintptr_t*)ptr == 0x141826A10)
				{
					uintptr_t* stack = (uintptr_t*)_AddressOfReturnAddress();
					stack += (32 / 8);

					std::array<uintptr_t, 16> stacky;
					memcpy(stacky.data(), stack, 16 * 8);

					{
						g_freeThings.insert({ ptr, { allocSize, stacky } });
					}
				}
			}

			/*static char* location = hook::pattern("4C 8D 0D ? ? ? ? 48 89 01 4C 89 81 80 00 00").count(1).get(0).get<char>(3);
			static char** g_collectionRoot = (char**)(location + *(int32_t*)location + 4);

			for (int i = 0; i < 0x950; i++)
			{
				if (g_collectionRoot[i])
				{
					void* baad = *(void**)(g_collectionRoot[i] + 32);

					if (baad >= pointer && baad < ((char*)pointer + allocSize))
					{
						atArray<char>* array = (atArray<char>*)(g_collectionRoot[i] + 128);

						trace("freed collection %s (%p-%p)\n", &array->Get(0), pointer, allocSize + (char*)pointer);

						uintptr_t* stack = (uintptr_t*)_AddressOfReturnAddress();
						stack += (32 / 8);

						for (int i = 0; i < 16; i++)
						{
							trace("stack: %p\n", stack[i]);
						}
					}
				}
			}*/



			/*if (g_inLevelFree)
			{
			if (allocSize != -1)
			{
			int stackIdx = g_stackIdx++;

			std::vector<uintptr_t> stackList(96);

			uintptr_t* stack = (uintptr_t*)_AddressOfReturnAddress();

			for (int i = 0; i < stackList.size(); i++)
			{
			stackList[i] = stack[i];
			}

			g_stacks[stackIdx] = stackList;

			trace("level free: %p-%p - stack idx: %d\n", pointer, (char*)pointer + allocSize, stackIdx);
			}
			}*/

			g_allocData.erase(it);
		}

		LeaveCriticalSection(&g_allocCS);
	}

	return retval;
}
Beispiel #8
0
        void UpdateAI(uint32 diff) override
        {
            //Check if we have a target
            if (!UpdateVictim())
            {
                //No target so we'll use this section to do our random wispers instance wide
                //WisperTimer
                if (WisperTimer <= diff)
                {
                    Map* map = me->GetMap();
                    if (!map->IsDungeon())
                        return;

                    //Play random sound to the zone
                    Map::PlayerList const &PlayerList = map->GetPlayers();

                    if (!PlayerList.isEmpty())
                    {
                        for (Map::PlayerList::const_iterator itr = PlayerList.begin(); itr != PlayerList.end(); ++itr)
                        {
                            if (Player* pPlr = itr->GetSource())
                                pPlr->PlayDirectSound(RANDOM_SOUND_WHISPER, pPlr);
                        }
                    }

                    //One random wisper every 90 - 300 seconds
                    WisperTimer = urand(90000, 300000);
                } else WisperTimer -= diff;

                return;
            }

            me->SetTarget(ObjectGuid::Empty);

            uint32 currentPhase = instance->GetData(DATA_CTHUN_PHASE);
            if (currentPhase == PHASE_CTHUN_STOMACH || currentPhase == PHASE_CTHUN_WEAK)
            {
                // EyeTentacleTimer
                if (EyeTentacleTimer <= diff)
                {
                    //Spawn the 8 Eye Tentacles in the corret spots
                    SpawnEyeTentacle(0, 20);                //south
                    SpawnEyeTentacle(10, 10);               //south west
                    SpawnEyeTentacle(20, 0);                //west
                    SpawnEyeTentacle(10, -10);              //north west

                    SpawnEyeTentacle(0, -20);               //north
                    SpawnEyeTentacle(-10, -10);             //north east
                    SpawnEyeTentacle(-20, 0);               // east
                    SpawnEyeTentacle(-10, 10);              // south east

                    EyeTentacleTimer = 30000; // every 30sec in phase 2
                } else EyeTentacleTimer -= diff;
            }

            switch (currentPhase)
            {
                //Transition phase
                case PHASE_CTHUN_TRANSITION:
                    //PhaseTimer
                    if (PhaseTimer <= diff)
                    {
                        //Switch
                        instance->SetData(DATA_CTHUN_PHASE, PHASE_CTHUN_STOMACH);

                        //Switch to c'thun model
                        me->InterruptNonMeleeSpells(false);
                        DoCast(me, SPELL_TRANSFORM, false);
                        me->SetFullHealth();

                        me->SetVisible(true);
                        me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_NON_ATTACKABLE);

                        //Emerging phase
                        //AttackStart(ObjectAccessor::GetUnit(*me, HoldpPlayer));
                        DoZoneInCombat();

                        //Place all units in threat list on outside of stomach
                        Stomach_Map.clear();

                        for (std::list<HostileReference*>::const_iterator i = me->getThreatManager().getThreatList().begin(); i != me->getThreatManager().getThreatList().end(); ++i)
                            Stomach_Map[(*i)->getUnitGuid()] = false;   //Outside stomach

                        //Spawn 2 flesh tentacles
                        FleshTentaclesKilled = 0;

                        //Spawn flesh tentacle
                        for (uint8 i = 0; i < 2; i++)
                        {
                            Creature* spawned = me->SummonCreature(NPC_FLESH_TENTACLE, FleshTentaclePos[i], TEMPSUMMON_CORPSE_DESPAWN);
                            if (!spawned)
                                ++FleshTentaclesKilled;
                        }

                        PhaseTimer = 0;
                    } else PhaseTimer -= diff;

                    break;

                //Body Phase
                case PHASE_CTHUN_STOMACH:
                    //Remove Target field
                    me->SetTarget(ObjectGuid::Empty);

                    //Weaken
                    if (FleshTentaclesKilled > 1)
                    {
                        instance->SetData(DATA_CTHUN_PHASE, PHASE_CTHUN_WEAK);

                        Talk(EMOTE_WEAKENED);
                        PhaseTimer = 45000;

                        DoCast(me, SPELL_PURPLE_COLORATION, true);

                        std::unordered_map<ObjectGuid, bool>::iterator i = Stomach_Map.begin();

                        //Kick all players out of stomach
                        while (i != Stomach_Map.end())
                        {
                            //Check for valid player
                            Unit* unit = ObjectAccessor::GetUnit(*me, i->first);

                            //Only move units in stomach
                            if (unit && i->second == true)
                            {
                                //Teleport each player out
                                DoTeleportPlayer(unit, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ() + 10, float(rand32() % 6));

                                //Cast knockback on them
                                DoCast(unit, SPELL_EXIT_STOMACH_KNOCKBACK, true);

                                //Remove the acid debuff
                                unit->RemoveAurasDueToSpell(SPELL_DIGESTIVE_ACID);

                                i->second = false;
                            }
                            ++i;
                        }

                        return;
                    }

                    //Stomach acid
                    if (StomachAcidTimer <= diff)
                    {
                        //Apply aura to all players in stomach
                        std::unordered_map<ObjectGuid, bool>::iterator i = Stomach_Map.begin();

                        while (i != Stomach_Map.end())
                        {
                            //Check for valid player
                            Unit* unit = ObjectAccessor::GetUnit(*me, i->first);

                            //Only apply to units in stomach
                            if (unit && i->second == true)
                            {
                                //Cast digestive acid on them
                                DoCast(unit, SPELL_DIGESTIVE_ACID, true);

                                //Check if player should be kicked from stomach
                                if (unit->IsWithinDist3d(&KickPos, 15.0f))
                                {
                                    //Teleport each player out
                                    DoTeleportPlayer(unit, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ() + 10, float(rand32() % 6));

                                    //Cast knockback on them
                                    DoCast(unit, SPELL_EXIT_STOMACH_KNOCKBACK, true);

                                    //Remove the acid debuff
                                    unit->RemoveAurasDueToSpell(SPELL_DIGESTIVE_ACID);

                                    i->second = false;
                                }
                            }
                            ++i;
                        }

                        StomachAcidTimer = 4000;
                    } else StomachAcidTimer -= diff;

                    //Stomach Enter Timer
                    if (StomachEnterTimer <= diff)
                    {
                        if (Unit* target = SelectRandomNotStomach())
                        {
                            //Set target in stomach
                            Stomach_Map[target->GetGUID()] = true;
                            target->InterruptNonMeleeSpells(false);
                            target->CastSpell(target, SPELL_MOUTH_TENTACLE, true, NULL, NULL, me->GetGUID());
                            StomachEnterTarget = target->GetGUID();
                            StomachEnterVisTimer = 3800;
                        }

                        StomachEnterTimer = 13800;
                    } else StomachEnterTimer -= diff;

                    if (StomachEnterVisTimer && StomachEnterTarget)
                    {
                        if (StomachEnterVisTimer <= diff)
                        {
                            //Check for valid player
                            Unit* unit = ObjectAccessor::GetUnit(*me, StomachEnterTarget);

                            if (unit)
                            {
                                DoTeleportPlayer(unit, STOMACH_X, STOMACH_Y, STOMACH_Z, STOMACH_O);
                            }

                            StomachEnterTarget.Clear();
                            StomachEnterVisTimer = 0;
                        } else StomachEnterVisTimer -= diff;
                    }

                    //GientClawTentacleTimer
                    if (GiantClawTentacleTimer <= diff)
                    {
                        if (Unit* target = SelectRandomNotStomach())
                        {
                            //Spawn claw tentacle on the random target
                            if (Creature* spawned = me->SummonCreature(NPC_GIANT_CLAW_TENTACLE, *target, TEMPSUMMON_CORPSE_DESPAWN, 500))
                                if (spawned->AI())
                                    spawned->AI()->AttackStart(target);
                        }

                        //One giant claw tentacle every minute
                        GiantClawTentacleTimer = 60000;
                    } else GiantClawTentacleTimer -= diff;

                    //GiantEyeTentacleTimer
                    if (GiantEyeTentacleTimer <= diff)
                    {
                        if (Unit* target = SelectRandomNotStomach())
                        {
                            //Spawn claw tentacle on the random target
                            if (Creature* spawned = me->SummonCreature(NPC_GIANT_EYE_TENTACLE, *target, TEMPSUMMON_CORPSE_DESPAWN, 500))
                                if (spawned->AI())
                                    spawned->AI()->AttackStart(target);
                        }

                        //One giant eye tentacle every minute
                        GiantEyeTentacleTimer = 60000;
                    } else GiantEyeTentacleTimer -= diff;

                    break;

                //Weakened state
                case PHASE_CTHUN_WEAK:
                    //PhaseTimer
                    if (PhaseTimer <= diff)
                    {
                        //Switch
                        instance->SetData(DATA_CTHUN_PHASE, PHASE_CTHUN_STOMACH);

                        //Remove purple coloration
                        me->RemoveAurasDueToSpell(SPELL_PURPLE_COLORATION);

                        //Spawn 2 flesh tentacles
                        FleshTentaclesKilled = 0;

                        //Spawn flesh tentacle
                        for (uint8 i = 0; i < 2; i++)
                        {
                            Creature* spawned = me->SummonCreature(NPC_FLESH_TENTACLE, FleshTentaclePos[i], TEMPSUMMON_CORPSE_DESPAWN);
                            if (!spawned)
                                ++FleshTentaclesKilled;
                        }

                        PhaseTimer = 0;
                    } else PhaseTimer -= diff;

                    break;
            }
        }
std::string convert_talk_topic( talk_topic_enum const old_value )
{
    static const std::unordered_map<talk_topic_enum, std::string> talk_topic_enum_mapping = { {
// This macro creates the appropriate new names (as string) for each enum value, so one does not
// have to repeat so much (e.g. 'WRAP(TALK_ARSONIST)' instead of '{ TALK_ARSONIST, "TALK_ARSONIST" }')
// It also ensures that each name is exactly as the name of the enum value.
#define WRAP(value) { value, #value }
 WRAP(TALK_NONE),
 WRAP(TALK_DONE),
 WRAP(TALK_GUARD),
 WRAP(TALK_MISSION_LIST),
 WRAP(TALK_MISSION_LIST_ASSIGNED),
 WRAP(TALK_MISSION_DESCRIBE),
 WRAP(TALK_MISSION_OFFER),
 WRAP(TALK_MISSION_ACCEPTED),
 WRAP(TALK_MISSION_REJECTED),
 WRAP(TALK_MISSION_ADVICE),
 WRAP(TALK_MISSION_INQUIRE),
 WRAP(TALK_MISSION_SUCCESS),
 WRAP(TALK_MISSION_SUCCESS_LIE),
 WRAP(TALK_MISSION_FAILURE),
 WRAP(TALK_MISSION_REWARD),
 WRAP(TALK_EVAC_MERCHANT),
 WRAP(TALK_EVAC_MERCHANT_NEW),
 WRAP(TALK_EVAC_MERCHANT_PLANS),
 WRAP(TALK_EVAC_MERCHANT_PLANS2),
 WRAP(TALK_EVAC_MERCHANT_PLANS3),
 WRAP(TALK_EVAC_MERCHANT_WORLD),
 WRAP(TALK_EVAC_MERCHANT_HORDES),
 WRAP(TALK_EVAC_MERCHANT_PRIME_LOOT),
 WRAP(TALK_EVAC_MERCHANT_ASK_JOIN),
 WRAP(TALK_EVAC_MERCHANT_NO),
 WRAP(TALK_EVAC_MERCHANT_HELL_NO),
 WRAP(TALK_FREE_MERCHANT_STOCKS),
 WRAP(TALK_FREE_MERCHANT_STOCKS_NEW),
 WRAP(TALK_FREE_MERCHANT_STOCKS_WHY),
 WRAP(TALK_FREE_MERCHANT_STOCKS_ALL),
 WRAP(TALK_FREE_MERCHANT_STOCKS_JERKY),
 WRAP(TALK_FREE_MERCHANT_STOCKS_CORNMEAL),
 WRAP(TALK_FREE_MERCHANT_STOCKS_FLOUR),
 WRAP(TALK_FREE_MERCHANT_STOCKS_SUGAR),
 WRAP(TALK_FREE_MERCHANT_STOCKS_WINE),
 WRAP(TALK_FREE_MERCHANT_STOCKS_BEER),
 WRAP(TALK_FREE_MERCHANT_STOCKS_SMMEAT),
 WRAP(TALK_FREE_MERCHANT_STOCKS_SMFISH),
 WRAP(TALK_FREE_MERCHANT_STOCKS_OIL),
 WRAP(TALK_FREE_MERCHANT_STOCKS_DELIVERED),
 WRAP(TALK_EVAC_GUARD1),
 WRAP(TALK_EVAC_GUARD1_PLACE),
 WRAP(TALK_EVAC_GUARD1_GOVERNMENT),
 WRAP(TALK_EVAC_GUARD1_TRADE),
 WRAP(TALK_EVAC_GUARD1_JOIN),
 WRAP(TALK_EVAC_GUARD1_JOIN2),
 WRAP(TALK_EVAC_GUARD1_JOIN3),
 WRAP(TALK_EVAC_GUARD1_ATTITUDE),
 WRAP(TALK_EVAC_GUARD1_JOB),
 WRAP(TALK_EVAC_GUARD1_OLDGUARD),
 WRAP(TALK_EVAC_GUARD1_BYE),
 WRAP(TALK_EVAC_GUARD2),
 WRAP(TALK_EVAC_GUARD2_NEW),
 WRAP(TALK_EVAC_GUARD2_RULES),
 WRAP(TALK_EVAC_GUARD2_RULES_BASEMENT),
 WRAP(TALK_EVAC_GUARD2_WHO),
 WRAP(TALK_EVAC_GUARD2_TRADE),
 WRAP(TALK_EVAC_GUARD3),
 WRAP(TALK_EVAC_GUARD3_NEW),
 WRAP(TALK_EVAC_GUARD3_RULES),
 WRAP(TALK_EVAC_GUARD3_HIDE1),
 WRAP(TALK_EVAC_GUARD3_HIDE2),
 WRAP(TALK_EVAC_GUARD3_WASTE),
 WRAP(TALK_EVAC_GUARD3_DEAD),
 WRAP(TALK_EVAC_GUARD3_HOSTILE),
 WRAP(TALK_EVAC_GUARD3_INSULT),
 WRAP(TALK_EVAC_HUNTER),
 WRAP(TALK_EVAC_HUNTER_SMELL),
 WRAP(TALK_EVAC_HUNTER_DO),
 WRAP(TALK_EVAC_HUNTER_LIFE),
 WRAP(TALK_EVAC_HUNTER_HUNT),
 WRAP(TALK_EVAC_HUNTER_SALE),
 WRAP(TALK_EVAC_HUNTER_ADVICE),
 WRAP(TALK_EVAC_HUNTER_BYE),
 WRAP(TALK_OLD_GUARD_REP),
 WRAP(TALK_OLD_GUARD_REP_NEW),
 WRAP(TALK_OLD_GUARD_REP_NEW_DOING),
 WRAP(TALK_OLD_GUARD_REP_NEW_DOWNSIDE),
 WRAP(TALK_OLD_GUARD_REP_WORLD),
 WRAP(TALK_OLD_GUARD_REP_WORLD_2NDFLEET),
 WRAP(TALK_OLD_GUARD_REP_WORLD_FOOTHOLDS),
 WRAP(TALK_OLD_GUARD_REP_ASK_JOIN),
 WRAP(TALK_ARSONIST),
 WRAP(TALK_ARSONIST_NEW),
 WRAP(TALK_ARSONIST_DOING),
 WRAP(TALK_ARSONIST_DOING_REBAR),
 WRAP(TALK_ARSONIST_WORLD),
 WRAP(TALK_ARSONIST_WORLD_OPTIMISTIC),
 WRAP(TALK_ARSONIST_JOIN),
 WRAP(TALK_ARSONIST_MUTATION),
 WRAP(TALK_ARSONIST_MUTATION_INSULT),
 WRAP(TALK_SCAVENGER_MERC),
 WRAP(TALK_SCAVENGER_MERC_NEW),
 WRAP(TALK_SCAVENGER_MERC_TIPS),
 WRAP(TALK_SCAVENGER_MERC_HIRE),
 WRAP(TALK_SCAVENGER_MERC_HIRE_SUCCESS),
 WRAP(TALK_SHELTER),
 WRAP(TALK_SHELTER_PLANS),
 WRAP(TALK_SHARE_EQUIPMENT),
 WRAP(TALK_GIVE_EQUIPMENT),
 WRAP(TALK_DENY_EQUIPMENT),
 WRAP(TALK_TRAIN),
 WRAP(TALK_TRAIN_START),
 WRAP(TALK_TRAIN_FORCE),
 WRAP(TALK_SUGGEST_FOLLOW),
 WRAP(TALK_AGREE_FOLLOW),
 WRAP(TALK_DENY_FOLLOW),
 WRAP(TALK_SHOPKEEP),
 WRAP(TALK_LEADER),
 WRAP(TALK_LEAVE),
 WRAP(TALK_PLAYER_LEADS),
 WRAP(TALK_LEADER_STAYS),
 WRAP(TALK_HOW_MUCH_FURTHER),
 WRAP(TALK_FRIEND),
 WRAP(TALK_FRIEND_GUARD),
 WRAP(TALK_DENY_GUARD),
 WRAP(TALK_DENY_TRAIN),
 WRAP(TALK_DENY_PERSONAL),
 WRAP(TALK_FRIEND_UNCOMFORTABLE),
 WRAP(TALK_COMBAT_COMMANDS),
 WRAP(TALK_COMBAT_ENGAGEMENT),
 WRAP(TALK_STRANGER_NEUTRAL),
 WRAP(TALK_STRANGER_WARY),
 WRAP(TALK_STRANGER_SCARED),
 WRAP(TALK_STRANGER_FRIENDLY),
 WRAP(TALK_STRANGER_AGGRESSIVE),
 WRAP(TALK_MUG),
 WRAP(TALK_DESCRIBE_MISSION),
 WRAP(TALK_WEAPON_DROPPED),
 WRAP(TALK_DEMAND_LEAVE),
 WRAP(TALK_SIZE_UP),
 WRAP(TALK_LOOK_AT),
 WRAP(TALK_OPINION)
} };
#undef WRAP
    auto const iter = talk_topic_enum_mapping.find( old_value );
    if( iter == talk_topic_enum_mapping.end() ) {
        debugmsg( "could not convert %d to new talk topic string", static_cast<int>( old_value ) );
        return "TALK_NONE";
    }
    return iter->second;
}
Beispiel #10
0
static void DeinitLevel()
{
	static bool initedLateHook = false;

	if (!initedLateHook)
	{
		// late hook to prevent scenario manager from reinitializing on map load - it messes things up, a lot, and I doubt custom maps use scenarios anyway. :)
		hook::put<uint16_t>(hook::pattern("83 F9 04 0F 85 F9 00 00 00").count(1).get(0).get<void>(3), 0xE990); // shutdown
		hook::put<uint16_t>(hook::pattern("83 F9 02 0F 85 C6 01 00 00").count(1).get(0).get<void>(3), 0xE990); // init

		// don't load mounted ped (personality) metadata anymore (temp dbg-y?)
		hook::nop(hook::pattern("48 8B DA 83 E9 14 74 5B").count(1).get(0).get<void>(0x72 - 12), 5);

		// recreate interior proxy pool sanely
		//char* poolFn = hook::get_pattern<char>("41 0F B7 C6 4D 89 73 E8 41 8B F6 66 89 44 24 28", -0x23);
		//poolFn += 0xD4;
		//hook::nop(poolFn, 44);
		//hook::jump(poolFn, ClearInteriorProxyPool);

		initedLateHook = true;
	}

	// stuff
	g_inLevelFree = true;

	g_deinitLevel();

	shutdownModelInfo(1);
	initModelInfo(1);
	initStreamingInterface();

	//g_loadClipSets();

	// extra content manager shutdown session removes these, and we want these before init session, so we scan them right here, right now.
	// TEMP REMOVE
	extraContentMgr__doScanInt(*g_extraContentMgr);
	extraContentMgr__doScanPost(*g_extraContentMgr, false, false);

	//shutdownPhysics(1);
	//initPhysics(1);

	// unknown value in the bounds streaming module, doesn't get cleared on 'after map loaded' shutdown
	int colCrashOffset = *hook::get_pattern<int>("0F B7 83 ? ? 00 00 BA FF 1F 00 00 66 33 C1 66", 3);
	int colCrashCountMax = (colCrashOffset - 464) / 4;

	*(uint32_t*)(g_boundsStreamingModule + colCrashOffset) = 0;

	// bounds streaming module, 'has preloading bounds completed' value
	*(uint8_t*)(g_boundsStreamingModule + 255) = 0;

	// clear the 'loaded cache hashes' list
	//*g_cacheArray = atArray<allocWrap<uint32_t>>(16);
	g_cacheArray->ClearCount();

	// free one CScene list of all the bad influences from the last session
	ClearInteriorProxyList(g_sceneLinkedList);

	// also clear the interior proxy pool out, as it might contain garbage references to static bounds, still
	(*g_interiorProxyPool)->Clear();

	// and some global vehicle audio entity also houses... interior proxies.
	*g_vehicleReflEntityArray = atArray<CInteriorProxy*>();

	// clear interior proxies from render phases
	for (auto& pair : g_renderPhases)
	{
		CRenderPhaseScanned* renderPhase = pair.second;

		if (renderPhase->portalScanner)
		{
			trace("clearing %s interior proxy (was %p)\n", pair.first.c_str(), renderPhase->portalScanner->interiorProxy);

			renderPhase->portalScanner->interiorProxy = nullptr;
		}
	}

	g_inLevelFree = false;

	if (!g_didLevelFree)
	{
		for (auto& stack : g_stacks)
		{
			FILE* f = fopen(va("D:\\dev\\stacks\\%p.txt", ((stack.first / 256) * 256)), "a");

			if (f)
			{
				fprintf(f, "--- %p ---\n", stack.first);

				for (auto& entry : stack.second)
				{
					fprintf(f, "%p\n", entry);
				}

				fprintf(f, "--- --- ---\n");

				fclose(f);
			}
		}

		g_stackIdx = 0;
		g_stacks.clear();

		g_didLevelFree = true;
	}
}
std::unordered_set<TileID, TileID::Hash>
AnnotationManager::addTileFeature(const uint32_t annotationID,
                                  const AnnotationSegments& segments,
                                  const std::vector<std::vector<vec2<double>>>& projectedFeature,
                                  const AnnotationType& type,
                                  const StyleProperties& styleProperties,
                                  const std::unordered_map<std::string, std::string>& featureProperties,
                                  const std::string layerId,
                                  const uint8_t maxZoom) {

    assert(type != AnnotationType::Any);

    // track the annotation global ID and its original geometry
    auto anno_it = annotations.emplace(annotationID,
        std::make_unique<Annotation>(type, layerId, segments, styleProperties));

    std::unordered_set<TileID, TileID::Hash> affectedTiles;

    if (type == AnnotationType::Shape) {

        orderedShapeAnnotations.push_back(annotationID);

        using namespace mapbox::util::geojsonvt;

        const double z2 = 1 << maxZoom;
        const double baseTolerance = 3;
        const double extent = 4096;

        const double tolerance = baseTolerance / (z2 * extent);

        ProjectedGeometryContainer rings;

        std::vector<LonLat> points;

        for (size_t i = 0; i < segments[0].size(); ++i) { // first segment for now (no holes)
            const double constraintedLatitude = ::fmin(::fmax(segments[0][i].latitude, -util::LATITUDE_MAX), util::LATITUDE_MAX);
            points.push_back(LonLat(segments[0][i].longitude, constraintedLatitude));
        }

        ProjectedFeatureType featureType;

        if (styleProperties.is<FillProperties>()) {
            featureType = ProjectedFeatureType::Polygon;

            if (points.front().lon != points.back().lon || points.front().lat != points.back().lat) {
                points.push_back(LonLat(points.front().lon, points.front().lat));
            }
        } else {
            featureType = ProjectedFeatureType::LineString;
        }

        ProjectedGeometryContainer ring = Convert::project(points, tolerance);

        rings.members.push_back(ring);

        std::vector<ProjectedFeature> features;

        Tags tags;
        tags.insert(featureProperties.begin(), featureProperties.end());

        features.push_back(Convert::create(tags, featureType, rings));

        shapeTilers.emplace(annotationID, std::make_unique<GeoJSONVT>(features, maxZoom, 4, 100, 10));

    } else {

        // side length of map at max zoom
        double z2 = 1 << maxZoom;

        const double extent = 4096;

        uint32_t x = 0;
        uint32_t y = 0;

        for (int8_t z = maxZoom; z >= 0; z--) {

            std::unordered_map<TileID, GeometryCollection, TileID::Hash> featureTiles;

            if (type == AnnotationType::Point) {
                auto& pp = projectedFeature[0][0];

                x = pp.x * z2;
                y = pp.y * z2;

                const Coordinate coordinate(extent * (pp.x * z2 - x), extent * (pp.y * z2 - y));

                GeometryCollection geometries = {{ {{ coordinate }} }};

                featureTiles.emplace(TileID(z, x, y, z), geometries);
            } else {
                for (size_t l = 0; l < projectedFeature.size(); ++l) {
                    for (size_t p = 0; p < projectedFeature[l].size(); ++p) {

                        auto& pp = projectedFeature[l][p];

                        x = pp.x * z2;
                        y = pp.y * z2;

                        const Coordinate coordinate(extent * (pp.x * z2 - x), extent * (pp.y * z2 - y));

                        auto tile_it = featureTiles.find(TileID(z, x, y, z));

                        if (tile_it != featureTiles.end()) {
                            GeometryCollection& geometries = featureTiles.find(TileID(z, x, y, z))->second;
                            if (!geometries.empty()) {
                                geometries.back().push_back(coordinate);
                            } else {
                                geometries.push_back({{ coordinate }});
                            }
                        } else {
                            GeometryCollection geometries = {{ {{ coordinate }} }};
                            featureTiles.emplace(TileID(z, x, y, z), geometries);
                        }
                    }
                }
            }

            for (auto& featureTile : featureTiles) {
                // determine feature type
                FeatureType featureType;
                if (type == AnnotationType::Point) {
                    featureType = FeatureType::Point;
                } else if (styleProperties.is<LineProperties>()) {
                    featureType = FeatureType::LineString;
                } else if (styleProperties.is<FillProperties>()) {
                    featureType = FeatureType::Polygon;
                } else {
                    throw std::runtime_error("Invalid feature type");
                }

                // create tile feature
                auto feature = std::make_shared<const LiveTileFeature>(
                    featureType,
                    featureTile.second,
                    featureProperties
                );

                // check for tile & create if necessary
                auto tile_pos = tiles.emplace(featureTile.first,
                                              std::make_pair(std::unordered_set<uint32_t>({ annotationID }),
                                                             std::make_unique<LiveTile>()));

                // check for annotation layer & create if necessary
                util::ptr<LiveTileLayer> layer;
                std::string layerID = "";
                if (type == AnnotationType::Point) {
                    layerID = PointLayerID;
                } else {
                    layerID = ShapeLayerID + "." + util::toString(annotationID);
                }
                if (tile_pos.second || tile_pos.first->second.second->getMutableLayer(layerID) == nullptr) {
                    layer = std::make_shared<LiveTileLayer>();
                    tile_pos.first->second.second->addLayer(layerID, layer);
                } else {
                    layer = tile_pos.first->second.second->getMutableLayer(layerID);

                    // associate annotation with tile
                    tile_pos.first->second.first.insert(annotationID);
                }

                // add feature to layer
                layer->addFeature(feature);

                // Record annotation association with tile and tile feature. This is used to determine stale tiles,
                // as well as to remove the feature from the tile upon annotation deletion.
                anno_it.first->second->tilePointFeatures.emplace(featureTile.first, std::weak_ptr<const LiveTileFeature>(feature));

                // track affected tile
                affectedTiles.insert(featureTile.first);
            }

            // get ready for the next-lower zoom number
            z2 /= 2;
            x /= 2;
            y /= 2;
        }
    }

    return affectedTiles;
}
Beispiel #12
0
tweener_t get_tweener(std::wstring name)
{
    std::transform(name.begin(), name.end(), name.begin(), std::tolower);

    if(name == L"linear")
        return [](double t, double b, double c, double d) {
        return ease_none(t, b, c, d, std::vector<double>());
    };

    std::vector<double> params;

    static const boost::wregex expr(L"(?<NAME>\\w*)(:(?<V0>\\d+\\.?\\d?))?(:(?<V1>\\d+\\.?\\d?))?"); // boost::regex has no repeated captures?
    boost::wsmatch what;
    if(boost::regex_match(name, what, expr))
    {
        name = what["NAME"].str();
        if(what["V0"].matched)
            params.push_back(boost::lexical_cast<double>(what["V0"].str()));
        if(what["V1"].matched)
            params.push_back(boost::lexical_cast<double>(what["V1"].str()));
    }

    typedef std::function<double(double, double, double, double, const std::vector<double>&)> tween_t;
    static const std::unordered_map<std::wstring, tween_t> tweens = boost::assign::map_list_of
            (L"",					ease_none		   )
            (L"linear",				ease_none		   )
            (L"easenone",			ease_none		   )
            (L"easeinquad",			ease_in_quad	   )
            (L"easeoutquad",		ease_out_quad	   )
            (L"easeinoutquad",		ease_in_out_quad   )
            (L"easeoutinquad",		ease_out_in_quad   )
            (L"easeincubic",		ease_in_cubic	   )
            (L"easeoutcubic",		ease_out_cubic	   )
            (L"easeinoutcubic",		ease_in_out_cubic  )
            (L"easeoutincubic",		ease_out_in_cubic  )
            (L"easeinquart", 		ease_in_quart 	   )
            (L"easeoutquart",		ease_out_quart	   )
            (L"easeinoutquart",		ease_in_out_quart  )
            (L"easeoutinquart",		ease_out_in_quart  )
            (L"easeinquint",		ease_in_quint	   )
            (L"easeoutquint",		ease_out_quint	   )
            (L"easeinoutquint",		ease_in_out_quint  )
            (L"easeoutinquint",		ease_out_in_quint  )
            (L"easeinsine",			ease_in_sine	   )
            (L"easeoutsine",		ease_out_sine	   )
            (L"easeinoutsine",		ease_in_out_sine   )
            (L"easeoutinsine",		ease_out_in_sine   )
            (L"easeinexpo",			ease_in_expo	   )
            (L"easeoutexpo",		ease_out_expo	   )
            (L"easeinoutexpo",		ease_in_out_expo   )
            (L"easeoutinexpo",		ease_out_in_expo   )
            (L"easeincirc",			ease_in_circ	   )
            (L"easeoutcirc",		ease_out_circ	   )
            (L"easeinoutcirc",		ease_in_out_circ   )
            (L"easeoutincirc",		ease_out_in_circ   )
            (L"easeinelastic",		ease_in_elastic	   )
            (L"easeoutelastic",		ease_out_elastic   )
            (L"easeinoutelastic",	ease_in_out_elastic)
            (L"easeoutinelastic",	ease_out_in_elastic)
            (L"easeinback",			ease_in_back	   )
            (L"easeoutback",		ease_out_back	   )
            (L"easeinoutback",		ease_in_out_back   )
            (L"easeoutintback",		ease_out_int_back  )
            (L"easeoutbounce",		ease_out_bounce	   )
            (L"easeinbounce",		ease_in_bounce	   )
            (L"easeinoutbounce",	ease_in_out_bounce )
            (L"easeoutinbounce",	ease_out_in_bounce );

    auto it = tweens.find(name);
    if(it == tweens.end())
        it = tweens.find(L"linear");

    return [=](double t, double b, double c, double d)
    {
        return it->second(t, b, c, d, params);
    };
};
Beispiel #13
0
namespace VM
{
	#define COLLISION_PADDING 0.1f

	std::vector<Script> scripts;
	std::unordered_map<std::string, scriptID> loadedScripts;

	ScriptStack::ScriptStack()
		: tail(0)
	{
		stack = new unsigned char[ptr_max];
		clear();
	}

	ScriptStack::~ScriptStack()
	{
		delete [] stack;
	}

	void ScriptStack::push(unsigned char* data, ptr size)
	{
		assert ( (tail+size) < ptr_max);
		memcpy(stack + tail, data, size);
		tail += size;
	}

	unsigned char* ScriptStack::get(ptr index)
	{
		assert( index < tail );
		return &stack[index];
	}

	void ScriptStack::clear()
	{
		tail = 0;
		memset(stack, 0xCD, ptr_max);
	}


	// FUNCTIONS ////////////////////////////////////////////////////////////////////////
	scriptID AddScript(const Script& script)
	{
		scriptID scriptid = scripts.size();
		scripts.push_back(Script());
		Script& newScript = scripts.back();

		CopyScript(newScript, script);

		return scriptid;
	}
	////////////////////////////////////////////////////////////////////////////////////////
	const Script& GetScript(scriptID id)
	{
		return scripts[id];
	}
	////////////////////////////////////////////////////////////////////////////////////////
	scriptID LoadCompiledScript(const std::string& scriptFile)
	{
		std::unordered_map<std::string, scriptID>::iterator scriptIter = loadedScripts.find(scriptFile);
		if (scriptIter != loadedScripts.end())
		{
			return loadedScripts[scriptFile];
		}
		std::fstream file;
		size_t dataSize;
		unsigned char code;
		unsigned char data[256];
		file.open(scriptFile, std::ios::in | std::ios::binary);

		scriptID newscriptID = scripts.size();
		scripts.push_back(Script());
		Script& newScript = scripts.back();

		size_t scriptSize;
		file.read((char*)&scriptSize, sizeof(size_t));
		newScript.reserve(scriptSize);

		for(size_t i = 0; i < scriptSize; ++i)
		{
			file.read((char*) &dataSize, sizeof(size_t));
			file.read((char*) &code, sizeof(unsigned char));
			file.read((char*) data, sizeof(unsigned char) * dataSize);

			newScript.push_back( Instruction(code, &data[0], dataSize) );
		}

		loadedScripts[scriptFile] = newscriptID;

		return newscriptID;
	}

	/////////////////////////////////////////////////////////////////////////////////////
	void SaveCompiledScript(const std::string& scriptFile, scriptID id)
	{
		std::fstream file;
		file.open(scriptFile, std::ios::out | std::ios::binary);

		Script script = scripts[id];

		Script::const_iterator it = script.begin();
		Script::const_iterator end = script.end();
		size_t scriptSize = script.size();
		file.write((char*)&scriptSize, sizeof(size_t));

		size_t dataSize;
		unsigned char code;
		const unsigned char* data;

		for(; it!= end; ++it)
		{
			dataSize = it->GetDataSize();
			code = it->GetCode();
			data = it->GetData();

			file.write((char*)&dataSize, sizeof(size_t));
			file.write((char*)&code, sizeof(unsigned char));
			file.write((char*)data, sizeof(unsigned char) * dataSize);
		}

		file.close();

	}

	/////////////////////////////////////////////////////////////////////////////////////
	void CopyScript(Script& dst, const Script& source)
	{
		dst.resize(source.size());

		for(size_t i = 0; i < source.size(); ++i)
		{
			dst[i] = source[i];
		}
	}

	// EXECUTE /////////////////////////////////////////////////////////////////////////////
	Actor* GetActor(unsigned char* data)
	{
		return (Actor*)*(unsigned int*)data;
	}

	const unsigned char* DataAtOffset(const unsigned char* data, ptr offset)
	{
		return data + offset * ptr_size;
	}

	void Execute(scriptID id)
	{
		ScriptStack scriptState;
		Execute(id, scriptState);
	}

	/////////////////////////////////////////////////////////////////////////////////////
	void Execute(scriptID id, ScriptStack& scriptState)
	{
		Script script = scripts[id];
		Script::const_iterator ins = script.begin();
		Script::const_iterator end = script.end();
		for (; ins != end; ++ins)
		{
			switch(ins->GetCode())
			{
			/////////////////////////////////////////////////////////////////////////////
			case op_noop:
				break;

			case op_push:
				{
					const unsigned char* data = ins->GetData();
					ptr size = *(ptr*)data; // SIZE MISMATCH, fix it ppeas Phil
					unsigned char* value = (unsigned char*)DataAtOffset(data, 1);
					scriptState.push(value, size);
				}

				break;
			/////////////////////////////////////////////////////////////////////////////
			case op_end:
				return;
				break;

			/////////////////////////////////////////////////////////////////////////////
			case op_forceout:
				{
					// figure out our overlap and how much we have.
					const unsigned char* data = ins->GetData();
					Actor* target = GetActor(scriptState.get(*data));
					Actor* source = GetActor( scriptState.get(*DataAtOffset(data, 1)) );
					const Box* sourceBox = source->GetCollision();
					const Box* targetBox = target->GetCollision();

					if ( !BoxesIntersect(sourceBox, targetBox) )
					{
						return;
					}

					float x1, x2, x3, x4, y1, y2, y3, y4;

					x1 = sourceBox->GetUpperLeft().x;
					x2 = targetBox->GetUpperRight().x;

					x3 = sourceBox->GetUpperRight().x;
					x4 = targetBox->GetUpperLeft().x;

					y1 = sourceBox->GetLowerLeft().y;
					y2 = targetBox->GetUpperLeft().y;

					y3 = sourceBox->GetUpperLeft().y;
					y4 = targetBox->GetLowerLeft().y;

					float bottomOverlap = y1-y2+COLLISION_PADDING;
					float topOverlap = y3-y4-COLLISION_PADDING;

					float leftOverlap = x1-x2-COLLISION_PADDING;
					float rightOverlap = x3-x4+COLLISION_PADDING;

					float moveY = abs(topOverlap) > abs(bottomOverlap) ? bottomOverlap : topOverlap;
					float moveX = abs(leftOverlap) > abs(rightOverlap) ? rightOverlap : leftOverlap;

					Vector2 moveFirst, moveSecond;

					if (abs(moveX) < abs(moveY))
					{
						moveFirst.x = moveX;
						moveSecond.y = moveY;
					}
					else
					{
						moveFirst.y = moveY;
						moveSecond.x = moveX;
					}

					target->Move(moveFirst);

					if ( BoxesIntersect(sourceBox, targetBox) )
					{
						target->Move(moveSecond);
					}
				}
				break;
			/////////////////////////////////////////////////////////////////////////////
			case op_playanim:
				{
					const unsigned char* data = ins->GetData();
					Actor* target = GetActor(scriptState.get(*data));
					unsigned char animName = (unsigned char)*( DataAtOffset(data, 1) );
					target->GetAnimComponent()->PlayAnim((char*)scriptState.get(animName));
				}
				break;

			/////////////////////////////////////////////////////////////////////////////
			case op_kill:
				const unsigned char* data = ins->GetData();
				Actor* target = (Actor*) scriptState.get(*(unsigned int*)data);
				target->MarkForCleanup();
				break;

			} // end switch(instruction)
		} // end for
	} // end Execute

} // end namespace
void OnlineFileRequestImpl::removeObserver(FileRequest* req) {
    observers.erase(req);
}
Beispiel #15
0
EXPORT_CDECL(bool) RegisterDataProvider(LPCWSTR name, IDataProvider *provider) {
  sDataProviders.emplace(name, provider);
  return true;
}
bool OnlineFileRequestImpl::hasObservers() const {
    return !observers.empty();
}
Beispiel #17
0
 /// Check whether the given subsystem is running or not
 bool is_running(const std::string &sub) noexcept {
   return subsystems.count(sub) > 0;
 }
Beispiel #18
0
bool TestHelpers::check_empty_map(const std::unordered_map<std::string,int64_t> & m) {
    return m.empty();
}
Beispiel #19
0
namespace pyston {

static uint64_t next_stack_addr = 0x4270000000L;
static std::deque<uint64_t> available_addrs;

// There should be a better way of getting this:
#define PAGE_SIZE 4096

#define INITIAL_STACK_SIZE (8 * PAGE_SIZE)
#define STACK_REDZONE_SIZE PAGE_SIZE
#define MAX_STACK_SIZE (4 * 1024 * 1024)

static std::unordered_map<void*, BoxedGenerator*> s_generator_map;
static_assert(THREADING_USE_GIL, "have to make the generator map thread safe!");

class RegisterHelper {
private:
    void* frame_addr;

public:
    RegisterHelper(BoxedGenerator* generator, void* frame_addr) : frame_addr(frame_addr) {
        s_generator_map[frame_addr] = generator;
    }
    ~RegisterHelper() {
        assert(s_generator_map.count(frame_addr));
        s_generator_map.erase(frame_addr);
    }
};

static void freeGeneratorStack(BoxedGenerator* g) {
    if (g->stack_begin == NULL)
        return;

    available_addrs.push_back((uint64_t)g->stack_begin);
    // Limit the number of generator stacks we keep around:
    if (available_addrs.size() > 5) {
        uint64_t addr = available_addrs.front();
        available_addrs.pop_front();
        int r = munmap((void*)(addr - MAX_STACK_SIZE), MAX_STACK_SIZE);
        assert(r == 0);
    }

    g->stack_begin = NULL;
}

Context* getReturnContextForGeneratorFrame(void* frame_addr) {
    BoxedGenerator* generator = s_generator_map[frame_addr];
    assert(generator);
    return generator->returnContext;
}

void generatorEntry(BoxedGenerator* g) {
    {
        assert(g->cls == generator_cls);
        assert(g->function->cls == function_cls);

        threading::pushGenerator(g, g->stack_begin, g->returnContext);
        try {
            RegisterHelper context_registerer(g, __builtin_frame_address(0));

            // call body of the generator
            BoxedFunctionBase* func = g->function;

            Box** args = g->args ? &g->args->elts[0] : nullptr;
            callCLFunc(func->f, nullptr, func->f->numReceivedArgs(), func->closure, g, func->globals, g->arg1, g->arg2,
                       g->arg3, args);
        } catch (ExcInfo e) {
            // unhandled exception: propagate the exception to the caller
            g->exception = e;
        }

        // we returned from the body of the generator. next/send/throw will notify the caller
        g->entryExited = true;
        threading::popGenerator();
    }
    swapContext(&g->context, g->returnContext, 0);
}

Box* generatorIter(Box* s) {
    return s;
}

// called from both generatorHasNext and generatorSend/generatorNext (but only if generatorHasNext hasn't been called)
static void generatorSendInternal(BoxedGenerator* self, Box* v) {
    STAT_TIMER(t0, "us_timer_generator_switching", 0);

    if (self->running)
        raiseExcHelper(ValueError, "generator already executing");

    // check if the generator already exited
    if (self->entryExited) {
        freeGeneratorStack(self);
        raiseExcHelper(StopIteration, (const char*)nullptr);
    }

    self->returnValue = v;
    self->running = true;

#if STAT_TIMERS
    if (!self->prev_stack)
        self->prev_stack = StatTimer::createStack(self->my_timer);
    else
        self->prev_stack = StatTimer::swapStack(self->prev_stack);
#endif

    swapContext(&self->returnContext, self->context, (intptr_t)self);

#if STAT_TIMERS
    self->prev_stack = StatTimer::swapStack(self->prev_stack);
    if (self->entryExited) {
        assert(self->prev_stack == &self->my_timer);
        assert(self->my_timer.isPaused());
    }
#endif

    self->running = false;

    // propagate exception to the caller
    if (self->exception.type) {
        assert(self->entryExited);
        freeGeneratorStack(self);
        // don't raise StopIteration exceptions because those are handled specially.
        if (!self->exception.matches(StopIteration))
            throw self->exception;
        return;
    }

    if (self->entryExited) {
        freeGeneratorStack(self);
        // Reset the current exception.
        // We could directly create the StopIteration exception but we delay creating it because often the caller is not
        // interested in the exception (=generatorHasnext). If we really need it we will create it inside generatorSend.
        self->exception = ExcInfo(NULL, NULL, NULL);
        return;
    }
}

Box* generatorSend(Box* s, Box* v) {
    assert(s->cls == generator_cls);
    BoxedGenerator* self = static_cast<BoxedGenerator*>(s);

    if (self->iterated_from__hasnext__)
        Py_FatalError(".throw called on generator last advanced with __hasnext__");

    generatorSendInternal(self, v);

    // throw StopIteration if the generator exited
    if (self->entryExited) {
        // But we can't just create a new exc because the generator may have exited because of an explicit
        // 'raise StopIterationSubClass, "test"' statement and we can't replace it with the generic StopIteration
        // exception.
        // That's why we set inside 'generatorSendInternal()' 'self->exception' to the raised StopIteration exception or
        // create a new one if the generator exited implicit.
        // CPython raises the custom exception just once, on the next generator 'next' it will we a normal StopIteration
        // exc.
        assert(self->exception.type == NULL || self->exception.matches(StopIteration));
        ExcInfo old_exc = self->exception;
        // Clear the exception for GC purposes:
        self->exception = ExcInfo(nullptr, nullptr, nullptr);
        if (old_exc.type == NULL)
            raiseExcHelper(StopIteration, (const char*)nullptr);
        throw old_exc;
    }

    return self->returnValue;
}

Box* generatorThrow(Box* s, BoxedClass* exc_cls, Box* exc_val = nullptr, Box** args = nullptr) {
    assert(s->cls == generator_cls);
    BoxedGenerator* self = static_cast<BoxedGenerator*>(s);

    if (self->iterated_from__hasnext__)
        Py_FatalError(".throw called on generator last advanced with __hasnext__");

    // don't overwrite self->exception if the generator already exited
    // because it will contain the StopIteration exception to throw.
    if (!self->entryExited) {
        Box* exc_tb = args ? nullptr : args[0];
        if (!exc_val)
            exc_val = None;
        if (!exc_tb)
            exc_tb = None;
        self->exception = excInfoForRaise(exc_cls, exc_val, exc_tb);
    }
    return generatorSend(self, None);
}

Box* generatorClose(Box* s) {
    assert(s->cls == generator_cls);
    BoxedGenerator* self = static_cast<BoxedGenerator*>(s);

    // check if the generator already exited
    if (self->entryExited)
        return None;

    return generatorThrow(self, GeneratorExit, nullptr, nullptr);
}

Box* generatorNext(Box* s) {
    assert(s->cls == generator_cls);
    BoxedGenerator* self = static_cast<BoxedGenerator*>(s);

    if (self->iterated_from__hasnext__) {
        self->iterated_from__hasnext__ = false;
        return self->returnValue;
    }

    return generatorSend(s, None);
}

i1 generatorHasnextUnboxed(Box* s) {
    assert(s->cls == generator_cls);
    BoxedGenerator* self = static_cast<BoxedGenerator*>(s);

    if (!self->iterated_from__hasnext__) {
        generatorSendInternal(self, None);
        self->iterated_from__hasnext__ = true;
    }

    return !self->entryExited;
}

Box* generatorHasnext(Box* s) {
    return boxBool(generatorHasnextUnboxed(s));
}


extern "C" Box* yield(BoxedGenerator* obj, Box* value) {
    STAT_TIMER(t0, "us_timer_generator_switching", 0);

    assert(obj->cls == generator_cls);
    BoxedGenerator* self = static_cast<BoxedGenerator*>(obj);
    self->returnValue = value;

    threading::popGenerator();
    swapContext(&self->context, self->returnContext, 0);
    threading::pushGenerator(obj, obj->stack_begin, obj->returnContext);

    // if the generator receives a exception from the caller we have to throw it
    if (self->exception.type) {
        ExcInfo e = self->exception;
        self->exception = ExcInfo(NULL, NULL, NULL);
        throw e;
    }
    return self->returnValue;
}


extern "C" BoxedGenerator* createGenerator(BoxedFunctionBase* function, Box* arg1, Box* arg2, Box* arg3, Box** args) {
    assert(function);
    assert(function->cls == function_cls);
    return new BoxedGenerator(function, arg1, arg2, arg3, args);
}

#if STAT_TIMERS
static uint64_t* generator_timer_counter = Stats::getStatCounter("us_timer_generator_toplevel");
#endif
extern "C" BoxedGenerator::BoxedGenerator(BoxedFunctionBase* function, Box* arg1, Box* arg2, Box* arg3, Box** args)
    : function(function),
      arg1(arg1),
      arg2(arg2),
      arg3(arg3),
      args(nullptr),
      entryExited(false),
      running(false),
      returnValue(nullptr),
      exception(nullptr, nullptr, nullptr),
      context(nullptr),
      returnContext(nullptr)
#if STAT_TIMERS
      ,
      prev_stack(NULL),
      my_timer(generator_timer_counter, 0, true)
#endif
{

    int numArgs = function->f->numReceivedArgs();
    if (numArgs > 3) {
        numArgs -= 3;
        this->args = new (numArgs) GCdArray();
        memcpy(&this->args->elts[0], args, numArgs * sizeof(Box*));
    }

    static StatCounter generator_stack_reused("generator_stack_reused");
    static StatCounter generator_stack_created("generator_stack_created");

    void* initial_stack_limit;
    if (available_addrs.size() == 0) {
        generator_stack_created.log();

        uint64_t stack_low = next_stack_addr;
        uint64_t stack_high = stack_low + MAX_STACK_SIZE;
        next_stack_addr = stack_high;

#if STACK_GROWS_DOWN
        this->stack_begin = (void*)stack_high;

        initial_stack_limit = (void*)(stack_high - INITIAL_STACK_SIZE);
        void* p = mmap(initial_stack_limit, INITIAL_STACK_SIZE, PROT_READ | PROT_WRITE,
                       MAP_PRIVATE | MAP_FIXED | MAP_ANONYMOUS | MAP_GROWSDOWN, -1, 0);
        ASSERT(p == initial_stack_limit, "%p %s", p, strerror(errno));

        // Create an inaccessible redzone so that the generator stack won't grow indefinitely.
        // Looks like it throws a SIGBUS if we reach the redzone; it's unclear if that's better
        // or worse than being able to consume all available memory.
        void* p2
            = mmap((void*)stack_low, STACK_REDZONE_SIZE, PROT_NONE, MAP_PRIVATE | MAP_FIXED | MAP_ANONYMOUS, -1, 0);
        assert(p2 == (void*)stack_low);
        // Interestingly, it seems like MAP_GROWSDOWN will leave a page-size gap between the redzone and the growable
        // region.

        if (VERBOSITY() >= 1) {
            printf("Created new generator stack, starts at %p, currently extends to %p\n", (void*)stack_high,
                   initial_stack_limit);
            printf("Created a redzone from %p-%p\n", (void*)stack_low, (void*)(stack_low + STACK_REDZONE_SIZE));
        }
#else
#error "implement me"
#endif

        // we're registering memory that isn't in the gc heap here,
        // which may sound wrong.  Generators, however, can represent
        // a larger tax on system resources than just their GC
        // allocation, so we try to encode that here as additional gc
        // heap pressure.
        gc::registerGCManagedBytes(INITIAL_STACK_SIZE);
    } else {
        generator_stack_reused.log();

#if STACK_GROWS_DOWN
        uint64_t stack_high = available_addrs.back();
        this->stack_begin = (void*)stack_high;
        initial_stack_limit = (void*)(stack_high - INITIAL_STACK_SIZE);
        available_addrs.pop_back();
#else
#error "implement me"
#endif
    }

    assert(((intptr_t)stack_begin & (~(intptr_t)(0xF))) == (intptr_t)stack_begin && "stack must be aligned");

    context = makeContext(stack_begin, (void (*)(intptr_t))generatorEntry);
}

extern "C" void generatorGCHandler(GCVisitor* v, Box* b) {
    boxGCHandler(v, b);

    BoxedGenerator* g = (BoxedGenerator*)b;

    v->visit(g->function);
    int num_args = g->function->f->numReceivedArgs();
    if (num_args >= 1)
        v->visit(g->arg1);
    if (num_args >= 2)
        v->visit(g->arg2);
    if (num_args >= 3)
        v->visit(g->arg3);
    if (g->args)
        v->visit(g->args);
    if (num_args > 3)
        v->visitPotentialRange(reinterpret_cast<void* const*>(&g->args->elts[0]),
                               reinterpret_cast<void* const*>(&g->args->elts[num_args - 3]));
    if (g->returnValue)
        v->visit(g->returnValue);
    if (g->exception.type)
        v->visit(g->exception.type);
    if (g->exception.value)
        v->visit(g->exception.value);
    if (g->exception.traceback)
        v->visit(g->exception.traceback);

    if (g->running) {
        v->visitPotentialRange((void**)&g->returnContext,
                               ((void**)&g->returnContext) + sizeof(g->returnContext) / sizeof(void*));
    } else {
        // g->context is always set for a running generator, but we can trigger a GC while constructing
        // a generator in which case we can see a NULL context
        if (g->context) {
#if STACK_GROWS_DOWN
            v->visitPotentialRange((void**)g->context, (void**)g->stack_begin);
#endif
        }
    }
}

Box* generatorName(Box* _self, void* context) {
    assert(isSubclass(_self->cls, generator_cls));
    BoxedGenerator* self = static_cast<BoxedGenerator*>(_self);

    return boxString(self->function->f->source->getName());
}

void generatorDestructor(Box* b) {
    assert(isSubclass(b->cls, generator_cls));
    BoxedGenerator* self = static_cast<BoxedGenerator*>(b);
    freeGeneratorStack(self);
}

void setupGenerator() {
    generator_cls
        = BoxedHeapClass::create(type_cls, object_cls, &generatorGCHandler, 0, offsetof(BoxedGenerator, weakreflist),
                                 sizeof(BoxedGenerator), false, "generator");
    generator_cls->simple_destructor = generatorDestructor;
    generator_cls->giveAttr("__iter__",
                            new BoxedFunction(boxRTFunction((void*)generatorIter, typeFromClass(generator_cls), 1)));

    generator_cls->giveAttr("close", new BoxedFunction(boxRTFunction((void*)generatorClose, UNKNOWN, 1)));
    generator_cls->giveAttr("next", new BoxedFunction(boxRTFunction((void*)generatorNext, UNKNOWN, 1)));

    CLFunction* hasnext = boxRTFunction((void*)generatorHasnextUnboxed, BOOL, 1);
    addRTFunction(hasnext, (void*)generatorHasnext, BOXED_BOOL);
    generator_cls->giveAttr("__hasnext__", new BoxedFunction(hasnext));

    generator_cls->giveAttr("send", new BoxedFunction(boxRTFunction((void*)generatorSend, UNKNOWN, 2)));
    auto gthrow = new BoxedFunction(boxRTFunction((void*)generatorThrow, UNKNOWN, 4, 2, false, false), { NULL, NULL });
    generator_cls->giveAttr("throw", gthrow);

    generator_cls->giveAttr("__name__", new (pyston_getset_cls) BoxedGetsetDescriptor(generatorName, NULL, NULL));

    generator_cls->freeze();
}
}
 inline const int index(const W& word) const {
   auto finder = word_idx.find(word);
   return (finder == word_idx.end()) ? 0 : finder->second;
 }
Beispiel #21
0
 ~RegisterHelper() {
     assert(s_generator_map.count(frame_addr));
     s_generator_map.erase(frame_addr);
 }
Beispiel #22
0
void mission::clear_all()
{
    world_missions.clear();
}
Beispiel #23
0
/// Close all open sockets
static void CleanupSockets() {
    for (auto sock : open_sockets)
        closesocket(sock.second.socket_fd);
    open_sockets.clear();
}
Beispiel #24
0
		Util::StringIdentifier getId(Obj * obj)const{
			const auto it = map_objToId.find(obj);
			return it==map_objToId.end() ? Util::StringIdentifier() : it->second;
		}
	void add(int number) {
	    if(hashmap.find(number)==hashmap.end())
	        hashmap[number] = 0;
	    hashmap[number] += 1;
	}
Beispiel #26
0
 void remove(std::string name)
 {
     auto pos = stringTextureMap.find(name);
     stringTextureMap.remove(pos);
 }
void CarbonRouterInstanceBase::addStartupOpts(
    std::unordered_map<std::string, std::string> additionalOpts) {
  additionalStartupOpts_.insert(additionalOpts.begin(), additionalOpts.end());
}
namespace GameEngine{
	//Initialise static attributes to null{0}
	btDynamicsWorld* PhysicsEngine::_world = 0;
	btDefaultCollisionConfiguration* PhysicsEngine::_config = 0;
	btCollisionDispatcher* PhysicsEngine::_dispatcher = 0;
	btBroadphaseInterface* PhysicsEngine::_broadphase = 0;
	btSequentialImpulseConstraintSolver* PhysicsEngine::_solver = 0;
	std::list<btRigidBody*> PhysicsEngine::_rigidBodies = std::list<btRigidBody*>();

	std::unordered_map<Entity*, std::set<Entity*>> contacts;

	bool HandleContacts(btManifoldPoint& point, btCollisionObject* body0, btCollisionObject* body1){
		//Get the 2 entities involved by accessing the user pointer of the bodies in contact
		Entity* entity0 = (Entity*)body0->getUserPointer();
		Entity* entity1 = (Entity*)body1->getUserPointer();

		// check if entity0 is already in map
		auto found = contacts.find(entity0);
		if(found != contacts.end()){
			//Entity in map. Add entity2 to the set mapped to it
			//Sets don't allow duplicates, so value won't be added if it already exists
			found->second.insert(entity1);
		}else{
			//entity1 not in map. Create new set and add entity1
			std::set<Entity*> set;
			set.insert(entity1);
			//add entity0 mapped to the new set in the contacts map
			contacts[entity0] = set;
		}
		return true;
	}

	bool PhysicsEngine::initialise(){
		_config = new btDefaultCollisionConfiguration();
		_dispatcher = new btCollisionDispatcher(_config);
		_broadphase = new btAxisSweep3(btVector3(-1000, -1000, -1000), btVector3(1000, 1000, 1000));
		_solver = new btSequentialImpulseConstraintSolver();
		_world = new btDiscreteDynamicsWorld(_dispatcher, _broadphase, _solver, _config);

		//set the collision processed callback
		gContactProcessedCallback = (ContactProcessedCallback)HandleContacts;
		
		//could check everything's ok but just return true for now
		return true;
	}

	bool PhysicsEngine::update(float deltaTime){
		_world->stepSimulation(deltaTime, 60);

		//iterate across the contacts map
		for(auto contactsIter = contacts.begin(); contactsIter!=contacts.end(); ++contactsIter){
			//get the entity key from  teh current entry in the map
			Entity* collider0 = contactsIter->first;
			//get the set of colliders from the current entry in the map
			std::set<Entity*>& set = contactsIter->second;
			//iterate thru all the entities in the set
			for(auto entityIter = set.begin(); entityIter!=set.end(); ++entityIter){
				// get the other colider from the iterator
				Entity* collider1 = *entityIter;
				//create 2 messages - one for collider and one for the entity being hit
				Message msg1(collider0, "COLLISION", collider1);
				Message msg2(collider1, "COLLISION", collider0);
				//dispatch teh messages
				MessageHandler::sendMessage(msg1);
				MessageHandler::sendMessage(msg2);
			}
		}
		//empty the contacts map ready for next time
		contacts.clear();

		//for now
		return true;
	}

	void PhysicsEngine::shutdown(){
		//remove all  rigid bodies
		for(auto iter = _rigidBodies.begin(); iter != _rigidBodies.end(); ++iter){
			//remove from world simulation
			_world->removeRigidBody(*iter);
			//delete from memory
			delete *iter;
			//set pointer to null{0}
			*iter = 0;
		}
		//now empty the list
		_rigidBodies.clear();

		//start deleting the physics components
		delete _world;
		_world = 0;
		delete _solver;
		_solver = 0;
		delete _dispatcher;
		_dispatcher = 0;
		delete _broadphase;
		_broadphase = 0;
		delete _config;
		_config = 0;
		//Physics now shutdown
	}
	

	//creates and registers a new square rigidbody - assumes position is set
	btRigidBody* PhysicsEngine::createBoxRigidBody(Entity* entity, const vector3df& scale, float mass){
		
		//create rigidbody's transform using entity's position
		btTransform transform;
		transform.setIdentity();
		vector3df pos = entity->getNode()->getPosition();
		transform.setOrigin(btVector3(pos.X, pos.Y, pos.Z));

		//create the motionState of the object
		btDefaultMotionState* motionState = new btDefaultMotionState(transform);

		//create the bounding volume
		btVector3 halfExtents(scale.X*0.5f, scale.Y*0.5f, scale.Z*0.5f);
		btCollisionShape* shape = new btBoxShape(halfExtents);

		//create intertia info for the shape
		btVector3 localinertia;
		shape->calculateLocalInertia(mass, localinertia);

		//now create the rigidBody
		btRigidBody* rigidBody = new btRigidBody(mass, motionState, shape, localinertia);

		//add a pointer to rigidBody pointing to associated Entity
		rigidBody->setUserPointer(entity);

		//add the rigidBody to the world
		_world->addRigidBody(rigidBody);

		//and add to the list of rigidBodies
		_rigidBodies.push_back(rigidBody);

		//finally return created body
		return rigidBody;
	}

	//creates and registers a new sphere - assumes position already set
	btRigidBody* PhysicsEngine::createSphereRigidBody(Entity* entity, float radius, float mass){
		//create rigidbody's transform using entity's position
		btTransform transform;
		transform.setIdentity();
		vector3df pos = entity->getNode()->getPosition();
		transform.setOrigin(btVector3(pos.X, pos.Y, pos.Z));

		//create the motionState of the object
		btDefaultMotionState* motionState = new btDefaultMotionState(transform);

		//create the bounding volume
		btCollisionShape* shape = new btSphereShape(radius);

		//create intertia info for the shape
		btVector3 localinertia;
		shape->calculateLocalInertia(mass, localinertia);

		//now create the rigidBody
		btRigidBody* rigidBody = new btRigidBody(mass, motionState, shape, localinertia);

		//add a pointer to rigidBody pointing to associated Entity
		rigidBody->setUserPointer(entity);

		//add the rigidBody to the world
		_world->addRigidBody(rigidBody);

		//and add to the list of rigidBodies
		_rigidBodies.push_back(rigidBody);

		//finally return created body
		return rigidBody;
	}

	bool PhysicsEngine::removeRigidBody(btRigidBody* body){
		_rigidBodies.remove(body);
		_world->removeRigidBody(body);

		return true;
	}

}
Beispiel #29
0
ICInfo* getICInfo(void* rtn_addr) {
    std::unordered_map<void*, ICInfo*>::iterator it = ics_by_return_addr.find(rtn_addr);
    if (it == ics_by_return_addr.end())
        return NULL;
    return it->second;
}