<commit_before>/*
 * DeliverMissionObjectiveImplementation.cpp
 *
 *  Created on: 20/08/2010
 *      Author: dannuic
 */

#include "DeliverMissionObjective.h"
#include "server/zone/objects/area/MissionSpawnActiveArea.h"

#include "server/zone/objects/waypoint/WaypointObject.h"
#include "server/zone/objects/creature/AiAgent.h"
#include "server/zone/objects/player/PlayerObject.h"
#include "server/zone/objects/region/Region.h"
#include "server/zone/Zone.h"
#include "server/zone/ZoneServer.h"
#include "server/zone/managers/object/ObjectManager.h"
#include "server/zone/managers/creature/CreatureManager.h"
#include "server/zone/managers/mission/MissionManager.h"
#include "server/zone/managers/terrain/TerrainManager.h"
#include "server/zone/managers/planet/PlanetManager.h"
#include "server/zone/packets/object/NpcConversationMessage.h"
#include "server/zone/packets/object/StartNpcConversation.h"
#include "server/zone/packets/object/StopNpcConversation.h"
#include "MissionObject.h"
#include "MissionObserver.h"

void DeliverMissionObjectiveImplementation::activate() {
	MissionObjectiveImplementation::activate();

	if (!activateWithResult()) {
		//Send error message to player.
		CreatureObject* owner = getPlayerOwner();
		if (owner == NULL) {
			return;
		}

		int randomNumber = System::random(4) + 1;
		StringIdChatParameter message("@mission/mission_generic:mission_incomplete_0" + String::valueOf(randomNumber));

		owner->sendSystemMessage(message);

		removeMissionFromPlayer();
	}
}

bool DeliverMissionObjectiveImplementation::activateWithResult() {
	CreatureObject* owner = getPlayerOwner();
	if (owner == NULL) {
		return false;
	}
	Zone* zone = owner->getZone();
	if (zone == NULL) {
		return false;
	}

	CreatureManager* creatureManager = zone->getCreatureManager();

	PlanetManager* planetManager = zone->getPlanetManager();
	if (planetManager == NULL) {
		return false;
	}
	TerrainManager* terrainManager = planetManager->getTerrainManager();
	if (terrainManager == NULL) {
		return false;
	}

	ZoneServer* zoneServer = owner->getZoneServer();
	if (zoneServer == NULL) {
		return false;
	}

	MissionManager* missionManager = zoneServer->getMissionManager();
	if (missionManager == NULL) {
		return false;
	}

	//Select spawn type.
	int spawnType = NpcSpawnPoint::NEUTRALSPAWN;
	switch (mission->getFaction()) {
	case MissionObject::FACTIONIMPERIAL:
		spawnType = NpcSpawnPoint::IMPERIALSPAWN;
		break;
	case MissionObject::FACTIONREBEL:
		spawnType = NpcSpawnPoint::REBELSPAWN;
		break;
	default:
		spawnType = NpcSpawnPoint::NEUTRALSPAWN;
		break;
	}

	//Spawn target and destination NPC's.

	//Target NPC
	//Find a free spawn point.
	targetSpawnPoint = missionManager->getRandomFreeNpcSpawnPoint(mission->getStartPlanetCRC(), mission->getStartPositionX(), mission->getStartPositionY(), spawnType);
	if (targetSpawnPoint == NULL) {
		return false;
	}
	Vector3* targetPosition = targetSpawnPoint->getPosition();
	if (targetPosition == NULL) {
		return false;
	}
	String deliverNpc = "deliver_npc";
	//Get the terrain height at the spawn point.
	float z = terrainManager->getHeight(targetPosition->getX(), targetPosition->getY());
	//Spawn the NPC.
	target = cast<AiAgent*>(creatureManager->spawnCreature(deliverNpc.hashCode(), 0, targetPosition->getX(), z, targetPosition->getY(), 0));
	//Update the heading direction of the NPC.
	Quaternion* direction = targetSpawnPoint->getDirection();
	target->updateDirection(direction->getW(), direction->getX(), direction->getY(), direction->getZ());
	//Set the name of the NPC.
	target->setCustomObjectName(mission->getCreatorName(), true);

	//Destination NPC.
	//Find a free spawn point.
	destinationSpawnPoint = missionManager->getRandomFreeNpcSpawnPoint(mission->getEndPlanet().hashCode(), mission->getEndPositionX(), mission->getEndPositionY(), spawnType);
	if (destinationSpawnPoint == NULL) {
		return false;
	}
	Vector3* destinationPosition = destinationSpawnPoint->getPosition();
	if (destinationPosition == NULL) {
		return false;
	}
	//Get the terrain height at the spawn point.
	z = terrainManager->getHeight(destinationPosition->getX(), destinationPosition->getY());
	//Spawn the NPC.
	destination = cast<AiAgent*>(creatureManager->spawnCreature(deliverNpc.hashCode(), 0, destinationPosition->getX(), z, destinationPosition->getY(), 0));
	//Update the heading direction of the NPC.
	direction = destinationSpawnPoint->getDirection();
	destination->updateDirection(direction->getW(), direction->getX(), direction->getY(), direction->getZ());
	//Set the name of the NPC.
	destination->setCustomObjectName(mission->getTargetName(), true);

	//Create waypoint and activate it.
	if (objectiveStatus == 0) {
		WaypointObject* waypoint = mission->getWaypointToMission();

		if (waypoint == NULL) {
			waypoint = mission->createWaypoint();
		}

		waypoint->setPlanetCRC(mission->getStartPlanetCRC());
		waypoint->setPosition(targetPosition->getX(), 0, targetPosition->getY());
		waypoint->setActive(true);

		mission->updateMissionLocation();
	} else {
		updateMissionTarget(getPlayerOwner());
	}

	return true;
}

void DeliverMissionObjectiveImplementation::abort() {
	MissionObjectiveImplementation::abort();

	despawnNpcs();
}

void DeliverMissionObjectiveImplementation::complete() {
	despawnNpcs();

	MissionObjectiveImplementation::complete();
}

void DeliverMissionObjectiveImplementation::despawnNpcs() {
	ZoneServer* zoneServer = getPlayerOwner()->getZoneServer();
	MissionManager* missionManager = zoneServer->getMissionManager();

	if (despawnMissionNpcsTask == NULL) {
		despawnMissionNpcsTask = new DespawnMissionNpcsTask(target, destination, targetSpawnPoint, destinationSpawnPoint, missionManager);
	}

	if (despawnMissionNpcsTask->isScheduled()) {
		return;
	} else {
		//Despawn after 1 minute.
		despawnMissionNpcsTask->schedule(60 * 1000);
	}
}

void DeliverMissionObjectiveImplementation::updateMissionStatus(CreatureObject* player) {
	StringBuffer itemEntry;
	itemEntry << "m" << mission->getMissionNumber();

	ManagedReference<SceneObject*> inventory = player->getSlottedObject("inventory");
	StringId itemName;

	Locker lock(player);

	switch (objectiveStatus) {
	case 0:
		itemEntry << "l";
		item = NULL;
		//TODO: create correct item.
		item = cast<TangibleObject*>( player->getZoneServer()->createObject(String("object/tangible/mission/mission_datadisk.iff").hashCode(), 2));
		if (item == NULL) {
			return;
		}

		itemName.setStringId("mission/mission_deliver_neutral_easy", itemEntry.toString());
		item->setObjectName(itemName);
		item->sendTo(player, true);

		//Give player the item to deliver
		inventory->transferObject(item, -1, true);

		updateMissionTarget(player);

		objectiveStatus = PICKEDUPSTATUS;
		break;
	case 1:
		// check for item, then remove item
		if (item == NULL || !inventory->hasObjectInContainer(item->getObjectID())) {
			return;
		}

		item->destroyObjectFromWorld(true);

		complete();

		objectiveStatus = DELIVEREDSTATUS;
		break;
	default:
		break;
	}
}

bool DeliverMissionObjectiveImplementation::updateMissionTarget(CreatureObject* player) {
	//Now update the waypoint to the new target
	WaypointObject* waypoint = mission->getWaypointToMission();
	if (waypoint == NULL) {
		waypoint = mission->createWaypoint();
	}

	waypoint->setPlanetCRC(mission->getEndPlanet().hashCode());
	waypoint->setPosition(destinationSpawnPoint->getPosition()->getX(), 0, destinationSpawnPoint->getPosition()->getY());
	waypoint->setActive(true);

	mission->updateMissionLocation();

	return true;
}
<commit_msg>[fixed] stability issue<commit_after>/*
 * DeliverMissionObjectiveImplementation.cpp
 *
 *  Created on: 20/08/2010
 *      Author: dannuic
 */

#include "DeliverMissionObjective.h"
#include "server/zone/objects/area/MissionSpawnActiveArea.h"
#include "server/ServerCore.h"
#include "server/zone/objects/waypoint/WaypointObject.h"
#include "server/zone/objects/creature/AiAgent.h"
#include "server/zone/objects/player/PlayerObject.h"
#include "server/zone/objects/region/Region.h"
#include "server/zone/Zone.h"
#include "server/zone/ZoneServer.h"
#include "server/zone/managers/object/ObjectManager.h"
#include "server/zone/managers/creature/CreatureManager.h"
#include "server/zone/managers/mission/MissionManager.h"
#include "server/zone/managers/terrain/TerrainManager.h"
#include "server/zone/managers/planet/PlanetManager.h"
#include "server/zone/packets/object/NpcConversationMessage.h"
#include "server/zone/packets/object/StartNpcConversation.h"
#include "server/zone/packets/object/StopNpcConversation.h"
#include "MissionObject.h"
#include "MissionObserver.h"

void DeliverMissionObjectiveImplementation::activate() {
	MissionObjectiveImplementation::activate();

	if (!activateWithResult()) {
		//Send error message to player.
		CreatureObject* owner = getPlayerOwner();
		if (owner == NULL) {
			return;
		}

		int randomNumber = System::random(4) + 1;
		StringIdChatParameter message("@mission/mission_generic:mission_incomplete_0" + String::valueOf(randomNumber));

		owner->sendSystemMessage(message);

		removeMissionFromPlayer();
	}
}

bool DeliverMissionObjectiveImplementation::activateWithResult() {
	CreatureObject* owner = getPlayerOwner();
	if (owner == NULL) {
		return false;
	}
	Zone* zone = owner->getZone();
	if (zone == NULL) {
		return false;
	}

	CreatureManager* creatureManager = zone->getCreatureManager();

	PlanetManager* planetManager = zone->getPlanetManager();
	if (planetManager == NULL) {
		return false;
	}
	TerrainManager* terrainManager = planetManager->getTerrainManager();
	if (terrainManager == NULL) {
		return false;
	}

	ZoneServer* zoneServer = owner->getZoneServer();
	if (zoneServer == NULL) {
		return false;
	}

	MissionManager* missionManager = zoneServer->getMissionManager();
	if (missionManager == NULL) {
		return false;
	}

	//Select spawn type.
	int spawnType = NpcSpawnPoint::NEUTRALSPAWN;
	switch (mission->getFaction()) {
	case MissionObject::FACTIONIMPERIAL:
		spawnType = NpcSpawnPoint::IMPERIALSPAWN;
		break;
	case MissionObject::FACTIONREBEL:
		spawnType = NpcSpawnPoint::REBELSPAWN;
		break;
	default:
		spawnType = NpcSpawnPoint::NEUTRALSPAWN;
		break;
	}

	//Spawn target and destination NPC's.

	//Target NPC
	//Find a free spawn point.
	targetSpawnPoint = missionManager->getRandomFreeNpcSpawnPoint(mission->getStartPlanetCRC(), mission->getStartPositionX(), mission->getStartPositionY(), spawnType);
	if (targetSpawnPoint == NULL) {
		return false;
	}
	Vector3* targetPosition = targetSpawnPoint->getPosition();
	if (targetPosition == NULL) {
		return false;
	}
	String deliverNpc = "deliver_npc";
	//Get the terrain height at the spawn point.
	float z = terrainManager->getHeight(targetPosition->getX(), targetPosition->getY());
	//Spawn the NPC.
	target = cast<AiAgent*>(creatureManager->spawnCreature(deliverNpc.hashCode(), 0, targetPosition->getX(), z, targetPosition->getY(), 0));
	//Update the heading direction of the NPC.
	Quaternion* direction = targetSpawnPoint->getDirection();
	target->updateDirection(direction->getW(), direction->getX(), direction->getY(), direction->getZ());
	//Set the name of the NPC.
	target->setCustomObjectName(mission->getCreatorName(), true);

	//Destination NPC.
	//Find a free spawn point.
	destinationSpawnPoint = missionManager->getRandomFreeNpcSpawnPoint(mission->getEndPlanet().hashCode(), mission->getEndPositionX(), mission->getEndPositionY(), spawnType);
	if (destinationSpawnPoint == NULL) {
		return false;
	}
	Vector3* destinationPosition = destinationSpawnPoint->getPosition();
	if (destinationPosition == NULL) {
		return false;
	}
	//Get the terrain height at the spawn point.
	z = terrainManager->getHeight(destinationPosition->getX(), destinationPosition->getY());
	//Spawn the NPC.
	destination = cast<AiAgent*>(creatureManager->spawnCreature(deliverNpc.hashCode(), 0, destinationPosition->getX(), z, destinationPosition->getY(), 0));
	//Update the heading direction of the NPC.
	direction = destinationSpawnPoint->getDirection();
	destination->updateDirection(direction->getW(), direction->getX(), direction->getY(), direction->getZ());
	//Set the name of the NPC.
	destination->setCustomObjectName(mission->getTargetName(), true);

	//Create waypoint and activate it.
	if (objectiveStatus == 0) {
		WaypointObject* waypoint = mission->getWaypointToMission();

		if (waypoint == NULL) {
			waypoint = mission->createWaypoint();
		}

		waypoint->setPlanetCRC(mission->getStartPlanetCRC());
		waypoint->setPosition(targetPosition->getX(), 0, targetPosition->getY());
		waypoint->setActive(true);

		mission->updateMissionLocation();
	} else {
		updateMissionTarget(getPlayerOwner());
	}

	return true;
}

void DeliverMissionObjectiveImplementation::abort() {
	MissionObjectiveImplementation::abort();

	despawnNpcs();
}

void DeliverMissionObjectiveImplementation::complete() {
	despawnNpcs();

	MissionObjectiveImplementation::complete();
}

void DeliverMissionObjectiveImplementation::despawnNpcs() {
	ZoneServer* zoneServer = ServerCore::getZoneServer();
	MissionManager* missionManager = zoneServer->getMissionManager();

	if (despawnMissionNpcsTask == NULL) {
		despawnMissionNpcsTask = new DespawnMissionNpcsTask(target, destination, targetSpawnPoint, destinationSpawnPoint, missionManager);
	}

	if (despawnMissionNpcsTask->isScheduled()) {
		return;
	} else {
		//Despawn after 1 minute.
		despawnMissionNpcsTask->schedule(60 * 1000);
	}
}

void DeliverMissionObjectiveImplementation::updateMissionStatus(CreatureObject* player) {
	StringBuffer itemEntry;
	itemEntry << "m" << mission->getMissionNumber();

	ManagedReference<SceneObject*> inventory = player->getSlottedObject("inventory");
	StringId itemName;

	Locker lock(player);

	switch (objectiveStatus) {
	case 0:
		itemEntry << "l";
		item = NULL;
		//TODO: create correct item.
		item = cast<TangibleObject*>( player->getZoneServer()->createObject(String("object/tangible/mission/mission_datadisk.iff").hashCode(), 2));
		if (item == NULL) {
			return;
		}

		itemName.setStringId("mission/mission_deliver_neutral_easy", itemEntry.toString());
		item->setObjectName(itemName);
		item->sendTo(player, true);

		//Give player the item to deliver
		inventory->transferObject(item, -1, true);

		updateMissionTarget(player);

		objectiveStatus = PICKEDUPSTATUS;
		break;
	case 1:
		// check for item, then remove item
		if (item == NULL || !inventory->hasObjectInContainer(item->getObjectID())) {
			return;
		}

		item->destroyObjectFromWorld(true);

		complete();

		objectiveStatus = DELIVEREDSTATUS;
		break;
	default:
		break;
	}
}

bool DeliverMissionObjectiveImplementation::updateMissionTarget(CreatureObject* player) {
	//Now update the waypoint to the new target
	WaypointObject* waypoint = mission->getWaypointToMission();
	if (waypoint == NULL) {
		waypoint = mission->createWaypoint();
	}

	waypoint->setPlanetCRC(mission->getEndPlanet().hashCode());
	waypoint->setPosition(destinationSpawnPoint->getPosition()->getX(), 0, destinationSpawnPoint->getPosition()->getY());
	waypoint->setActive(true);

	mission->updateMissionLocation();

	return true;
}
<|endoftext|>


<commit_before>//
// Created by marc on 15-11-16.
//

#include <iostream>
#include "PartitionSafe.h"

int main() {
    std::cout << "PartitionSafe :: Test script" << std::endl;

    try {

        //
        // Create vault
        //

        // Vault metadata
        const char *vaultPath = "/tmp/marc.vault";
        const char *keyStorePath = "/tmp/marc.vault";
        char label[40] = "Marc";

        // Create the partition safe instance
        PartitionSafe *ps = new PartitionSafe();

        // Create the vault
        ps->create(vaultPath, keyStorePath, label, 1024);
        std::cout << "Partition created" << std::endl;

        //
        // Open vault
        //

        // Init the vault
        ps->init(vaultPath, keyStorePath)->open();
        std::cout << "Partition opened" << std::endl;

        //
        // Write file
        //

        // File content
        const std::string filename = "sample.txt";
        const char line[] = "Hello world\nHai";

        // Write content
        ps->writeFile(filename, line, sizeof(line));
        std::cout << "File written" << std::endl;

        //
        // Open file
        //

        // File metadata
        FILINFO fileInfo;

        // Get file info
        ps->fileInfo(filename, &fileInfo);

        // The file buffer
        char readLines[fileInfo.fsize];

        // Read content
        ps->readFile(filename, readLines, sizeof(readLines));
        std::cout << "Read from file: " << std::endl << readLines;
    } catch(const char* exception) {
        // Hey, exception
        std::cout << "Thrown exception: " << exception << std::endl;
    }

    return 0;
}
<commit_msg>Fixed test script bug<commit_after>//
// Created by marc on 15-11-16.
//

#include <iostream>
#include "PartitionSafe.h"

int main() {
    std::cout << "PartitionSafe :: Test script" << std::endl << std::endl;

    try {

        //
        // Create vault
        //

        // Vault metadata
        const char *vaultPath = "/tmp/marc.vault";
        const char *keyStorePath = "/tmp/marc.keystore";
        char label[40] = "Marc";

        // Create the partition safe instance
        PartitionSafe *ps = new PartitionSafe();

        // Create the vault
        ps->create(vaultPath, keyStorePath, label, 1024);
        std::cout << "-- Partition created" << std::endl;

        //
        // Open vault
        //

        // Init the vault
        ps->init(vaultPath, keyStorePath)->open();
        std::cout << "-- Partition opened" << std::endl;

        //
        // Write file
        //

        // File content
        const std::string filename = "sample.txt";
        const char line[] = "Hello world\nHai";

        // Write content
        ps->writeFile(filename, line, sizeof(line));
        std::cout << "-- File written" << std::endl;

        //
        // Open file
        //

        // File metadata
        FILINFO fileInfo;

        // Get file info
        ps->fileInfo(filename, &fileInfo);

        // The file buffer
        char readLines[fileInfo.fsize];

        // Read content
        ps->readFile(filename, readLines, sizeof(readLines));
        std::cout << "-- Read from file: " << std::endl << readLines << std::endl;
    } catch(const char* exception) {
        // Hey, exception
        std::cout << "Thrown exception: " << exception << std::endl;
    }

    return 0;
}
<|endoftext|>


<commit_before><commit_msg>Working on bug fix<commit_after><|endoftext|>


<commit_before>/*
 * Copyright 2007-2017 Content Management AG
 * All rights reserved.
 *
 * author: Max Kellermann <mk@cm4all.com>
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * - Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *
 * - Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the
 * distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
 * FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#pragma once

#include "util/Cancellable.hxx"

#include <boost/intrusive/list.hpp>

/**
 * A job running in the background, which shall be aborted when
 * beng-proxy is shut down.  The job holds a reference to an
 * #Cancellable object, which may be used to stop it.
 */
struct BackgroundJob {
	static constexpr auto link_mode = boost::intrusive::normal_link;
	typedef boost::intrusive::link_mode<link_mode> LinkMode;
	typedef boost::intrusive::list_member_hook<LinkMode> SiblingsListHook;
	SiblingsListHook siblings;

	CancellablePointer cancel_ptr;
};

/**
 * A container for background jobs.
 */
class BackgroundManager {
	boost::intrusive::list<BackgroundJob,
			       boost::intrusive::member_hook<BackgroundJob,
							     BackgroundJob::SiblingsListHook,
							     &BackgroundJob::siblings>,
			       boost::intrusive::constant_time_size<false>> jobs;

public:
	/**
	 * Register a job to the manager.
	 */
	void Add(BackgroundJob &job) {
		jobs.push_front(job);
	}

	/**
	 * Add a background job to the manager, and return its
	 * #CancellablePointer.  This is a convenience function.
	 */
	CancellablePointer &Add2(BackgroundJob &job) {
		Add(job);
		return job.cancel_ptr;
	}

	/**
	 * Leave the job registered in the manager, and reuse its
	 * #CancellablePointer for another job iteration.
	 */
	CancellablePointer &Reuse(BackgroundJob &job) {
		return job.cancel_ptr;
	}

	/**
	 * Unregister a job from the manager.
	 */
	void Remove(BackgroundJob &job) {
		jobs.erase(jobs.iterator_to(job));
	}

	/**
	 * Abort all background jobs in the manager.  This is called on
	 * shutdown.
	 */
	void AbortAll() {
		jobs.clear_and_dispose([](BackgroundJob *job){
			job->cancel_ptr.Cancel();
		});
	}
};

class LinkedBackgroundJob : public BackgroundJob {
	BackgroundManager &manager;

public:
	LinkedBackgroundJob(BackgroundManager &_manager):manager(_manager) {}

	void Remove() {
		manager.Remove(*this);
	}
};
<commit_msg>util/Background: add `noexcept`<commit_after>/*
 * Copyright 2007-2020 CM4all GmbH
 * All rights reserved.
 *
 * author: Max Kellermann <mk@cm4all.com>
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * - Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *
 * - Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the
 * distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
 * FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#pragma once

#include "util/Cancellable.hxx"

#include <boost/intrusive/list.hpp>

/**
 * A job running in the background, which shall be aborted when
 * beng-proxy is shut down.  The job holds a reference to an
 * #Cancellable object, which may be used to stop it.
 */
struct BackgroundJob {
	static constexpr auto link_mode = boost::intrusive::normal_link;
	typedef boost::intrusive::link_mode<link_mode> LinkMode;
	typedef boost::intrusive::list_member_hook<LinkMode> SiblingsListHook;
	SiblingsListHook siblings;

	CancellablePointer cancel_ptr;
};

/**
 * A container for background jobs.
 */
class BackgroundManager {
	boost::intrusive::list<BackgroundJob,
			       boost::intrusive::member_hook<BackgroundJob,
							     BackgroundJob::SiblingsListHook,
							     &BackgroundJob::siblings>,
			       boost::intrusive::constant_time_size<false>> jobs;

public:
	/**
	 * Register a job to the manager.
	 */
	void Add(BackgroundJob &job) noexcept {
		jobs.push_front(job);
	}

	/**
	 * Add a background job to the manager, and return its
	 * #CancellablePointer.  This is a convenience function.
	 */
	CancellablePointer &Add2(BackgroundJob &job) noexcept {
		Add(job);
		return job.cancel_ptr;
	}

	/**
	 * Leave the job registered in the manager, and reuse its
	 * #CancellablePointer for another job iteration.
	 */
	CancellablePointer &Reuse(BackgroundJob &job) noexcept {
		return job.cancel_ptr;
	}

	/**
	 * Unregister a job from the manager.
	 */
	void Remove(BackgroundJob &job) noexcept {
		jobs.erase(jobs.iterator_to(job));
	}

	/**
	 * Abort all background jobs in the manager.  This is called on
	 * shutdown.
	 */
	void AbortAll() noexcept {
		jobs.clear_and_dispose([](BackgroundJob *job){
			job->cancel_ptr.Cancel();
		});
	}
};

class LinkedBackgroundJob : public BackgroundJob {
	BackgroundManager &manager;

public:
	LinkedBackgroundJob(BackgroundManager &_manager) noexcept
		:manager(_manager) {}

	void Remove() noexcept {
		manager.Remove(*this);
	}
};
<|endoftext|>


<commit_before>// Copyright 2019 The MediaPipe Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include <algorithm>
#include <memory>

#include "mediapipe/examples/desktop/autoflip/autoflip_messages.pb.h"
#include "mediapipe/examples/desktop/autoflip/calculators/active_speaker_to_region_calculator.pb.h"
#include "mediapipe/examples/desktop/autoflip/quality/visual_scorer.h"
#include "mediapipe/framework/calculator_framework.h"
#include "mediapipe/framework/formats/detection.pb.h"
#include "mediapipe/framework/formats/rect.pb.h"
#include "mediapipe/framework/formats/image_frame.h"
#include "mediapipe/framework/formats/image_frame_opencv.h"
#include "mediapipe/framework/formats/location_data.pb.h"
#include "mediapipe/framework/port/opencv_core_inc.h"
#include "mediapipe/framework/port/opencv_imgproc_inc.h"
#include "mediapipe/framework/port/ret_check.h"
#include "mediapipe/framework/port/status.h"
#include "mediapipe/framework/port/status_builder.h"

namespace mediapipe {
namespace autoflip {

constexpr char kInputVideo[] = "VIDEO";
constexpr char kInputRois[] = "DETECTIONS_SPEAKERS";
constexpr char kOutputRegion[] = "REGIONS";

// This calculator converts detected active speaker to SalientRegion protos that can be
// used for downstream processing. Each SalientRegion is scored using image
// cues. Scoring can be controlled through
// ActiveSpeakerToRegionCalculator::scorer_options.
// Example:
//    calculator: "ActiveSpeakerToRegionCalculator"
//    input_stream: "VIDEO:frames"
//    input_stream: "DETECTIONS_SPEAKERS:active_speakers_detections"
//    output_stream: "REGIONS:regions"
//    options:{
//      [mediapipe.autoflip.ActiveSpeakerToRegionCalculatorOptions.ext]:{
//        use_visual_scorer: true
//      }
//    }
//
class ActiveSpeakerToRegionCalculator : public CalculatorBase {
 public:
  ActiveSpeakerToRegionCalculator();
  ~ActiveSpeakerToRegionCalculator() override {}
  ActiveSpeakerToRegionCalculator(const ActiveSpeakerToRegionCalculator&) = delete;
  ActiveSpeakerToRegionCalculator& operator=(const ActiveSpeakerToRegionCalculator&) = delete;

  static ::mediapipe::Status GetContract(mediapipe::CalculatorContract* cc);
  ::mediapipe::Status Open(mediapipe::CalculatorContext* cc) override;
  ::mediapipe::Status Process(mediapipe::CalculatorContext* cc) override;

 private:
  // Calculator options.
  ActiveSpeakerToRegionCalculatorOptions options_;
  // A scorer used to assign weights to active speakers.
  std::unique_ptr<VisualScorer> scorer_;
  // Dimensions of video frame
  int frame_width_;
  int frame_height_;
}; // end with inheritance

REGISTER_CALCULATOR(ActiveSpeakerToRegionCalculator);

ActiveSpeakerToRegionCalculator::ActiveSpeakerToRegionCalculator() {}

::mediapipe::Status ActiveSpeakerToRegionCalculator::GetContract(
    mediapipe::CalculatorContract* cc) {
  if (cc->Inputs().HasTag(kInputVideo)) {
    cc->Inputs().Tag(kInputVideo).Set<ImageFrame>();
  }
  cc->Inputs().Tag(kInputRois).Set<std::vector<Detection>>();
  cc->Outputs().Tag(kOutputRegion).Set<DetectionSet>();
  return ::mediapipe::OkStatus();
}

::mediapipe::Status ActiveSpeakerToRegionCalculator::Open(
    mediapipe::CalculatorContext* cc) {
  options_ = cc->Options<ActiveSpeakerToRegionCalculatorOptions>();
  if (!cc->Inputs().HasTag(kInputVideo)) {
    RET_CHECK(!options_.use_visual_scorer())
        << "VIDEO input must be provided when using visual_scorer.";
  }

  scorer_ = absl::make_unique<VisualScorer>(options_.scorer_options());
  frame_width_ = -1;
  frame_height_ = -1;
  return ::mediapipe::OkStatus();
}

::mediapipe::Status ActiveSpeakerToRegionCalculator::Process(
    mediapipe::CalculatorContext* cc) {
  if (cc->Inputs().HasTag(kInputVideo) &&
      cc->Inputs().Tag(kInputVideo).Value().IsEmpty()) {
    return ::mediapipe::UnknownErrorBuilder(MEDIAPIPE_LOC)
           << "No VIDEO input at time " << cc->InputTimestamp().Seconds();
  }

  cv::Mat frame;
  if (cc->Inputs().HasTag(kInputVideo)) {
    frame = mediapipe::formats::MatView(
        &cc->Inputs().Tag(kInputVideo).Get<ImageFrame>());
    frame_width_ = frame.cols;
    frame_height_ = frame.rows;
  }

  auto region_set = ::absl::make_unique<DetectionSet>();
  if (!cc->Inputs().Tag(kInputRois).Value().IsEmpty()) {
    const auto& input_rois =
        cc->Inputs().Tag(kInputRois).Get<std::vector<Detection>>();

    for (const auto& input_roi : input_rois) {
      RET_CHECK(input_roi.location_data().format() ==
        mediapipe::LocationData::RELATIVE_BOUNDING_BOX)
        << "Speaker detection input is lacking required relative_bounding_box()";
      const auto& location = input_roi.location_data().relative_bounding_box();

      float x = std::max(0.0f, location.xmin());
      float y = std::max(0.0f, location.ymin());
      float width =
          std::min(location.width() - x + location.xmin(), 1 - x);
      float height =
          std::min(location.height() - y + location.ymin(), 1 - y);

      // Convert the text bounding box to a region.
      SalientRegion* region = region_set->add_detections();
      region->mutable_location_normalized()->set_x(x);
      region->mutable_location_normalized()->set_y(y);
      region->mutable_location_normalized()->set_width(width);
      region->mutable_location_normalized()->set_height(height);
      region->mutable_signal_type()->set_standard(SignalType::FACE_FULL);

      // Score the scores based on image cues.
      float visual_score = 1.0f;
      if (options_.use_visual_scorer()) {
        MP_RETURN_IF_ERROR(
            scorer_->CalculateScore(frame, *region, &visual_score));
        }
      region->set_score(visual_score);
      }
    }
  cc->Outputs().Tag(kOutputRegion).Add(region_set.release(), cc->InputTimestamp());

  return ::mediapipe::OkStatus();
}

}  // namespace autoflip
}  // namespace mediapipe
<commit_msg>Add SPEAKER signal type<commit_after>// Copyright 2019 The MediaPipe Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include <algorithm>
#include <memory>

#include "mediapipe/examples/desktop/autoflip/autoflip_messages.pb.h"
#include "mediapipe/examples/desktop/autoflip/calculators/active_speaker_to_region_calculator.pb.h"
#include "mediapipe/examples/desktop/autoflip/quality/visual_scorer.h"
#include "mediapipe/framework/calculator_framework.h"
#include "mediapipe/framework/formats/detection.pb.h"
#include "mediapipe/framework/formats/rect.pb.h"
#include "mediapipe/framework/formats/image_frame.h"
#include "mediapipe/framework/formats/image_frame_opencv.h"
#include "mediapipe/framework/formats/location_data.pb.h"
#include "mediapipe/framework/port/opencv_core_inc.h"
#include "mediapipe/framework/port/opencv_imgproc_inc.h"
#include "mediapipe/framework/port/ret_check.h"
#include "mediapipe/framework/port/status.h"
#include "mediapipe/framework/port/status_builder.h"

namespace mediapipe {
namespace autoflip {

constexpr char kInputVideo[] = "VIDEO";
constexpr char kInputRois[] = "DETECTIONS_SPEAKERS";
constexpr char kOutputRegion[] = "REGIONS";

// This calculator converts detected active speaker to SalientRegion protos that can be
// used for downstream processing. Each SalientRegion is scored using image
// cues. Scoring can be controlled through
// ActiveSpeakerToRegionCalculator::scorer_options.
// Example:
//    calculator: "ActiveSpeakerToRegionCalculator"
//    input_stream: "VIDEO:frames"
//    input_stream: "DETECTIONS_SPEAKERS:active_speakers_detections"
//    output_stream: "REGIONS:regions"
//    options:{
//      [mediapipe.autoflip.ActiveSpeakerToRegionCalculatorOptions.ext]:{
//        use_visual_scorer: true
//      }
//    }
//
class ActiveSpeakerToRegionCalculator : public CalculatorBase {
 public:
  ActiveSpeakerToRegionCalculator();
  ~ActiveSpeakerToRegionCalculator() override {}
  ActiveSpeakerToRegionCalculator(const ActiveSpeakerToRegionCalculator&) = delete;
  ActiveSpeakerToRegionCalculator& operator=(const ActiveSpeakerToRegionCalculator&) = delete;

  static ::mediapipe::Status GetContract(mediapipe::CalculatorContract* cc);
  ::mediapipe::Status Open(mediapipe::CalculatorContext* cc) override;
  ::mediapipe::Status Process(mediapipe::CalculatorContext* cc) override;

 private:
  // Calculator options.
  ActiveSpeakerToRegionCalculatorOptions options_;
  // A scorer used to assign weights to active speakers.
  std::unique_ptr<VisualScorer> scorer_;
  // Dimensions of video frame
  int frame_width_;
  int frame_height_;
}; // end with inheritance

REGISTER_CALCULATOR(ActiveSpeakerToRegionCalculator);

ActiveSpeakerToRegionCalculator::ActiveSpeakerToRegionCalculator() {}

::mediapipe::Status ActiveSpeakerToRegionCalculator::GetContract(
    mediapipe::CalculatorContract* cc) {
  if (cc->Inputs().HasTag(kInputVideo)) {
    cc->Inputs().Tag(kInputVideo).Set<ImageFrame>();
  }
  cc->Inputs().Tag(kInputRois).Set<std::vector<Detection>>();
  cc->Outputs().Tag(kOutputRegion).Set<DetectionSet>();
  return ::mediapipe::OkStatus();
}

::mediapipe::Status ActiveSpeakerToRegionCalculator::Open(
    mediapipe::CalculatorContext* cc) {
  options_ = cc->Options<ActiveSpeakerToRegionCalculatorOptions>();
  if (!cc->Inputs().HasTag(kInputVideo)) {
    RET_CHECK(!options_.use_visual_scorer())
        << "VIDEO input must be provided when using visual_scorer.";
  }

  scorer_ = absl::make_unique<VisualScorer>(options_.scorer_options());
  frame_width_ = -1;
  frame_height_ = -1;
  return ::mediapipe::OkStatus();
}

::mediapipe::Status ActiveSpeakerToRegionCalculator::Process(
    mediapipe::CalculatorContext* cc) {
  if (cc->Inputs().HasTag(kInputVideo) &&
      cc->Inputs().Tag(kInputVideo).Value().IsEmpty()) {
    return ::mediapipe::UnknownErrorBuilder(MEDIAPIPE_LOC)
           << "No VIDEO input at time " << cc->InputTimestamp().Seconds();
  }

  cv::Mat frame;
  if (cc->Inputs().HasTag(kInputVideo)) {
    frame = mediapipe::formats::MatView(
        &cc->Inputs().Tag(kInputVideo).Get<ImageFrame>());
    frame_width_ = frame.cols;
    frame_height_ = frame.rows;
  }

  auto region_set = ::absl::make_unique<DetectionSet>();
  if (!cc->Inputs().Tag(kInputRois).Value().IsEmpty()) {
    const auto& input_rois =
        cc->Inputs().Tag(kInputRois).Get<std::vector<Detection>>();

    for (const auto& input_roi : input_rois) {
      RET_CHECK(input_roi.location_data().format() ==
        mediapipe::LocationData::RELATIVE_BOUNDING_BOX)
        << "Speaker detection input is lacking required relative_bounding_box()";
      const auto& location = input_roi.location_data().relative_bounding_box();

      float x = std::max(0.0f, location.xmin());
      float y = std::max(0.0f, location.ymin());
      float width =
          std::min(location.width() - x + location.xmin(), 1 - x);
      float height =
          std::min(location.height() - y + location.ymin(), 1 - y);

      // Convert the text bounding box to a region.
      SalientRegion* region = region_set->add_detections();
      region->mutable_location_normalized()->set_x(x);
      region->mutable_location_normalized()->set_y(y);
      region->mutable_location_normalized()->set_width(width);
      region->mutable_location_normalized()->set_height(height);
      region->mutable_signal_type()->set_standard(SignalType::SPEAKER);

      // Score the scores based on image cues.
      float visual_score = 1.0f;
      if (options_.use_visual_scorer()) {
        MP_RETURN_IF_ERROR(
            scorer_->CalculateScore(frame, *region, &visual_score));
        }
      region->set_score(visual_score);
      }
    }
  cc->Outputs().Tag(kOutputRegion).Add(region_set.release(), cc->InputTimestamp());

  return ::mediapipe::OkStatus();
}

}  // namespace autoflip
}  // namespace mediapipe
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2006, 2008, 2009, 2010 Apple Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "config.h"
#include "core/html/HTMLViewSourceDocument.h"

#include "HTMLNames.h"
#include "core/dom/Attribute.h"
#include "core/dom/DOMImplementation.h"
#include "core/dom/DocumentStyleSheetCollection.h"
#include "core/dom/Text.h"
#include "core/html/HTMLAnchorElement.h"
#include "core/html/HTMLBRElement.h"
#include "core/html/HTMLBaseElement.h"
#include "core/html/HTMLBodyElement.h"
#include "core/html/HTMLDivElement.h"
#include "core/html/HTMLHtmlElement.h"
#include "core/html/HTMLTableCellElement.h"
#include "core/html/HTMLTableElement.h"
#include "core/html/HTMLTableRowElement.h"
#include "core/html/HTMLTableSectionElement.h"
#include "core/html/parser/HTMLToken.h"
#include "core/html/parser/HTMLViewSourceParser.h"
#include "core/html/parser/TextViewSourceParser.h"
#include "core/platform/text/SegmentedString.h"

namespace WebCore {

using namespace HTMLNames;

HTMLViewSourceDocument::HTMLViewSourceDocument(Frame* frame, const KURL& url, const String& mimeType)
    : HTMLDocument(frame, url)
    , m_type(mimeType)
{
    styleSheetCollection()->setUsesBeforeAfterRulesOverride(true);
    setIsViewSource(true);

    setCompatibilityMode(QuirksMode);
    lockCompatibilityMode();
}

PassRefPtr<DocumentParser> HTMLViewSourceDocument::createParser()
{
    if (m_type == "text/html" || m_type == "application/xhtml+xml" || m_type == "image/svg+xml" || DOMImplementation::isXMLMIMEType(m_type))
        return HTMLViewSourceParser::create(this);

    return TextViewSourceParser::create(this);
}

void HTMLViewSourceDocument::createContainingTable()
{
    RefPtr<HTMLHtmlElement> html = HTMLHtmlElement::create(this);
    parserAppendChild(html);
    html->attach();
    RefPtr<HTMLBodyElement> body = HTMLBodyElement::create(this);
    html->parserAppendChild(body);
    body->attach();

    // Create a line gutter div that can be used to make sure the gutter extends down the height of the whole
    // document.
    RefPtr<HTMLDivElement> div = HTMLDivElement::create(this);
    div->setAttribute(classAttr, "webkit-line-gutter-backdrop");
    body->parserAppendChild(div);
    div->attach();

    RefPtr<HTMLTableElement> table = HTMLTableElement::create(this);
    body->parserAppendChild(table);
    table->attach();
    m_tbody = HTMLTableSectionElement::create(tbodyTag, this);
    table->parserAppendChild(m_tbody);
    m_tbody->attach();
    m_current = m_tbody;
}

void HTMLViewSourceDocument::addSource(const String& source, HTMLToken& token)
{
    if (!m_current)
        createContainingTable();

    switch (token.type()) {
    case HTMLToken::Uninitialized:
        ASSERT_NOT_REACHED();
        break;
    case HTMLToken::DOCTYPE:
        processDoctypeToken(source, token);
        break;
    case HTMLToken::EndOfFile:
        if (!m_tbody->hasChildNodes())
            addLine(String());
        break;
    case HTMLToken::StartTag:
    case HTMLToken::EndTag:
        processTagToken(source, token);
        break;
    case HTMLToken::Comment:
        processCommentToken(source, token);
        break;
    case HTMLToken::Character:
        processCharacterToken(source, token);
        break;
    }
}

void HTMLViewSourceDocument::processDoctypeToken(const String& source, HTMLToken&)
{
    if (!m_current)
        createContainingTable();
    m_current = addSpanWithClassName("webkit-html-doctype");
    addText(source, "webkit-html-doctype");
    m_current = m_td;
}

void HTMLViewSourceDocument::processTagToken(const String& source, HTMLToken& token)
{
    m_current = addSpanWithClassName("webkit-html-tag");

    AtomicString tagName(token.name());

    unsigned index = 0;
    HTMLToken::AttributeList::const_iterator iter = token.attributes().begin();
    while (index < source.length()) {
        if (iter == token.attributes().end()) {
            // We want to show the remaining characters in the token.
            index = addRange(source, index, source.length(), "");
            ASSERT(index == source.length());
            break;
        }

        AtomicString name(iter->name);
        String value = StringImpl::create8BitIfPossible(iter->value);

        index = addRange(source, index, iter->nameRange.start - token.startIndex(), "");
        index = addRange(source, index, iter->nameRange.end - token.startIndex(), "webkit-html-attribute-name");

        if (tagName == baseTag && name == hrefAttr)
            m_current = addBase(value);

        index = addRange(source, index, iter->valueRange.start - token.startIndex(), "");

        bool isLink = name == srcAttr || name == hrefAttr;
        index = addRange(source, index, iter->valueRange.end - token.startIndex(), "webkit-html-attribute-value", isLink, tagName == aTag, value);

        ++iter;
    }
    m_current = m_td;
}

void HTMLViewSourceDocument::processCommentToken(const String& source, HTMLToken&)
{
    m_current = addSpanWithClassName("webkit-html-comment");
    addText(source, "webkit-html-comment");
    m_current = m_td;
}

void HTMLViewSourceDocument::processCharacterToken(const String& source, HTMLToken&)
{
    addText(source, "");
}

PassRefPtr<Element> HTMLViewSourceDocument::addSpanWithClassName(const AtomicString& className)
{
    if (m_current == m_tbody) {
        addLine(className);
        return m_current;
    }

    RefPtr<HTMLElement> span = HTMLElement::create(spanTag, this);
    span->setAttribute(classAttr, className);
    m_current->parserAppendChild(span);
    span->attach();
    return span.release();
}

void HTMLViewSourceDocument::addLine(const AtomicString& className)
{
    // Create a table row.
    RefPtr<HTMLTableRowElement> trow = HTMLTableRowElement::create(this);
    m_tbody->parserAppendChild(trow);
    trow->attach();

    // Create a cell that will hold the line number (it is generated in the stylesheet using counters).
    RefPtr<HTMLTableCellElement> td = HTMLTableCellElement::create(tdTag, this);
    td->setAttribute(classAttr, "webkit-line-number");
    trow->parserAppendChild(td);
    td->attach();

    // Create a second cell for the line contents
    td = HTMLTableCellElement::create(tdTag, this);
    td->setAttribute(classAttr, "webkit-line-content");
    trow->parserAppendChild(td);
    td->attach();
    m_current = m_td = td;

#ifdef DEBUG_LINE_NUMBERS
    RefPtr<Text> lineNumberText = Text::create(this, String::number(parser()->lineNumber() + 1) + " ");
    td->addChild(lineNumberText);
    lineNumberText->attach();
#endif

    // Open up the needed spans.
    if (!className.isEmpty()) {
        if (className == "webkit-html-attribute-name" || className == "webkit-html-attribute-value")
            m_current = addSpanWithClassName("webkit-html-tag");
        m_current = addSpanWithClassName(className);
    }
}

void HTMLViewSourceDocument::finishLine()
{
    if (!m_current->hasChildNodes()) {
        RefPtr<HTMLBRElement> br = HTMLBRElement::create(this);
        m_current->parserAppendChild(br);
        br->attach();
    }
    m_current = m_tbody;
}

void HTMLViewSourceDocument::addText(const String& text, const AtomicString& className)
{
    if (text.isEmpty())
        return;

    // Add in the content, splitting on newlines.
    Vector<String> lines;
    text.split('\n', true, lines);
    unsigned size = lines.size();
    for (unsigned i = 0; i < size; i++) {
        String substring = lines[i];
        if (m_current == m_tbody)
            addLine(className);
        if (substring.isEmpty()) {
            if (i == size - 1)
                break;
            finishLine();
            continue;
        }
        RefPtr<Text> t = Text::create(this, substring);
        m_current->parserAppendChild(t);
        t->attach();
        if (i < size - 1)
            finishLine();
    }
}

int HTMLViewSourceDocument::addRange(const String& source, int start, int end, const String& className, bool isLink, bool isAnchor, const String& link)
{
    ASSERT(start <= end);
    if (start == end)
        return start;

    String text = source.substring(start, end - start);
    if (!className.isEmpty()) {
        if (isLink)
            m_current = addLink(link, isAnchor);
        else
            m_current = addSpanWithClassName(className);
    }
    addText(text, className);
    if (!className.isEmpty() && m_current != m_tbody)
        m_current = toElement(m_current->parentNode());
    return end;
}

PassRefPtr<Element> HTMLViewSourceDocument::addBase(const AtomicString& href)
{
    RefPtr<HTMLBaseElement> base = HTMLBaseElement::create(baseTag, this);
    base->setAttribute(hrefAttr, href);
    m_current->parserAppendChild(base);
    base->attach();
    return base.release();
}

PassRefPtr<Element> HTMLViewSourceDocument::addLink(const AtomicString& url, bool isAnchor)
{
    if (m_current == m_tbody)
        addLine("webkit-html-tag");

    // Now create a link for the attribute value instead of a span.
    RefPtr<HTMLAnchorElement> anchor = HTMLAnchorElement::create(this);
    const char* classValue;
    if (isAnchor)
        classValue = "webkit-html-attribute-value webkit-html-external-link";
    else
        classValue = "webkit-html-attribute-value webkit-html-resource-link";
    anchor->setAttribute(classAttr, classValue);
    anchor->setAttribute(targetAttr, "_blank");
    anchor->setAttribute(hrefAttr, url);
    m_current->parserAppendChild(anchor);
    anchor->attach();
    return anchor.release();
}

}
<commit_msg>HTMLViewSourceDocument should lazyAttach<commit_after>/*
 * Copyright (C) 2006, 2008, 2009, 2010 Apple Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "config.h"
#include "core/html/HTMLViewSourceDocument.h"

#include "HTMLNames.h"
#include "core/dom/Attribute.h"
#include "core/dom/DOMImplementation.h"
#include "core/dom/DocumentStyleSheetCollection.h"
#include "core/dom/Text.h"
#include "core/html/HTMLAnchorElement.h"
#include "core/html/HTMLBRElement.h"
#include "core/html/HTMLBaseElement.h"
#include "core/html/HTMLBodyElement.h"
#include "core/html/HTMLDivElement.h"
#include "core/html/HTMLHtmlElement.h"
#include "core/html/HTMLTableCellElement.h"
#include "core/html/HTMLTableElement.h"
#include "core/html/HTMLTableRowElement.h"
#include "core/html/HTMLTableSectionElement.h"
#include "core/html/parser/HTMLToken.h"
#include "core/html/parser/HTMLViewSourceParser.h"
#include "core/html/parser/TextViewSourceParser.h"
#include "core/platform/text/SegmentedString.h"

namespace WebCore {

using namespace HTMLNames;

HTMLViewSourceDocument::HTMLViewSourceDocument(Frame* frame, const KURL& url, const String& mimeType)
    : HTMLDocument(frame, url)
    , m_type(mimeType)
{
    styleSheetCollection()->setUsesBeforeAfterRulesOverride(true);
    setIsViewSource(true);

    setCompatibilityMode(QuirksMode);
    lockCompatibilityMode();
}

PassRefPtr<DocumentParser> HTMLViewSourceDocument::createParser()
{
    if (m_type == "text/html" || m_type == "application/xhtml+xml" || m_type == "image/svg+xml" || DOMImplementation::isXMLMIMEType(m_type))
        return HTMLViewSourceParser::create(this);

    return TextViewSourceParser::create(this);
}

void HTMLViewSourceDocument::createContainingTable()
{
    RefPtr<HTMLHtmlElement> html = HTMLHtmlElement::create(this);
    parserAppendChild(html);
    html->lazyAttach();
    RefPtr<HTMLBodyElement> body = HTMLBodyElement::create(this);
    html->parserAppendChild(body);
    body->lazyAttach();

    // Create a line gutter div that can be used to make sure the gutter extends down the height of the whole
    // document.
    RefPtr<HTMLDivElement> div = HTMLDivElement::create(this);
    div->setAttribute(classAttr, "webkit-line-gutter-backdrop");
    body->parserAppendChild(div);
    div->lazyAttach();

    RefPtr<HTMLTableElement> table = HTMLTableElement::create(this);
    body->parserAppendChild(table);
    table->lazyAttach();
    m_tbody = HTMLTableSectionElement::create(tbodyTag, this);
    table->parserAppendChild(m_tbody);
    m_tbody->lazyAttach();
    m_current = m_tbody;
}

void HTMLViewSourceDocument::addSource(const String& source, HTMLToken& token)
{
    if (!m_current)
        createContainingTable();

    switch (token.type()) {
    case HTMLToken::Uninitialized:
        ASSERT_NOT_REACHED();
        break;
    case HTMLToken::DOCTYPE:
        processDoctypeToken(source, token);
        break;
    case HTMLToken::EndOfFile:
        if (!m_tbody->hasChildNodes())
            addLine(String());
        break;
    case HTMLToken::StartTag:
    case HTMLToken::EndTag:
        processTagToken(source, token);
        break;
    case HTMLToken::Comment:
        processCommentToken(source, token);
        break;
    case HTMLToken::Character:
        processCharacterToken(source, token);
        break;
    }
}

void HTMLViewSourceDocument::processDoctypeToken(const String& source, HTMLToken&)
{
    m_current = addSpanWithClassName("webkit-html-doctype");
    addText(source, "webkit-html-doctype");
    m_current = m_td;
}

void HTMLViewSourceDocument::processTagToken(const String& source, HTMLToken& token)
{
    m_current = addSpanWithClassName("webkit-html-tag");

    AtomicString tagName(token.name());

    unsigned index = 0;
    HTMLToken::AttributeList::const_iterator iter = token.attributes().begin();
    while (index < source.length()) {
        if (iter == token.attributes().end()) {
            // We want to show the remaining characters in the token.
            index = addRange(source, index, source.length(), "");
            ASSERT(index == source.length());
            break;
        }

        AtomicString name(iter->name);
        String value = StringImpl::create8BitIfPossible(iter->value);

        index = addRange(source, index, iter->nameRange.start - token.startIndex(), "");
        index = addRange(source, index, iter->nameRange.end - token.startIndex(), "webkit-html-attribute-name");

        if (tagName == baseTag && name == hrefAttr)
            m_current = addBase(value);

        index = addRange(source, index, iter->valueRange.start - token.startIndex(), "");

        bool isLink = name == srcAttr || name == hrefAttr;
        index = addRange(source, index, iter->valueRange.end - token.startIndex(), "webkit-html-attribute-value", isLink, tagName == aTag, value);

        ++iter;
    }
    m_current = m_td;
}

void HTMLViewSourceDocument::processCommentToken(const String& source, HTMLToken&)
{
    m_current = addSpanWithClassName("webkit-html-comment");
    addText(source, "webkit-html-comment");
    m_current = m_td;
}

void HTMLViewSourceDocument::processCharacterToken(const String& source, HTMLToken&)
{
    addText(source, "");
}

PassRefPtr<Element> HTMLViewSourceDocument::addSpanWithClassName(const AtomicString& className)
{
    if (m_current == m_tbody) {
        addLine(className);
        return m_current;
    }

    RefPtr<HTMLElement> span = HTMLElement::create(spanTag, this);
    span->setAttribute(classAttr, className);
    m_current->parserAppendChild(span);
    span->lazyAttach();
    return span.release();
}

void HTMLViewSourceDocument::addLine(const AtomicString& className)
{
    // Create a table row.
    RefPtr<HTMLTableRowElement> trow = HTMLTableRowElement::create(this);
    m_tbody->parserAppendChild(trow);
    trow->lazyAttach();

    // Create a cell that will hold the line number (it is generated in the stylesheet using counters).
    RefPtr<HTMLTableCellElement> td = HTMLTableCellElement::create(tdTag, this);
    td->setAttribute(classAttr, "webkit-line-number");
    trow->parserAppendChild(td);
    td->lazyAttach();

    // Create a second cell for the line contents
    td = HTMLTableCellElement::create(tdTag, this);
    td->setAttribute(classAttr, "webkit-line-content");
    trow->parserAppendChild(td);
    td->lazyAttach();
    m_current = m_td = td;

#ifdef DEBUG_LINE_NUMBERS
    RefPtr<Text> lineNumberText = Text::create(this, String::number(parser()->lineNumber() + 1) + " ");
    td->addChild(lineNumberText);
    lineNumberText->lazyAttach();
#endif

    // Open up the needed spans.
    if (!className.isEmpty()) {
        if (className == "webkit-html-attribute-name" || className == "webkit-html-attribute-value")
            m_current = addSpanWithClassName("webkit-html-tag");
        m_current = addSpanWithClassName(className);
    }
}

void HTMLViewSourceDocument::finishLine()
{
    if (!m_current->hasChildNodes()) {
        RefPtr<HTMLBRElement> br = HTMLBRElement::create(this);
        m_current->parserAppendChild(br);
        br->lazyAttach();
    }
    m_current = m_tbody;
}

void HTMLViewSourceDocument::addText(const String& text, const AtomicString& className)
{
    if (text.isEmpty())
        return;

    // Add in the content, splitting on newlines.
    Vector<String> lines;
    text.split('\n', true, lines);
    unsigned size = lines.size();
    for (unsigned i = 0; i < size; i++) {
        String substring = lines[i];
        if (m_current == m_tbody)
            addLine(className);
        if (substring.isEmpty()) {
            if (i == size - 1)
                break;
            finishLine();
            continue;
        }
        RefPtr<Text> t = Text::create(this, substring);
        m_current->parserAppendChild(t);
        t->lazyAttach();
        if (i < size - 1)
            finishLine();
    }
}

int HTMLViewSourceDocument::addRange(const String& source, int start, int end, const String& className, bool isLink, bool isAnchor, const String& link)
{
    ASSERT(start <= end);
    if (start == end)
        return start;

    String text = source.substring(start, end - start);
    if (!className.isEmpty()) {
        if (isLink)
            m_current = addLink(link, isAnchor);
        else
            m_current = addSpanWithClassName(className);
    }
    addText(text, className);
    if (!className.isEmpty() && m_current != m_tbody)
        m_current = toElement(m_current->parentNode());
    return end;
}

PassRefPtr<Element> HTMLViewSourceDocument::addBase(const AtomicString& href)
{
    RefPtr<HTMLBaseElement> base = HTMLBaseElement::create(baseTag, this);
    base->setAttribute(hrefAttr, href);
    m_current->parserAppendChild(base);
    base->lazyAttach();
    return base.release();
}

PassRefPtr<Element> HTMLViewSourceDocument::addLink(const AtomicString& url, bool isAnchor)
{
    if (m_current == m_tbody)
        addLine("webkit-html-tag");

    // Now create a link for the attribute value instead of a span.
    RefPtr<HTMLAnchorElement> anchor = HTMLAnchorElement::create(this);
    const char* classValue;
    if (isAnchor)
        classValue = "webkit-html-attribute-value webkit-html-external-link";
    else
        classValue = "webkit-html-attribute-value webkit-html-resource-link";
    anchor->setAttribute(classAttr, classValue);
    anchor->setAttribute(targetAttr, "_blank");
    anchor->setAttribute(hrefAttr, url);
    m_current->parserAppendChild(anchor);
    anchor->lazyAttach();
    return anchor.release();
}

}
<|endoftext|>


<commit_before>#include<iostream>
#include<hc.hpp>
#include<eap_resources.hpp>
#include<lua_cmds.hpp>
#include<boost/format.hpp>
#include<boost/filesystem.hpp>

namespace
{
    const std::string c_iterations = "iterations";
    const std::string c_convergence_factor = "convergence_factor";
}

hc::hc(std::string lua_file) : algorithm(lua_file)
{
    m_convergence_factor = 0.0f;
    m_best_fitness = 0.0f;
    m_converged_iterations = 0.0f;
}

/**
 * @desc Loads parameters for the hill climber algorithm
 */
void hc::setup_algo_params()
{
    try
    {
        algorithm::setup_algo_params();
        m_iterations = eap::get_fvalue(c_iterations);
        m_convergence_factor = eap::get_fvalue(c_convergence_factor);
        m_converged_iterations = m_iterations * m_convergence_factor;
        std::cout<<"***completed HC parameter setup"<<std::endl;
    }
    catch (const eap::InvalidStateException &e)
    {
        std::cerr<<e.what()<<"\n";
    }
}

/**
 * @desc Implements logic for HC runs
 */
void hc::run(unsigned int run_id)
{
    std::ofstream outfile;
    try
    {
        std::vector<position_ptr> placements;
        outfile.open(eap::results_directory + boost::filesystem::basename(m_lua_file) + "_r" + std::to_string(run_id) + "iters.csv");
        boost::format nec_input(eap::run_directory + "iter%09d");
        int q = 0; // successive state with best solution

        for (ant_config_ptr i_ant : m_ant_configs)
        {
            int pos;
            do
            {
                pos = eap::rand(0, i_ant->m_positions.size() - 1);
            } while(overlap(placements, i_ant->m_positions[pos]));
            placements.push_back(i_ant->m_positions[pos]);
        }

        m_p_parent = create_individual(str(nec_input % 0) + "a%02d.nec", placements);
        evaluate(0, m_p_parent);
        m_best_fitness = m_p_parent->m_fitness;
        outfile << 0 << "," << m_p_parent->m_fitness << "," << m_p_parent->m_gain_fitness << "," << m_p_parent->m_coupling_fitness << ",";
        for (position_ptr p_pos : m_p_parent->m_positions)
            outfile << p_pos->m_x << "," << p_pos->m_y << "," << p_pos->m_z <<",";
        outfile << "\n";

        for (unsigned int i=1; i<m_iterations; ++i)
        {
            std::vector<position_ptr> placements = mutate_pos_once(m_p_parent->m_positions);
            individual_ptr p_child = create_individual(str(nec_input % i) + "a%02d.nec", placements);
            evaluate(i, p_child);

            if (p_child->m_fitness < m_p_parent->m_fitness)
            {
                m_best_fitness = p_child->m_fitness;
                swap(m_p_parent, p_child);
                outfile << i << "," << m_p_parent->m_fitness << "," << m_p_parent->m_gain_fitness << "," << m_p_parent->m_coupling_fitness << ",";
                for (position_ptr p_pos : m_p_parent->m_positions)
                    outfile << p_pos->m_x << "," << p_pos->m_y << "," << p_pos->m_z <<",";
                outfile << "\n";
                std::cout<<"***iter="<<i<<", best ind "<<m_p_parent->m_fitness<<"\n";
            }

            if (m_p_parent->m_fitness >= m_best_fitness)
                q++;
            else
                q=0;

            if (q > m_converged_iterations)
            {
                //change mutation probability
                m_mutation *= 1.1;
                std::cout<<"***mutatation_prob changed to "<<m_mutation<<"\n";
                q = 0;
            }
            // remove all after an iteration
            boost::filesystem::path path_to_remove(eap::run_directory);
            for (boost::filesystem::directory_iterator end_dir_it, it(path_to_remove); it!=end_dir_it; ++it)
                remove_all(it->path());

            if (abs(m_p_parent->m_fitness - 0.496877) > 0.0000001) //exit condition for tc2
                break;
        }

        outfile.close();
    }

    catch (...)
    {
        outfile.close();
        throw;
    }
}

void hc::evaluate(unsigned int id, individual_ptr &p_ind)
{
    try
    {
        run_simulation(id);
        boost::format nec_output(eap::run_directory + "iter%09da%02d.out");
        for (unsigned int i_ant=0; i_ant<m_ant_configs.size(); ++i_ant)
        {
            evaluation_ptr p_eval(new evaluation);
            p_ind->m_evals.push_back(p_eval);
            unsigned int read = read_radiation(str(nec_output % id % i_ant), p_eval);
            if (read != (num_polar() * m_step_freq))
                throw eap::InvalidStateException("HC:Problem with output in " + str(nec_output % id % i_ant));
            p_ind->m_one_ant_on_fitness.push_back(compare(m_free_inds[i_ant]->m_evals[0], p_ind->m_evals[i_ant]));
            p_ind->m_gain_fitness += p_ind->m_one_ant_on_fitness[i_ant];
        }
        p_ind->m_gain_fitness /= m_max_gain;
        p_ind->m_coupling_fitness = read_coupling(str(nec_output % id % m_ant_configs.size()), m_ant_configs.size());
        //normalizing fitness
        p_ind->m_coupling_fitness += std::abs(m_min_coup);
        p_ind->m_coupling_fitness /= m_max_coup;
        p_ind->m_fitness = cal_fitness(p_ind);
    }
    catch (...)
    {
        throw;
    }
}

void hc::run_simulation(unsigned int id)
{
    try
    {
        boost::format formatter("ls " + eap::run_directory + "iter%09da*.nec | parallel -j+0 nec2++ -i {}");
        system(str(formatter % id).c_str());
        std::cout<<"***completed simulation for iteration "<<id<<"\n";
    }
    catch (...)
    {
        throw;
    }
}

hc::~hc(void)
{
}
<commit_msg>hc converged iterations<commit_after>#include<iostream>
#include<hc.hpp>
#include<eap_resources.hpp>
#include<lua_cmds.hpp>
#include<boost/format.hpp>
#include<boost/filesystem.hpp>

namespace
{
    const std::string c_iterations = "iterations";
    const std::string c_convergence_factor = "convergence_factor";
}

hc::hc(std::string lua_file) : algorithm(lua_file)
{
    m_convergence_factor = 0.0f;
    m_best_fitness = 0.0f;
    m_converged_iterations = 0.0f;
}

/**
 * @desc Loads parameters for the hill climber algorithm
 */
void hc::setup_algo_params()
{
    try
    {
        algorithm::setup_algo_params();
        m_iterations = eap::get_fvalue(c_iterations);
        m_convergence_factor = eap::get_fvalue(c_convergence_factor);
        m_converged_iterations = m_iterations * m_convergence_factor;
        std::cout<<"***completed HC parameter setup"<<std::endl;
    }
    catch (const eap::InvalidStateException &e)
    {
        std::cerr<<e.what()<<"\n";
    }
}

/**
 * @desc Implements logic for HC runs
 */
void hc::run(unsigned int run_id)
{
    std::ofstream outfile;
    try
    {
        std::vector<position_ptr> placements;
        outfile.open(eap::results_directory + boost::filesystem::basename(m_lua_file) + "_r" + std::to_string(run_id) + "iters.csv");
        boost::format nec_input(eap::run_directory + "iter%09d");
        int q = 0; // successive state with best solution

        for (ant_config_ptr i_ant : m_ant_configs)
        {
            int pos;
            do
            {
                pos = eap::rand(0, i_ant->m_positions.size() - 1);
            } while(overlap(placements, i_ant->m_positions[pos]));
            placements.push_back(i_ant->m_positions[pos]);
        }

        m_p_parent = create_individual(str(nec_input % 0) + "a%02d.nec", placements);
        evaluate(0, m_p_parent);
        m_best_fitness = m_p_parent->m_fitness;
        outfile << 0 << "," << m_p_parent->m_fitness << "," << m_p_parent->m_gain_fitness << "," << m_p_parent->m_coupling_fitness << ",";
        for (position_ptr p_pos : m_p_parent->m_positions)
            outfile << p_pos->m_x << "," << p_pos->m_y << "," << p_pos->m_z <<",";
        outfile << "\n";

        for (unsigned int i=1; i<m_iterations; ++i)
        {
            std::vector<position_ptr> placements = mutate_pos_once(m_p_parent->m_positions);
            individual_ptr p_child = create_individual(str(nec_input % i) + "a%02d.nec", placements);
            evaluate(i, p_child);

            if (p_child->m_fitness < m_p_parent->m_fitness)
            {
                m_best_fitness = p_child->m_fitness;
                swap(m_p_parent, p_child);
                outfile << i << "," << m_p_parent->m_fitness << "," << m_p_parent->m_gain_fitness << "," << m_p_parent->m_coupling_fitness << ",";
                for (position_ptr p_pos : m_p_parent->m_positions)
                    outfile << p_pos->m_x << "," << p_pos->m_y << "," << p_pos->m_z <<",";
                outfile << "\n";
                std::cout<<"***iter="<<i<<", best ind "<<m_p_parent->m_fitness<<"\n";
            }

            if (m_p_parent->m_fitness >= m_best_fitness)
                q++;
            else
                q=0;

            if (q > m_converged_iterations)
            {
                break;
            }
            // remove all after an iteration
            boost::filesystem::path path_to_remove(eap::run_directory);
            for (boost::filesystem::directory_iterator end_dir_it, it(path_to_remove); it!=end_dir_it; ++it)
                remove_all(it->path());

        }

        outfile.close();
    }

    catch (...)
    {
        outfile.close();
        throw;
    }
}

void hc::evaluate(unsigned int id, individual_ptr &p_ind)
{
    try
    {
        run_simulation(id);
        boost::format nec_output(eap::run_directory + "iter%09da%02d.out");
        for (unsigned int i_ant=0; i_ant<m_ant_configs.size(); ++i_ant)
        {
            evaluation_ptr p_eval(new evaluation);
            p_ind->m_evals.push_back(p_eval);
            unsigned int read = read_radiation(str(nec_output % id % i_ant), p_eval);
            if (read != (num_polar() * m_step_freq))
                throw eap::InvalidStateException("HC:Problem with output in " + str(nec_output % id % i_ant));
            p_ind->m_one_ant_on_fitness.push_back(compare(m_free_inds[i_ant]->m_evals[0], p_ind->m_evals[i_ant]));
            p_ind->m_gain_fitness += p_ind->m_one_ant_on_fitness[i_ant];
        }
        p_ind->m_gain_fitness /= m_max_gain;
        p_ind->m_coupling_fitness = read_coupling(str(nec_output % id % m_ant_configs.size()), m_ant_configs.size());
        //normalizing fitness
        p_ind->m_coupling_fitness += std::abs(m_min_coup);
        p_ind->m_coupling_fitness /= m_max_coup;
        p_ind->m_fitness = cal_fitness(p_ind);
    }
    catch (...)
    {
        throw;
    }
}

void hc::run_simulation(unsigned int id)
{
    try
    {
        boost::format formatter("ls " + eap::run_directory + "iter%09da*.nec | parallel -j+0 nec2++ -i {}");
        system(str(formatter % id).c_str());
        std::cout<<"***completed simulation for iteration "<<id<<"\n";
    }
    catch (...)
    {
        throw;
    }
}

hc::~hc(void)
{
}
<|endoftext|>


<commit_before>/**
 * Copyright (c) 2016-present, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 */

#include "SimpleInline.h"
#include "InlineHelper.h"
#include "Deleter.h"
#include "DexClass.h"
#include "DexInstruction.h"
#include "DexUtil.h"
#include "Resolver.h"
#include "Transform.h"
#include "Walkers.h"
#include "ReachableClasses.h"
#include "VirtualScope.h"

#include <algorithm>
#include <string>
#include <vector>
#include <map>
#include <set>

namespace {

// the max number of callers we care to track explicitly, after that we
// group all callees/callers count in the same bucket
const int MAX_COUNT = 10;

DEBUG_ONLY bool method_breakup(
    std::vector<std::vector<DexMethod*>>& calls_group) {
  size_t size = calls_group.size();
  for (size_t i = 0; i < size; ++i) {
    size_t inst = 0;
    size_t stat = 0;
    auto group = calls_group[i];
    for (auto callee : group) {
      is_static(callee) ? stat++ : inst++;
    }
    TRACE(SINL, 5, "%ld callers %ld: instance %ld, static %ld\n",
        i, group.size(), inst, stat);
  }
  return true;
}

std::unordered_set<DexType*> no_inline_annos(
  const std::vector<std::string>& annos,
  ConfigFiles& cfg
) {
  std::unordered_set<DexType*> no_inline;
  for (const auto& anno : cfg.get_no_optimizations_annos()) {
    no_inline.insert(anno);
  }
  for (auto const& no_inline_anno : annos) {
    auto type = DexType::get_type(
        DexString::get_string(no_inline_anno.c_str()));
    if (type != nullptr) {
      no_inline.insert(type);
    }
  }
  return no_inline;
}

std::unordered_set<DexType*> force_inline_annos(
    const std::vector<std::string>& annos) {
  std::unordered_set<DexType*> force_inline;
  for (auto const& force_inline_anno : annos) {
    auto type = DexType::get_type(force_inline_anno.c_str());
    if (type != nullptr) {
      force_inline.insert(type);
    }
  }
  return force_inline;
}

template<typename DexMember>
bool has_anno(DexMember* m, const std::unordered_set<DexType*>& no_inline) {
  if (no_inline.size() == 0) return false;
  if (m != nullptr && m->get_anno_set() != nullptr) {
    for (const auto& anno : m->get_anno_set()->get_annotations()) {
      if (no_inline.count(anno->type()) > 0) {
        return true;
      }
    }
  }
  return false;
}

}

void SimpleInlinePass::run_pass(DexStoresVector& stores, ConfigFiles& cfg, PassManager& mgr) {
  if (mgr.no_proguard_rules()) {
    TRACE(SINL, 1, "SimpleInlinePass not run because no ProGuard configuration was provided.");
    return;
  }
  const auto no_inline = no_inline_annos(m_no_inline_annos, cfg);
  const auto force_inline = force_inline_annos(m_force_inline_annos);

  auto scope = build_class_scope(stores);
  // gather all inlinable candidates
  auto methods = gather_non_virtual_methods(scope, no_inline, force_inline);
  select_single_called(scope, methods);

  auto resolver = [&](DexMethod* method, MethodSearch search) {
    return resolve_method(method, search, resolved_refs);
  };

  // inline candidates
  MultiMethodInliner inliner(
      scope, stores[0].get_dexen()[0], inlinable, resolver, m_inliner_config);
  inliner.inline_methods();

  MethodTransform::sync_all(scope);
  MethodTransform::balloon_all(scope);

  // delete all methods that can be deleted
  auto inlined = inliner.get_inlined();
  size_t inlined_count = inlined.size();
  size_t deleted = delete_methods(scope, inlined, resolver);

  TRACE(SINL, 3, "recursive %ld\n", inliner.get_info().recursive);
  TRACE(SINL, 3, "blacklisted meths %ld\n", inliner.get_info().blacklisted);
  TRACE(SINL, 3, "more than 16 regs %ld\n",
      inliner.get_info().more_than_16regs);
  TRACE(SINL, 3, "try/catch in callee %ld\n",
      inliner.get_info().try_catch_block);
  TRACE(SINL, 3, "try/catch in caller %ld\n",
      inliner.get_info().caller_tries);
  TRACE(SINL, 3, "virtualizing methods %ld\n", inliner.get_info().need_vmethod);
  TRACE(SINL, 3, "invoke super %ld\n", inliner.get_info().invoke_super);
  TRACE(SINL, 3, "override inputs %ld\n", inliner.get_info().write_over_ins);
  TRACE(SINL, 3, "escaped virtual %ld\n", inliner.get_info().escaped_virtual);
  TRACE(SINL, 3, "known non public virtual %ld\n",
      inliner.get_info().non_pub_virtual);
  TRACE(SINL, 3, "non public ctor %ld\n", inliner.get_info().non_pub_ctor);
  TRACE(SINL, 3, "unknown field %ld\n", inliner.get_info().escaped_field);
  TRACE(SINL, 3, "non public field %ld\n", inliner.get_info().non_pub_field);
  TRACE(SINL, 3, "throws %ld\n", inliner.get_info().throws);
  TRACE(SINL, 3, "multiple returns %ld\n", inliner.get_info().multi_ret);
  TRACE(SINL, 3, "reference outside of primary %ld\n",
      inliner.get_info().not_in_primary);
  TRACE(SINL, 3, "not found %ld\n", inliner.get_info().not_found);
  TRACE(SINL, 3, "caller too large %ld\n", inliner.get_info().caller_too_large);
  TRACE(SINL, 1,
      "%ld inlined calls over %ld methods and %ld methods removed\n",
      inliner.get_info().calls_inlined, inlined_count, deleted);

  mgr.incr_metric("calls_inlined", inliner.get_info().calls_inlined);
  mgr.incr_metric("methods_removed", deleted);
}

/**
 * Collect all non virtual methods and make all small methods candidates
 * for inlining.
 */
std::unordered_set<DexMethod*> SimpleInlinePass::gather_non_virtual_methods(
    Scope& scope,
    const std::unordered_set<DexType*>& no_inline,
    const std::unordered_set<DexType*>& force_inline) {
  // trace counter
  size_t all_methods = 0;
  size_t direct_methods = 0;
  size_t direct_no_code = 0;
  size_t non_virtual_no_code = 0;
  size_t clinit = 0;
  size_t init = 0;
  size_t static_methods = 0;
  size_t private_methods = 0;
  size_t dont_strip = 0;
  size_t no_inline_anno_count = 0;
  size_t non_virt_dont_strip = 0;
  size_t non_virt_methods = 0;

  // collect all non virtual methods (dmethods and vmethods)
  std::unordered_set<DexMethod*> methods;

  const auto can_inline_method = [&](DexMethod* meth, const DexCode& code) {
    DexClass* cls = type_class(meth->get_class());
    if (has_anno(cls, no_inline) ||
        has_anno(meth, no_inline)) {
      no_inline_anno_count++;
      return;
    }
    if (code.get_entries()->count_opcodes() < SMALL_CODE_SIZE) {
      // always inline small methods even if they are not deletable
      inlinable.insert(meth);
    } else {
      if (!can_delete(meth)) {
        // never inline methods that cannot be deleted
        TRACE(SINL, 4, "cannot_delete: %s\n", SHOW(meth));
        dont_strip++;
      } else {
        methods.insert(meth);
      }
    }

    if (has_anno(meth, force_inline)) {
      inlinable.insert(meth);
    }
  };

  walk_methods(scope,
      [&](DexMethod* method) {
        all_methods++;
        if (method->is_virtual()) return;

        auto& code = method->get_code();
        bool dont_inline = code == nullptr;

        direct_methods++;
        if (code == nullptr) direct_no_code++;
        if (is_constructor(method)) {
          (is_static(method)) ? clinit++ : init++;
          dont_inline = true;
        } else {
          (is_static(method)) ? static_methods++ : private_methods++;
        }

        if (dont_inline) return;

        can_inline_method(method, *code);
      });
  if (m_virtual_inline) {
    auto non_virtual = devirtualize(scope);
    non_virt_methods = non_virtual.size();
    for (const auto& vmeth : non_virtual) {
      auto& code = vmeth->get_code();
      if (code == nullptr) {
        non_virtual_no_code++;
        continue;
      }
      can_inline_method(vmeth, *code);
    }
  }

  TRACE(SINL, 2, "All methods count: %ld\n", all_methods);
  TRACE(SINL, 2, "Direct methods count: %ld\n", direct_methods);
  TRACE(SINL, 2, "Virtual methods count: %ld\n", all_methods - direct_methods);
  TRACE(SINL, 2, "Direct methods no code: %ld\n", direct_no_code);
  TRACE(SINL, 2, "Direct methods with code: %ld\n",
      direct_methods - direct_no_code);
  TRACE(SINL, 2, "Constructors with or without code: %ld\n", init);
  TRACE(SINL, 2, "Static constructors: %ld\n", clinit);
  TRACE(SINL, 2, "Static methods: %ld\n", static_methods);
  TRACE(SINL, 2, "Private methods: %ld\n", private_methods);
  TRACE(SINL, 2, "Virtual methods non virtual count: %ld\n", non_virt_methods);
  TRACE(SINL, 2, "Non virtual no code count: %ld\n", non_virtual_no_code);
  TRACE(SINL, 2, "Non virtual no strip count: %ld\n", non_virt_dont_strip);
  TRACE(SINL, 2, "Small methods: %ld\n", inlinable.size());
  TRACE(SINL, 2, "Don't strip inlinable methods count: %ld\n", dont_strip);
  TRACE(SINL, 2, "Don't inline annotation count: %ld\n", no_inline_anno_count);
  return methods;
}

/**
 * Add to the list the single called.
 */
void SimpleInlinePass::select_single_called(
    Scope& scope, std::unordered_set<DexMethod*>& methods) {
  std::unordered_map<DexMethod*, int> calls;
  for (const auto& method : methods) {
    calls[method] = 0;
  }
  // count call sites for each method
  walk_opcodes(scope, [](DexMethod* meth) { return true; },
      [&](DexMethod* meth, DexInstruction* insn) {
        if (is_invoke(insn->opcode())) {
          auto mop = static_cast<DexOpcodeMethod*>(insn);
          auto callee = resolve_method(
              mop->get_method(), opcode_to_search(insn), resolved_refs);
          if (callee != nullptr && callee->is_concrete()
              && methods.count(callee) > 0) {
            calls[callee]++;
          }
        }
      });

  // pick methods with a single call site and add to candidates.
  // This vector usage is only because of logging we should remove it
  // once the optimization is "closed"
  std::vector<std::vector<DexMethod*>> calls_group(MAX_COUNT);
  for (auto call_it : calls) {
    if (call_it.second >= MAX_COUNT) {
      calls_group[MAX_COUNT - 1].push_back(call_it.first);
      continue;
    }
    calls_group[call_it.second].push_back(call_it.first);
  }
  assert(method_breakup(calls_group));
  for (auto callee : calls_group[1]) {
    inlinable.insert(callee);
  }
}

static SimpleInlinePass s_pass;
<commit_msg>Don't call sync_all after SimpleInline<commit_after>/**
 * Copyright (c) 2016-present, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 */

#include "SimpleInline.h"
#include "InlineHelper.h"
#include "Deleter.h"
#include "DexClass.h"
#include "DexInstruction.h"
#include "DexUtil.h"
#include "Resolver.h"
#include "Transform.h"
#include "Walkers.h"
#include "ReachableClasses.h"
#include "VirtualScope.h"

#include <algorithm>
#include <string>
#include <vector>
#include <map>
#include <set>

namespace {

// the max number of callers we care to track explicitly, after that we
// group all callees/callers count in the same bucket
const int MAX_COUNT = 10;

DEBUG_ONLY bool method_breakup(
    std::vector<std::vector<DexMethod*>>& calls_group) {
  size_t size = calls_group.size();
  for (size_t i = 0; i < size; ++i) {
    size_t inst = 0;
    size_t stat = 0;
    auto group = calls_group[i];
    for (auto callee : group) {
      is_static(callee) ? stat++ : inst++;
    }
    TRACE(SINL, 5, "%ld callers %ld: instance %ld, static %ld\n",
        i, group.size(), inst, stat);
  }
  return true;
}

std::unordered_set<DexType*> no_inline_annos(
  const std::vector<std::string>& annos,
  ConfigFiles& cfg
) {
  std::unordered_set<DexType*> no_inline;
  for (const auto& anno : cfg.get_no_optimizations_annos()) {
    no_inline.insert(anno);
  }
  for (auto const& no_inline_anno : annos) {
    auto type = DexType::get_type(
        DexString::get_string(no_inline_anno.c_str()));
    if (type != nullptr) {
      no_inline.insert(type);
    }
  }
  return no_inline;
}

std::unordered_set<DexType*> force_inline_annos(
    const std::vector<std::string>& annos) {
  std::unordered_set<DexType*> force_inline;
  for (auto const& force_inline_anno : annos) {
    auto type = DexType::get_type(force_inline_anno.c_str());
    if (type != nullptr) {
      force_inline.insert(type);
    }
  }
  return force_inline;
}

template<typename DexMember>
bool has_anno(DexMember* m, const std::unordered_set<DexType*>& no_inline) {
  if (no_inline.size() == 0) return false;
  if (m != nullptr && m->get_anno_set() != nullptr) {
    for (const auto& anno : m->get_anno_set()->get_annotations()) {
      if (no_inline.count(anno->type()) > 0) {
        return true;
      }
    }
  }
  return false;
}

}

void SimpleInlinePass::run_pass(DexStoresVector& stores, ConfigFiles& cfg, PassManager& mgr) {
  if (mgr.no_proguard_rules()) {
    TRACE(SINL, 1, "SimpleInlinePass not run because no ProGuard configuration was provided.");
    return;
  }
  const auto no_inline = no_inline_annos(m_no_inline_annos, cfg);
  const auto force_inline = force_inline_annos(m_force_inline_annos);

  auto scope = build_class_scope(stores);
  // gather all inlinable candidates
  auto methods = gather_non_virtual_methods(scope, no_inline, force_inline);
  select_single_called(scope, methods);

  auto resolver = [&](DexMethod* method, MethodSearch search) {
    return resolve_method(method, search, resolved_refs);
  };

  // inline candidates
  MultiMethodInliner inliner(
      scope, stores[0].get_dexen()[0], inlinable, resolver, m_inliner_config);
  inliner.inline_methods();

  // delete all methods that can be deleted
  auto inlined = inliner.get_inlined();
  size_t inlined_count = inlined.size();
  size_t deleted = delete_methods(scope, inlined, resolver);

  TRACE(SINL, 3, "recursive %ld\n", inliner.get_info().recursive);
  TRACE(SINL, 3, "blacklisted meths %ld\n", inliner.get_info().blacklisted);
  TRACE(SINL, 3, "more than 16 regs %ld\n",
      inliner.get_info().more_than_16regs);
  TRACE(SINL, 3, "try/catch in callee %ld\n",
      inliner.get_info().try_catch_block);
  TRACE(SINL, 3, "try/catch in caller %ld\n",
      inliner.get_info().caller_tries);
  TRACE(SINL, 3, "virtualizing methods %ld\n", inliner.get_info().need_vmethod);
  TRACE(SINL, 3, "invoke super %ld\n", inliner.get_info().invoke_super);
  TRACE(SINL, 3, "override inputs %ld\n", inliner.get_info().write_over_ins);
  TRACE(SINL, 3, "escaped virtual %ld\n", inliner.get_info().escaped_virtual);
  TRACE(SINL, 3, "known non public virtual %ld\n",
      inliner.get_info().non_pub_virtual);
  TRACE(SINL, 3, "non public ctor %ld\n", inliner.get_info().non_pub_ctor);
  TRACE(SINL, 3, "unknown field %ld\n", inliner.get_info().escaped_field);
  TRACE(SINL, 3, "non public field %ld\n", inliner.get_info().non_pub_field);
  TRACE(SINL, 3, "throws %ld\n", inliner.get_info().throws);
  TRACE(SINL, 3, "multiple returns %ld\n", inliner.get_info().multi_ret);
  TRACE(SINL, 3, "reference outside of primary %ld\n",
      inliner.get_info().not_in_primary);
  TRACE(SINL, 3, "not found %ld\n", inliner.get_info().not_found);
  TRACE(SINL, 3, "caller too large %ld\n", inliner.get_info().caller_too_large);
  TRACE(SINL, 1,
      "%ld inlined calls over %ld methods and %ld methods removed\n",
      inliner.get_info().calls_inlined, inlined_count, deleted);

  mgr.incr_metric("calls_inlined", inliner.get_info().calls_inlined);
  mgr.incr_metric("methods_removed", deleted);
}

/**
 * Collect all non virtual methods and make all small methods candidates
 * for inlining.
 */
std::unordered_set<DexMethod*> SimpleInlinePass::gather_non_virtual_methods(
    Scope& scope,
    const std::unordered_set<DexType*>& no_inline,
    const std::unordered_set<DexType*>& force_inline) {
  // trace counter
  size_t all_methods = 0;
  size_t direct_methods = 0;
  size_t direct_no_code = 0;
  size_t non_virtual_no_code = 0;
  size_t clinit = 0;
  size_t init = 0;
  size_t static_methods = 0;
  size_t private_methods = 0;
  size_t dont_strip = 0;
  size_t no_inline_anno_count = 0;
  size_t non_virt_dont_strip = 0;
  size_t non_virt_methods = 0;

  // collect all non virtual methods (dmethods and vmethods)
  std::unordered_set<DexMethod*> methods;

  const auto can_inline_method = [&](DexMethod* meth, const DexCode& code) {
    DexClass* cls = type_class(meth->get_class());
    if (has_anno(cls, no_inline) ||
        has_anno(meth, no_inline)) {
      no_inline_anno_count++;
      return;
    }
    if (code.get_entries()->count_opcodes() < SMALL_CODE_SIZE) {
      // always inline small methods even if they are not deletable
      inlinable.insert(meth);
    } else {
      if (!can_delete(meth)) {
        // never inline methods that cannot be deleted
        TRACE(SINL, 4, "cannot_delete: %s\n", SHOW(meth));
        dont_strip++;
      } else {
        methods.insert(meth);
      }
    }

    if (has_anno(meth, force_inline)) {
      inlinable.insert(meth);
    }
  };

  walk_methods(scope,
      [&](DexMethod* method) {
        all_methods++;
        if (method->is_virtual()) return;

        auto& code = method->get_code();
        bool dont_inline = code == nullptr;

        direct_methods++;
        if (code == nullptr) direct_no_code++;
        if (is_constructor(method)) {
          (is_static(method)) ? clinit++ : init++;
          dont_inline = true;
        } else {
          (is_static(method)) ? static_methods++ : private_methods++;
        }

        if (dont_inline) return;

        can_inline_method(method, *code);
      });
  if (m_virtual_inline) {
    auto non_virtual = devirtualize(scope);
    non_virt_methods = non_virtual.size();
    for (const auto& vmeth : non_virtual) {
      auto& code = vmeth->get_code();
      if (code == nullptr) {
        non_virtual_no_code++;
        continue;
      }
      can_inline_method(vmeth, *code);
    }
  }

  TRACE(SINL, 2, "All methods count: %ld\n", all_methods);
  TRACE(SINL, 2, "Direct methods count: %ld\n", direct_methods);
  TRACE(SINL, 2, "Virtual methods count: %ld\n", all_methods - direct_methods);
  TRACE(SINL, 2, "Direct methods no code: %ld\n", direct_no_code);
  TRACE(SINL, 2, "Direct methods with code: %ld\n",
      direct_methods - direct_no_code);
  TRACE(SINL, 2, "Constructors with or without code: %ld\n", init);
  TRACE(SINL, 2, "Static constructors: %ld\n", clinit);
  TRACE(SINL, 2, "Static methods: %ld\n", static_methods);
  TRACE(SINL, 2, "Private methods: %ld\n", private_methods);
  TRACE(SINL, 2, "Virtual methods non virtual count: %ld\n", non_virt_methods);
  TRACE(SINL, 2, "Non virtual no code count: %ld\n", non_virtual_no_code);
  TRACE(SINL, 2, "Non virtual no strip count: %ld\n", non_virt_dont_strip);
  TRACE(SINL, 2, "Small methods: %ld\n", inlinable.size());
  TRACE(SINL, 2, "Don't strip inlinable methods count: %ld\n", dont_strip);
  TRACE(SINL, 2, "Don't inline annotation count: %ld\n", no_inline_anno_count);
  return methods;
}

/**
 * Add to the list the single called.
 */
void SimpleInlinePass::select_single_called(
    Scope& scope, std::unordered_set<DexMethod*>& methods) {
  std::unordered_map<DexMethod*, int> calls;
  for (const auto& method : methods) {
    calls[method] = 0;
  }
  // count call sites for each method
  walk_opcodes(scope, [](DexMethod* meth) { return true; },
      [&](DexMethod* meth, DexInstruction* insn) {
        if (is_invoke(insn->opcode())) {
          auto mop = static_cast<DexOpcodeMethod*>(insn);
          auto callee = resolve_method(
              mop->get_method(), opcode_to_search(insn), resolved_refs);
          if (callee != nullptr && callee->is_concrete()
              && methods.count(callee) > 0) {
            calls[callee]++;
          }
        }
      });

  // pick methods with a single call site and add to candidates.
  // This vector usage is only because of logging we should remove it
  // once the optimization is "closed"
  std::vector<std::vector<DexMethod*>> calls_group(MAX_COUNT);
  for (auto call_it : calls) {
    if (call_it.second >= MAX_COUNT) {
      calls_group[MAX_COUNT - 1].push_back(call_it.first);
      continue;
    }
    calls_group[call_it.second].push_back(call_it.first);
  }
  assert(method_breakup(calls_group));
  for (auto callee : calls_group[1]) {
    inlinable.insert(callee);
  }
}

static SimpleInlinePass s_pass;
<|endoftext|>


<commit_before>#include "objmaterial.h"
#include "objmaterial_ispc.h"
#include "../../common/data.h"

namespace ospray {
  namespace obj {

    //extern "C" void ispc_OBJMaterial_create(void *cppE);
    //    extern "C" void ispc_OBJMaterial_set(

    //! \brief commit the material's parameters
    void OBJMaterial::commit()
    {
      if (ispcEquivalent == NULL)
        ispcEquivalent = ispc::OBJMaterial_create(this);

      Ref<Data> textureData = getParamData("textures.list",NULL);
      int32 num_textures = getParam1i("textures.count",0);

      if(textureData && num_textures > 0) {
        Texture2D **textures = (ospray::Texture2D**)textureData->data;
        int map_d_idx = getParam1i("map_d", num_textures+1);
        int map_Kd_idx = getParam1i("map_Kd", getParam1i("map_kd",num_textures+1));
        int map_Ks_idx = getParam1i("map_Ks", getParam1i("map_ks",num_textures+1));
        int map_Ns_idx = getParam1i("map_Ns", getParam1i("map_ns",num_textures+1));
        int map_Bump_idx = getParam1i("map_Bump", getParam1i("map_bump",num_textures+1));

        map_d = map_d_idx < num_textures ? textures[map_d_idx] : NULL;
        map_Kd =    map_Kd_idx < num_textures ? textures[map_Kd_idx] : NULL;
        map_Ks =    map_Ks_idx < num_textures ? textures[map_Ks_idx] : NULL;
        map_Ns =    map_Ns_idx < num_textures ? textures[map_Ns_idx] : NULL;
        map_Bump =  map_Bump_idx < num_textures ? textures[map_Bump_idx] : NULL;

      } else {
        map_d = map_Kd = map_Ks = map_Ns = map_Bump = NULL;
      }

      d  = getParam1f("d", 1.f);
      Kd = getParam3f("kd",vec3f(.8f));
      Ks = getParam3f("ks",vec3f(0.f));
      Ns = getParam1f("ns",0.f);

      ispc::OBJMaterial_set(getIE(),
                            map_d ? map_d->getIE() : NULL,
                            d,
                            map_Kd ? map_Kd->getIE() : NULL,
                            (ispc::vec3f&)Kd,
                            map_Ks ? map_Ks->getIE() : NULL,
                            (ispc::vec3f&)Ks,
                            map_Ns ? map_Ns->getIE() : NULL,
                            Ns,
                            map_Bump != NULL ? map_Bump->getIE() : NULL );
    }

    OBJMaterial::~OBJMaterial()
    {
      if (getIE() != NULL)
        ispc::OBJMaterial_destroy(getIE());
    }

    OSP_REGISTER_MATERIAL(OBJMaterial,OBJMaterial);
  }
}
<commit_msg>Fixed parameter handling for obj materials<commit_after>#include "objmaterial.h"
#include "objmaterial_ispc.h"
#include "../../common/data.h"

namespace ospray {
  namespace obj {

    //extern "C" void ispc_OBJMaterial_create(void *cppE);
    //    extern "C" void ispc_OBJMaterial_set(

    //! \brief commit the material's parameters
    void OBJMaterial::commit()
    {
      if (ispcEquivalent == NULL)
        ispcEquivalent = ispc::OBJMaterial_create(this);

      Ref<Data> textureData = getParamData("textures.list",NULL);
      int32 num_textures = getParam1i("textures.count",0);

      if(textureData && num_textures > 0) {
        Texture2D **textures = (ospray::Texture2D**)textureData->data;
        int map_d_idx = getParam1i("map_d", num_textures+1);
        int map_Kd_idx = getParam1i("map_Kd", getParam1i("map_kd",num_textures+1));
        int map_Ks_idx = getParam1i("map_Ks", getParam1i("map_ks",num_textures+1));
        int map_Ns_idx = getParam1i("map_Ns", getParam1i("map_ns",num_textures+1));
        int map_Bump_idx = getParam1i("map_Bump", getParam1i("map_bump",num_textures+1));

        map_d = map_d_idx < num_textures ? textures[map_d_idx] : NULL;
        map_Kd =    map_Kd_idx < num_textures ? textures[map_Kd_idx] : NULL;
        map_Ks =    map_Ks_idx < num_textures ? textures[map_Ks_idx] : NULL;
        map_Ns =    map_Ns_idx < num_textures ? textures[map_Ns_idx] : NULL;
        map_Bump =  map_Bump_idx < num_textures ? textures[map_Bump_idx] : NULL;

      } else {
        map_d = map_Kd = map_Ks = map_Ns = map_Bump = NULL;
      }

      d  = getParam1f("d", 1.f);
      Kd = getParam3f("kd", getParam3f("Kd", vec3f(.8f)));
      Ks = getParam3f("ks", getParam3f("Ks", vec3f(0.f)));
      Ns = getParam1f("ns", getParam1f("Ns", 0.f));

      ispc::OBJMaterial_set(getIE(),
                            map_d ? map_d->getIE() : NULL,
                            d,
                            map_Kd ? map_Kd->getIE() : NULL,
                            (ispc::vec3f&)Kd,
                            map_Ks ? map_Ks->getIE() : NULL,
                            (ispc::vec3f&)Ks,
                            map_Ns ? map_Ns->getIE() : NULL,
                            Ns,
                            map_Bump != NULL ? map_Bump->getIE() : NULL );
    }

    OBJMaterial::~OBJMaterial()
    {
      if (getIE() != NULL)
        ispc::OBJMaterial_destroy(getIE());
    }

    OSP_REGISTER_MATERIAL(OBJMaterial,OBJMaterial);
  }
}
<|endoftext|>