예제 #1
0
int main(int argc, char *argv[]) {
    /*
     * 	n = přirozené číslo představující počet uzlů grafu G, n≥5
     *	m = přirozené číslo představující počet hran grafu G, m≥n
     *	k = přirozené číslo řádu jednotek představující průměrný stupeň uzlu grafu G, n≥k≥log n
     *	G(V,E) = jednoduchý souvislý neorientovaný neohodnocený graf o n uzlech a m hranách
     *	u = číslo uzlu reprezentujícího kořen kostry
     * */

    char* getArgFile = getCmdOption(argv, argv + argc, "-f");
    char* getArgRoot = getCmdOption(argv, argv + argc, "-u");

    if (getArgFile && getArgRoot)
    {
        string filename = (string) getArgFile;
        int u = atoi(getArgRoot);

        Graph *g = new Graph(filename);
        // g -> print_graph();
        BSTFinder bst_finder(u, g);
        bst_finder . find();

        delete g;
    } else {
        cout << "Zadejte jako argument -f \"cesta/ke/grafu.txt\"" << endl;
        cout << "Zadejte jako argument -u 6" << endl;
    }
}
예제 #2
0
파일: sasmc.cpp 프로젝트: BrooksEE/sbi
/*
	Main
*/
int main (int argc, char** argv)
{
	bool silent=false;
	bool clean=false;
	bool verbose=false;
	
	if(cmdOptionExists(argv, argv+argc, "-i")==false)
	{
		printf("SASM Compiler\n ver %s by Gi@cky98\n\n", VERSION_STR);
		printf("Usage: %s -i input.sasm [-o output.sbi] [-s] [-cl]\n\n", (char*)argv[0]);
		printf("-i input.sasm\t\tSASM assembly file to compile\n");
		printf("-o output.sbi\t\tSBI output filename\n");
		printf("-s\t\t\tSilent mode\n");
		printf("-v\t\t\tVerbose mode\n");
		printf("-cl\t\t\tClean non-SBI files used during compilation\n");
		return 1;
	}


	
	const char* inname = getCmdOption(argv, argv + argc, "-i");
    char* outname;

	if(cmdOptionExists(argv, argv + argc, "-o"))
		outname = getCmdOption(argv, argv + argc, "-o");
	else
		outname = (char*)"out.sbi";

	if(cmdOptionExists(argv, argv + argc, "-s")) silent = true;
	if(cmdOptionExists(argv, argv + argc, "-cl")) clean = true;
	if(cmdOptionExists(argv, argv + argc, "-v")) verbose = true;
	
	return sasmc (inname, outname, silent, clean, verbose);
}
예제 #3
0
BlitzleOpts BlitzleApp::parseCmdOptions(int argc, char** argv)
{
	BlitzleOpts opts;
	char** end = argv + argc;

	if (cmdOptionExists(argv, end, "-dota"))
	{
		opts.detectorType = DOTA;
	}

	if (cmdOptionExists(argv, end, "-paladins"))
	{
		opts.detectorType = PALADINS;
	}

	if (cmdOptionExists(argv, end, "-debug"))
	{
		opts.withDebug = true;
	}

	if (cmdOptionExists(argv, end, "-controls"))
	{
		opts.withControls = true;
	}

	if (cmdOptionExists(argv, end, "-cuda"))
	{
		opts.withCuda = true;
	}

	char* outputScaleOpt = getCmdOption(argv, end, "-scale");
	if (outputScaleOpt)
	{
		float outputScale = std::stof(std::string(outputScaleOpt));
		opts.outputScale = max(min(outputScale, 1.0f), 0.2f);
	}

	char* sensivityOpt = getCmdOption(argv, end, "-sensivity");
	if (sensivityOpt)
	{
		float sensivity = std::stof(std::string(sensivityOpt));
		opts.sensivity = max(min(sensivity, 10.0f), 0.0f);
	}

	char* duplicationOutputOpt = getCmdOption(argv, end, "-output");
	if (duplicationOutputOpt)
	{
		int duplicationOutput = std::stoi(std::string(duplicationOutputOpt));
		opts.duplicationOutput = max(duplicationOutput, 0);
	}

	char* duplicationAdapterOpt = getCmdOption(argv, end, "-adapter");
	if (duplicationAdapterOpt)
	{
		int duplicationAdapter = std::stoi(std::string(duplicationAdapterOpt));
		opts.duplicationAdapter = max(duplicationAdapter, 0);
	}

	return opts;
}
예제 #4
0
vector<int> GetIntervalTime(int argc, _TCHAR* argv[])
{
    wstring txt = L"1,1";

    if (cmdOptionExists(argv, argv + argc, L"-d") == true)
    {
        txt = getCmdOption(argv, argv + argc, L"-d");
    }

    StringSplit split;
    split.SplitString(txt, L",");
    vector<int> intervalTimes;

    for (size_t i = 0; i < split.GetCount(); i++)
    {
        int interval = ::_wtoi(txt.c_str());
        intervalTimes.push_back(interval);
    }

    if (intervalTimes.size() < 2)
    {
        intervalTimes.push_back(5);
    }

    return intervalTimes;
}
예제 #5
0
파일: main.cpp 프로젝트: hifialanwu/hifi
int main(int argc, const char * argv[]) {
    timeval startup_time;
    gettimeofday(&startup_time, NULL);
    
    // Debug option to demonstrate that the client's local time does not 
    // need to be in sync with any other network node. This forces clock 
    // skew for the individual client
    const char* CLOCK_SKEW = "--clockSkew";
    const char* clockSkewOption = getCmdOption(argc, argv, CLOCK_SKEW);
    if (clockSkewOption) {
        int clockSkew = atoi(clockSkewOption);
        usecTimestampNowForceClockSkew(clockSkew);
        qDebug("clockSkewOption=%s clockSkew=%d", clockSkewOption, clockSkew);
    }
    
    int exitCode;
    {
        Application app(argc, const_cast<char**>(argv), startup_time);
    
        qDebug( "Created QT Application.");
	//	Application::getInstance()->init();
        exitCode = app.exec();
    }
    qDebug("Normal exit.");
    return exitCode;
}   
예제 #6
0
파일: main.cpp 프로젝트: nnunley/hifi
int main(int argc, char* argv[]) {
    initialiseUsecTimestampNow();
    
#ifndef WIN32
    setvbuf(stdout, NULL, _IOLBF, 0);
#endif

    // use the verbose message handler in Logging
    qInstallMessageHandler(Logging::verboseMessageHandler);
    
    const char* numForksString = getCmdOption(argc, (const char**)argv, NUM_FORKS_PARAMETER);
    
    int numForks = 0;
    
    if (numForksString) {
        numForks = atoi(numForksString);
    }
    
    if (numForks) {
        AssignmentClientMonitor monitor(argc, argv, numForks);
        return monitor.exec();
    } else {
        AssignmentClient client(argc, argv);
        return client.exec();
    }
}
예제 #7
0
파일: main.cpp 프로젝트: heyhussain/hifi
int main(int argc, const char * argv[]) {
    timeval startup_time;
    gettimeofday(&startup_time, NULL);

    // Debug option to demonstrate that the client's local time does not
    // need to be in sync with any other network node. This forces clock
    // skew for the individual client
    const char* CLOCK_SKEW = "--clockSkew";
    const char* clockSkewOption = getCmdOption(argc, argv, CLOCK_SKEW);
    if (clockSkewOption) {
        int clockSkew = atoi(clockSkewOption);
        usecTimestampNowForceClockSkew(clockSkew);
        qDebug("clockSkewOption=%s clockSkew=%d", clockSkewOption, clockSkew);
    }

    int exitCode;
    {
        QSettings::setDefaultFormat(QSettings::IniFormat);
        Application app(argc, const_cast<char**>(argv), startup_time);

        QTranslator translator;
        translator.load("interface_en");
        app.installTranslator(&translator);

        qDebug( "Created QT Application.");
        exitCode = app.exec();
    }
    qDebug("Normal exit.");
    return exitCode;
}
예제 #8
0
DomainServer::DomainServer(int argc, char* argv[]) :
    _assignmentQueueMutex(),
    _assignmentQueue(),
    _staticAssignmentFile(QString("%1/config.ds").arg(QCoreApplication::applicationDirPath())),
    _staticAssignmentFileData(NULL),
    _voxelServerConfig(NULL),
    _hasCompletedRestartHold(false)
{
    DomainServer::setDomainServerInstance(this);
        
    const char CUSTOM_PORT_OPTION[] = "-p";
    const char* customPortString = getCmdOption(argc, (const char**) argv, CUSTOM_PORT_OPTION);
    unsigned short domainServerPort = customPortString ? atoi(customPortString) : DEFAULT_DOMAIN_SERVER_PORT;
    
    NodeList::createInstance(NODE_TYPE_DOMAIN, domainServerPort);
    
    struct sigaction sigIntHandler;
    
    sigIntHandler.sa_handler = DomainServer::signalHandler;
    sigemptyset(&sigIntHandler.sa_mask);
    sigIntHandler.sa_flags = 0;
    
    sigaction(SIGINT, &sigIntHandler, NULL);
        
    const char VOXEL_CONFIG_OPTION[] = "--voxelServerConfig";
    _voxelServerConfig = getCmdOption(argc, (const char**) argv, VOXEL_CONFIG_OPTION);
    
    // setup the mongoose web server
    struct mg_callbacks callbacks = {};
    
    QString documentRootString = QString("%1/resources/web").arg(QCoreApplication::applicationDirPath());
    
    char documentRoot[documentRootString.size() + 1];
    strcpy(documentRoot, documentRootString.toLocal8Bit().constData());
    
    // list of options. Last element must be NULL.
    const char* options[] = {"listening_ports", "8080",
        "document_root", documentRoot, NULL};
    
    callbacks.begin_request = civetwebRequestHandler;
    callbacks.upload = civetwebUploadHandler;
    
    // Start the web server.
    mg_start(&callbacks, NULL, options);
}
예제 #9
0
wstring GetUID(int argc, _TCHAR* argv[])
{
    if (cmdOptionExists(argv, argv + argc, L"-id") == true)
    {
        return getCmdOption(argv, argv + argc, L"-id");
    }

    return L"";
}
예제 #10
0
파일: main.cpp 프로젝트: anthonyyuan/eyeMon
void processOptions(int argc, char* argv[]) {
    /*
    if(cmdOptionExists(argv, argv+argc, "-h")) {
        // Do stuff
    }
    */
    char* filename = getCmdOption(argv, argv + argc, "--debug_show_img_main");
    if (filename) {
        // Do interesting things
    }
}
예제 #11
0
int main(int argc, char* argv[])
{
    const char* rendererFlag = getCmdOption(argv, argv + argc, "--renderer");
    
    auto game = Game();
    if(game.Init(rendererFlag))
    {
        game.Loop();
    }
    game.Terminate();
    return 0;
}
예제 #12
0
wstring GetApiKey(int argc, _TCHAR* argv[])
{
    if (g_isConsoleApp == false)
    {
        return GetEnvVar(L"apiKey");
    }

    if (cmdOptionExists(argv, argv + argc, L"-key") == true)
    {
        return getCmdOption(argv, argv + argc, L"-key");
    }

    return L"";
}
예제 #13
0
void SetupHostPort(int argc, _TCHAR* argv[], ConnectionInfo &connection)
{
    wstring txt;

    if (g_isConsoleApp == false)
    {
        txt = GetEnvVar(L"port");
    }
    else
    {
        if (cmdOptionExists(argv, argv + argc, L"-port") == true)
        {
            txt = getCmdOption(argv, argv + argc, L"-port");
        }
    }

    if (txt.length() == 0)
    {
        return;
    }

    connection.Setport(_wtoi(txt.c_str()));
}
예제 #14
0
string GetHostAddress(int argc, _TCHAR* argv[], ConnectionInfo &connection)
{
    wstring txt;

    if (g_isConsoleApp == false)
    {
        txt = GetEnvVar(L"server");
        return ws2s(txt);
    }
    else
    {
        if (cmdOptionExists(argv, argv + argc, L"-s") == true)
        {
            txt = getCmdOption(argv, argv + argc, L"-s");
        }
        else
        {
            txt = connection.Getaddress();
        }

        return ws2s(txt);
    }
}
예제 #15
0
파일: main.cpp 프로젝트: problem/hifi
int main(int argc, const char* argv[]) {
    
    QCoreApplication app(argc, (char**) argv);
    
    setvbuf(stdout, NULL, _IOLBF, 0);
    
    // use the verbose message handler in Logging
    qInstallMessageHandler(Logging::verboseMessageHandler);
    
    // start the Logging class with the parent's target name
    Logging::setTargetName(PARENT_TARGET_NAME);
    
    const char CUSTOM_ASSIGNMENT_SERVER_HOSTNAME_OPTION[] = "-a";
    const char CUSTOM_ASSIGNMENT_SERVER_PORT_OPTION[] = "-p";
    
    // grab the overriden assignment-server hostname from argv, if it exists
    const char* customAssignmentServerHostname = getCmdOption(argc, argv, CUSTOM_ASSIGNMENT_SERVER_HOSTNAME_OPTION);
    const char* customAssignmentServerPortString = getCmdOption(argc, argv, CUSTOM_ASSIGNMENT_SERVER_PORT_OPTION);
    
    if (customAssignmentServerHostname || customAssignmentServerPortString) {
        
        // set the custom port or default if it wasn't passed
        unsigned short assignmentServerPort = customAssignmentServerPortString
            ? atoi(customAssignmentServerPortString) : DEFAULT_DOMAIN_SERVER_PORT;
        
        // set the custom hostname or default if it wasn't passed
        if (!customAssignmentServerHostname) {
            customAssignmentServerHostname = LOCAL_ASSIGNMENT_SERVER_HOSTNAME;
        }
        
        ::customAssignmentSocket = socketForHostnameAndHostOrderPort(customAssignmentServerHostname, assignmentServerPort);
    }
    
    const char ASSIGNMENT_TYPE_OVVERIDE_OPTION[] = "-t";
    const char* assignmentTypeString = getCmdOption(argc, argv, ASSIGNMENT_TYPE_OVVERIDE_OPTION);
    
    if (assignmentTypeString) {
        // the user is asking to only be assigned to a particular type of assignment
        // so set that as the ::overridenAssignmentType to be used in requests
        ::overiddenAssignmentType = (Assignment::Type) atoi(assignmentTypeString);
    }

    const char* NUM_FORKS_PARAMETER = "-n";
    const char* numForksString = getCmdOption(argc, argv, NUM_FORKS_PARAMETER);
    
    int processID = 0;
    
    if (numForksString) {
        ::numForks = atoi(numForksString);
        qDebug("Starting %d assignment clients\n", ::numForks);
        
        ::childForks = new pid_t[::numForks];
        
        // fire off as many children as we need (this is one less than the parent since the parent will run as well)
        for (int i = 0; i < ::numForks; i++) {
            processID = fork();
            
            if (processID == 0) {
                // this is in one of the children, break so we don't start a fork bomb
                break;
            } else {
                // this is in the parent, save the ID of the forked process
                childForks[i] = processID;
            }
        }
    }
    
    if (processID == 0 || ::numForks == 0) {
        childClient();
    } else {
        parentMonitor();
    }
}
예제 #16
0
int main(int argc, char** argv) {

	int err;

	set_logging_level(logDEBUG1);

	if (argc < 2 || cmdOptionExists(argv, argv + argc, "-h")) {
		test::printHelp();
		return 0;
	}

	int device_id = atoi(argv[1]);

	string bitFile = getCmdOption(argv, argv + argc, "-b");

	if (bitFile.length() == 0) {
		bitFile = "../../bitfiles/mqco_aps_latest";
	}

	cout << "Programming device " << device_id << " using: " << string(bitFile) << endl;

	//Initialize the APSRack from the DLL
	init();

	if (cmdOptionExists(argv, argv + argc, "-0")) {
		char s[] = "stdout";
		set_log(s);
	}

	//Connect to device
	connect_by_ID(device_id);

	err = initAPS(device_id, const_cast<char*>(bitFile.c_str()), true);

	if (err != APS_OK) {
		cout << "Error initializing APS Rack: " << err << endl;
		exit(-1);
	}

//	vector<float> waveform(0);
//
//	for(int ct=0; ct<1000;ct++){
//		waveform.push_back(float(ct)/1000);
//	}

//	stop(0);
//	set_waveform_float(0, 0, &waveform.front(), waveform.size());
//	set_run_mode(0, 0, 0);
//	run(0);
//	usleep(1000);
//	stop(0);

	// select test to run

	if (cmdOptionExists(argv, argv + argc, "-wf")) {
		test::programSquareWaves();
	}

	if (cmdOptionExists(argv, argv + argc, "-stream")) {
		test::streaming();
	}

	if (cmdOptionExists(argv, argv + argc, "-t")) {
		test::doToggleTest();
	}

	if (cmdOptionExists(argv, argv + argc, "-w")) {
		test::doStoreLoadTest();
	}

	if (cmdOptionExists(argv, argv + argc, "-bf")) {
		test::doBulkStateFileTest();
	}

	if (cmdOptionExists(argv, argv + argc, "-sf")) {
		test::doStateFilesTest();
	}

	if (cmdOptionExists(argv, argv + argc, "-trig")) {
		test::getSetTriggerInterval();
	}

	if (cmdOptionExists(argv, argv + argc, "-seq")) {
			test::loadSequenceFile();
	}

	if (cmdOptionExists(argv, argv + argc, "-offset")) {
				test::offsetScale();
		}

	disconnect_by_ID(device_id);

	cout << "Made it through!" << endl;

	return 0;

}
예제 #17
0
//int main(int argc, const char * argv[]) {
void VoxelServer::run() {

    const char VOXEL_SERVER_LOGGING_TARGET_NAME[] = "voxel-server";

    // change the logging target name while this is running
    Logging::setTargetName(VOXEL_SERVER_LOGGING_TARGET_NAME);

    // Now would be a good time to parse our arguments, if we got them as assignment
    if (getNumPayloadBytes() > 0) {
        parsePayload();
    }

    qInstallMessageHandler(Logging::verboseMessageHandler);

    const char* STATUS_PORT = "--statusPort";
    const char* statusPort = getCmdOption(_argc, _argv, STATUS_PORT);
    if (statusPort) {
        int statusPortNumber = atoi(statusPort);
        initMongoose(statusPortNumber);
    }


    const char* JURISDICTION_FILE = "--jurisdictionFile";
    const char* jurisdictionFile = getCmdOption(_argc, _argv, JURISDICTION_FILE);
    if (jurisdictionFile) {
        qDebug("jurisdictionFile=%s\n", jurisdictionFile);

        qDebug("about to readFromFile().... jurisdictionFile=%s\n", jurisdictionFile);
        _jurisdiction = new JurisdictionMap(jurisdictionFile);
        qDebug("after readFromFile().... jurisdictionFile=%s\n", jurisdictionFile);
    } else {
        const char* JURISDICTION_ROOT = "--jurisdictionRoot";
        const char* jurisdictionRoot = getCmdOption(_argc, _argv, JURISDICTION_ROOT);
        if (jurisdictionRoot) {
            qDebug("jurisdictionRoot=%s\n", jurisdictionRoot);
        }

        const char* JURISDICTION_ENDNODES = "--jurisdictionEndNodes";
        const char* jurisdictionEndNodes = getCmdOption(_argc, _argv, JURISDICTION_ENDNODES);
        if (jurisdictionEndNodes) {
            qDebug("jurisdictionEndNodes=%s\n", jurisdictionEndNodes);
        }

        if (jurisdictionRoot || jurisdictionEndNodes) {
            _jurisdiction = new JurisdictionMap(jurisdictionRoot, jurisdictionEndNodes);
        }
    }

    // should we send environments? Default is yes, but this command line suppresses sending
    const char* DUMP_VOXELS_ON_MOVE = "--dumpVoxelsOnMove";
    _dumpVoxelsOnMove = cmdOptionExists(_argc, _argv, DUMP_VOXELS_ON_MOVE);
    qDebug("dumpVoxelsOnMove=%s\n", debug::valueOf(_dumpVoxelsOnMove));

    // should we send environments? Default is yes, but this command line suppresses sending
    const char* SEND_ENVIRONMENTS = "--sendEnvironments";
    bool dontSendEnvironments =  !cmdOptionExists(_argc, _argv, SEND_ENVIRONMENTS);
    if (dontSendEnvironments) {
        qDebug("Sending environments suppressed...\n");
        _sendEnvironments = false;
    } else {
        // should we send environments? Default is yes, but this command line suppresses sending
        const char* MINIMAL_ENVIRONMENT = "--minimalEnvironment";
        _sendMinimalEnvironment =  cmdOptionExists(_argc, _argv, MINIMAL_ENVIRONMENT);
        qDebug("Using Minimal Environment=%s\n", debug::valueOf(_sendMinimalEnvironment));
    }
    qDebug("Sending environments=%s\n", debug::valueOf(_sendEnvironments));

    NodeList* nodeList = NodeList::getInstance();
    nodeList->setOwnerType(NODE_TYPE_VOXEL_SERVER);

    // we need to ask the DS about agents so we can ping/reply with them
    const char nodeTypesOfInterest[] = { NODE_TYPE_AGENT, NODE_TYPE_ANIMATION_SERVER};
    nodeList->setNodeTypesOfInterest(nodeTypesOfInterest, sizeof(nodeTypesOfInterest));

    setvbuf(stdout, NULL, _IOLBF, 0);

    // tell our NodeList about our desire to get notifications
    nodeList->addHook(&_nodeWatcher);
    nodeList->linkedDataCreateCallback = &attachVoxelNodeDataToNode;

    nodeList->startSilentNodeRemovalThread();
    srand((unsigned)time(0));

    const char* DISPLAY_VOXEL_STATS = "--displayVoxelStats";
    _displayVoxelStats =  cmdOptionExists(_argc, _argv, DISPLAY_VOXEL_STATS);
    qDebug("displayVoxelStats=%s\n", debug::valueOf(_displayVoxelStats));

    const char* VERBOSE_DEBUG = "--verboseDebug";
    _verboseDebug =  cmdOptionExists(_argc, _argv, VERBOSE_DEBUG);
    qDebug("verboseDebug=%s\n", debug::valueOf(_verboseDebug));

    const char* DEBUG_VOXEL_SENDING = "--debugVoxelSending";
    _debugVoxelSending =  cmdOptionExists(_argc, _argv, DEBUG_VOXEL_SENDING);
    qDebug("debugVoxelSending=%s\n", debug::valueOf(_debugVoxelSending));

    const char* DEBUG_VOXEL_RECEIVING = "--debugVoxelReceiving";
    _debugVoxelReceiving =  cmdOptionExists(_argc, _argv, DEBUG_VOXEL_RECEIVING);
    qDebug("debugVoxelReceiving=%s\n", debug::valueOf(_debugVoxelReceiving));

    const char* WANT_ANIMATION_DEBUG = "--shouldShowAnimationDebug";
    _shouldShowAnimationDebug =  cmdOptionExists(_argc, _argv, WANT_ANIMATION_DEBUG);
    qDebug("shouldShowAnimationDebug=%s\n", debug::valueOf(_shouldShowAnimationDebug));

    // By default we will voxel persist, if you want to disable this, then pass in this parameter
    const char* NO_VOXEL_PERSIST = "--NoVoxelPersist";
    if (cmdOptionExists(_argc, _argv, NO_VOXEL_PERSIST)) {
        _wantVoxelPersist = false;
    }
    qDebug("wantVoxelPersist=%s\n", debug::valueOf(_wantVoxelPersist));

    // if we want Voxel Persistence, set up the local file and persist thread
    if (_wantVoxelPersist) {

        // Check to see if the user passed in a command line option for setting packet send rate
        const char* VOXELS_PERSIST_FILENAME = "--voxelsPersistFilename";
        const char* voxelsPersistFilenameParameter = getCmdOption(_argc, _argv, VOXELS_PERSIST_FILENAME);
        if (voxelsPersistFilenameParameter) {
            strcpy(_voxelPersistFilename, voxelsPersistFilenameParameter);
        } else {
            //strcpy(voxelPersistFilename, _wantLocalDomain ? LOCAL_VOXELS_PERSIST_FILE : VOXELS_PERSIST_FILE);
            strcpy(_voxelPersistFilename, LOCAL_VOXELS_PERSIST_FILE);
        }

        qDebug("voxelPersistFilename=%s\n", _voxelPersistFilename);

        // now set up VoxelPersistThread
        _voxelPersistThread = new VoxelPersistThread(&_serverTree, _voxelPersistFilename);
        if (_voxelPersistThread) {
            _voxelPersistThread->initialize(true);
        }
    }

    // Check to see if the user passed in a command line option for loading an old style local
    // Voxel File. If so, load it now. This is not the same as a voxel persist file
    const char* INPUT_FILE = "-i";
    const char* voxelsFilename = getCmdOption(_argc, _argv, INPUT_FILE);
    if (voxelsFilename) {
        _serverTree.readFromSVOFile(voxelsFilename);
    }

    // Check to see if the user passed in a command line option for setting packet send rate
    const char* PACKETS_PER_SECOND = "--packetsPerSecond";
    const char* packetsPerSecond = getCmdOption(_argc, _argv, PACKETS_PER_SECOND);
    if (packetsPerSecond) {
        _packetsPerClientPerInterval = atoi(packetsPerSecond) / INTERVALS_PER_SECOND;
        if (_packetsPerClientPerInterval < 1) {
            _packetsPerClientPerInterval = 1;
        }
        qDebug("packetsPerSecond=%s PACKETS_PER_CLIENT_PER_INTERVAL=%d\n", packetsPerSecond, _packetsPerClientPerInterval);
    }

    sockaddr senderAddress;

    unsigned char* packetData = new unsigned char[MAX_PACKET_SIZE];
    ssize_t packetLength;

    timeval lastDomainServerCheckIn = {};

    // set up our jurisdiction broadcaster...
    _jurisdictionSender = new JurisdictionSender(_jurisdiction);
    if (_jurisdictionSender) {
        _jurisdictionSender->initialize(true);
    }

    // set up our VoxelServerPacketProcessor
    _voxelServerPacketProcessor = new VoxelServerPacketProcessor(this);
    if (_voxelServerPacketProcessor) {
        _voxelServerPacketProcessor->initialize(true);
    }

    // Convert now to tm struct for local timezone
    tm* localtm = localtime(&_started);
    const int MAX_TIME_LENGTH = 128;
    char localBuffer[MAX_TIME_LENGTH] = { 0 };
    char utcBuffer[MAX_TIME_LENGTH] = { 0 };
    strftime(localBuffer, MAX_TIME_LENGTH, "%m/%d/%Y %X", localtm);
    // Convert now to tm struct for UTC
    tm* gmtm = gmtime(&_started);
    if (gmtm != NULL) {
        strftime(utcBuffer, MAX_TIME_LENGTH, " [%m/%d/%Y %X UTC]", gmtm);
    }
    qDebug() << "Now running... started at: " << localBuffer << utcBuffer << "\n";


    // loop to send to nodes requesting data
    while (true) {
        // check for >= in case one gets past the goalie
        if (NodeList::getInstance()->getNumNoReplyDomainCheckIns() >= MAX_SILENT_DOMAIN_SERVER_CHECK_INS) {
            qDebug() << "Exit loop... getInstance()->getNumNoReplyDomainCheckIns() >= MAX_SILENT_DOMAIN_SERVER_CHECK_INS\n";
            break;
        }

        // send a check in packet to the domain server if DOMAIN_SERVER_CHECK_IN_USECS has elapsed
        if (usecTimestampNow() - usecTimestamp(&lastDomainServerCheckIn) >= DOMAIN_SERVER_CHECK_IN_USECS) {
            gettimeofday(&lastDomainServerCheckIn, NULL);
            NodeList::getInstance()->sendDomainServerCheckIn();
        }

        // ping our inactive nodes to punch holes with them
        nodeList->possiblyPingInactiveNodes();

        if (nodeList->getNodeSocket()->receive(&senderAddress, packetData, &packetLength) &&
                packetVersionMatch(packetData)) {

            int numBytesPacketHeader = numBytesForPacketHeader(packetData);

            if (packetData[0] == PACKET_TYPE_VOXEL_QUERY) {
                // If we got a PACKET_TYPE_VOXEL_QUERY, then we're talking to an NODE_TYPE_AVATAR, and we
                // need to make sure we have it in our nodeList.
                QUuid nodeUUID = QUuid::fromRfc4122(QByteArray((char*)packetData + numBytesPacketHeader,
                                                    NUM_BYTES_RFC4122_UUID));

                Node* node = nodeList->nodeWithUUID(nodeUUID);

                if (node) {
                    nodeList->updateNodeWithData(node, &senderAddress, packetData, packetLength);
                    if (!node->getActiveSocket()) {
                        // we don't have an active socket for this node, but they're talking to us
                        // this means they've heard from us and can reply, let's assume public is active
                        node->activatePublicSocket();
                    }
                    VoxelNodeData* nodeData = (VoxelNodeData*) node->getLinkedData();
                    if (nodeData && !nodeData->isVoxelSendThreadInitalized()) {
                        nodeData->initializeVoxelSendThread(this);
                    }
                }
            } else if (packetData[0] == PACKET_TYPE_VOXEL_JURISDICTION_REQUEST) {
                if (_jurisdictionSender) {
                    _jurisdictionSender->queueReceivedPacket(senderAddress, packetData, packetLength);
                }
            } else if (_voxelServerPacketProcessor &&
                       (packetData[0] == PACKET_TYPE_SET_VOXEL
                        || packetData[0] == PACKET_TYPE_SET_VOXEL_DESTRUCTIVE
                        || packetData[0] == PACKET_TYPE_ERASE_VOXEL
                        || packetData[0] == PACKET_TYPE_Z_COMMAND)) {


                const char* messageName;
                switch (packetData[0]) {
                case PACKET_TYPE_SET_VOXEL:
                    messageName = "PACKET_TYPE_SET_VOXEL";
                    break;
                case PACKET_TYPE_SET_VOXEL_DESTRUCTIVE:
                    messageName = "PACKET_TYPE_SET_VOXEL_DESTRUCTIVE";
                    break;
                case PACKET_TYPE_ERASE_VOXEL:
                    messageName = "PACKET_TYPE_ERASE_VOXEL";
                    break;
                }
                int numBytesPacketHeader = numBytesForPacketHeader(packetData);

                if (packetData[0] != PACKET_TYPE_Z_COMMAND) {
                    unsigned short int sequence = (*((unsigned short int*)(packetData + numBytesPacketHeader)));
                    uint64_t sentAt = (*((uint64_t*)(packetData + numBytesPacketHeader + sizeof(sequence))));
                    uint64_t arrivedAt = usecTimestampNow();
                    uint64_t transitTime = arrivedAt - sentAt;
                    if (wantShowAnimationDebug() || wantsDebugVoxelReceiving()) {
                        printf("RECEIVE THREAD: got %s - command from client receivedBytes=%ld sequence=%d transitTime=%llu usecs\n",
                               messageName,
                               packetLength, sequence, transitTime);
                    }
                }

                _voxelServerPacketProcessor->queueReceivedPacket(senderAddress, packetData, packetLength);
            } else {
                // let processNodeData handle it.
                NodeList::getInstance()->processNodeData(&senderAddress, packetData, packetLength);
            }
        }
    }

    // call NodeList::clear() so that all of our node specific objects, including our sending threads, are
    // properly shutdown and cleaned up.
    NodeList::getInstance()->clear();

    if (_jurisdictionSender) {
        _jurisdictionSender->terminate();
        delete _jurisdictionSender;
    }

    if (_voxelServerPacketProcessor) {
        _voxelServerPacketProcessor->terminate();
        delete _voxelServerPacketProcessor;
    }

    if (_voxelPersistThread) {
        _voxelPersistThread->terminate();
        delete _voxelPersistThread;
    }

    // tell our NodeList we're done with notifications
    nodeList->removeHook(&_nodeWatcher);

    delete _jurisdiction;
    _jurisdiction = NULL;

    qDebug() << "VoxelServer::run()... DONE\n";
}
예제 #18
0
파일: main.cpp 프로젝트: Issacchaos/hifi
int main(int argc, const char * argv[])
{
    ::start = usecTimestampNow();

    NodeList* nodeList = NodeList::createInstance(NODE_TYPE_ANIMATION_SERVER, ANIMATION_LISTEN_PORT);
    setvbuf(stdout, NULL, _IOLBF, 0);

    // Handle Local Domain testing with the --local command line
    const char* NON_THREADED_PACKETSENDER = "--NonThreadedPacketSender";
    ::nonThreadedPacketSender = cmdOptionExists(argc, argv, NON_THREADED_PACKETSENDER);
    printf("nonThreadedPacketSender=%s\n", debug::valueOf(::nonThreadedPacketSender));

    // Handle Local Domain testing with the --local command line
    const char* NO_BILLBOARD = "--NoBillboard";
    ::includeBillboard = !cmdOptionExists(argc, argv, NO_BILLBOARD);
    printf("includeBillboard=%s\n", debug::valueOf(::includeBillboard));

    const char* NO_BORDER_TRACER = "--NoBorderTracer";
    ::includeBorderTracer = !cmdOptionExists(argc, argv, NO_BORDER_TRACER);
    printf("includeBorderTracer=%s\n", debug::valueOf(::includeBorderTracer));

    const char* NO_MOVING_BUG = "--NoMovingBug";
    ::includeMovingBug = !cmdOptionExists(argc, argv, NO_MOVING_BUG);
    printf("includeMovingBug=%s\n", debug::valueOf(::includeMovingBug));

    const char* INCLUDE_BLINKING_VOXEL = "--includeBlinkingVoxel";
    ::includeBlinkingVoxel = cmdOptionExists(argc, argv, INCLUDE_BLINKING_VOXEL);
    printf("includeBlinkingVoxel=%s\n", debug::valueOf(::includeBlinkingVoxel));

    const char* NO_DANCE_FLOOR = "--NoDanceFloor";
    ::includeDanceFloor = !cmdOptionExists(argc, argv, NO_DANCE_FLOOR);
    printf("includeDanceFloor=%s\n", debug::valueOf(::includeDanceFloor));

    const char* BUILD_STREET = "--BuildStreet";
    ::buildStreet = cmdOptionExists(argc, argv, BUILD_STREET);
    printf("buildStreet=%s\n", debug::valueOf(::buildStreet));

    // Handle Local Domain testing with the --local command line
    const char* showPPS = "--showPPS";
    ::shouldShowPacketsPerSecond = cmdOptionExists(argc, argv, showPPS);

    // Handle Local Domain testing with the --local command line
    const char* local = "--local";
    ::wantLocalDomain = cmdOptionExists(argc, argv,local);
    if (::wantLocalDomain) {
        printf("Local Domain MODE!\n");
        nodeList->setDomainIPToLocalhost();
    }

    const char* domainHostname = getCmdOption(argc, argv, "--domain");
    if (domainHostname) {
        NodeList::getInstance()->setDomainHostname(domainHostname);
    }

    const char* packetsPerSecondCommand = getCmdOption(argc, argv, "--pps");
    if (packetsPerSecondCommand) {
        ::packetsPerSecond = atoi(packetsPerSecondCommand);
    }
    printf("packetsPerSecond=%d\n",packetsPerSecond);

    const char* animateFPSCommand = getCmdOption(argc, argv, "--AnimateFPS");
    const char* animateIntervalCommand = getCmdOption(argc, argv, "--AnimateInterval");
    if (animateFPSCommand || animateIntervalCommand) {
        if (animateIntervalCommand) {
            ::ANIMATE_FPS_IN_MILLISECONDS = atoi(animateIntervalCommand);
            ::ANIMATE_VOXELS_INTERVAL_USECS = (ANIMATE_FPS_IN_MILLISECONDS * 1000.0); // converts from milliseconds to usecs
            ::ANIMATE_FPS = PacketSender::USECS_PER_SECOND / ::ANIMATE_VOXELS_INTERVAL_USECS;
        } else {
            ::ANIMATE_FPS = atoi(animateFPSCommand);
            ::ANIMATE_FPS_IN_MILLISECONDS = 1000.0/ANIMATE_FPS; // determines FPS from our desired FPS
            ::ANIMATE_VOXELS_INTERVAL_USECS = (ANIMATE_FPS_IN_MILLISECONDS * 1000.0); // converts from milliseconds to usecs
        }
    }
    printf("ANIMATE_FPS=%d\n",ANIMATE_FPS);
    printf("ANIMATE_VOXELS_INTERVAL_USECS=%d\n",ANIMATE_VOXELS_INTERVAL_USECS);

    const char* processingFPSCommand = getCmdOption(argc, argv, "--ProcessingFPS");
    const char* processingIntervalCommand = getCmdOption(argc, argv, "--ProcessingInterval");
    if (processingFPSCommand || processingIntervalCommand) {
        if (processingIntervalCommand) {
            ::PROCESSING_FPS_IN_MILLISECONDS = atoi(processingIntervalCommand);
            ::PROCESSING_INTERVAL_USECS = ::PROCESSING_FPS_IN_MILLISECONDS * 1000.0;
            ::PROCESSING_FPS = PacketSender::USECS_PER_SECOND / ::PROCESSING_INTERVAL_USECS;
        } else {
            ::PROCESSING_FPS = atoi(processingFPSCommand);
            ::PROCESSING_FPS_IN_MILLISECONDS = 1000.0/PROCESSING_FPS; // determines FPS from our desired FPS
            ::PROCESSING_INTERVAL_USECS = (PROCESSING_FPS_IN_MILLISECONDS * 1000.0) - FUDGE_USECS; // converts from milliseconds to usecs
        }
    }
    printf("PROCESSING_FPS=%d\n",PROCESSING_FPS);
    printf("PROCESSING_INTERVAL_USECS=%d\n",PROCESSING_INTERVAL_USECS);

    if (cmdOptionExists(argc, argv, "--quickExit")) {
        return 0;
    }


    nodeList->linkedDataCreateCallback = NULL; // do we need a callback?
    nodeList->startSilentNodeRemovalThread();
    
    // Create our JurisdictionListener so we'll know where to send edit packets
    ::jurisdictionListener = new JurisdictionListener();
    if (::jurisdictionListener) {
        ::jurisdictionListener->initialize(true);
    }
    
    // Create out VoxelEditPacketSender
    ::voxelEditPacketSender = new VoxelEditPacketSender;
    ::voxelEditPacketSender->initialize(!::nonThreadedPacketSender);

    if (::jurisdictionListener) {
        ::voxelEditPacketSender->setVoxelServerJurisdictions(::jurisdictionListener->getJurisdictions());
    }
    if (::nonThreadedPacketSender) {
        ::voxelEditPacketSender->setProcessCallIntervalHint(PROCESSING_INTERVAL_USECS);
    }
    
    srand((unsigned)time(0));

    pthread_t animateVoxelThread;
    pthread_create(&animateVoxelThread, NULL, animateVoxels, NULL);

    sockaddr nodePublicAddress;
    
    unsigned char* packetData = new unsigned char[MAX_PACKET_SIZE];
    ssize_t receivedBytes;
    
    timeval lastDomainServerCheckIn = {};
    NodeList::getInstance()->setNodeTypesOfInterest(&NODE_TYPE_VOXEL_SERVER, 1);

    // loop to send to nodes requesting data
    while (true) {
        // send a check in packet to the domain server if DOMAIN_SERVER_CHECK_IN_USECS has elapsed
        if (usecTimestampNow() - usecTimestamp(&lastDomainServerCheckIn) >= DOMAIN_SERVER_CHECK_IN_USECS) {
            gettimeofday(&lastDomainServerCheckIn, NULL);
            NodeList::getInstance()->sendDomainServerCheckIn();
        }
        
        // Nodes sending messages to us...
        if (nodeList->getNodeSocket()->receive(&nodePublicAddress, packetData, &receivedBytes) &&
            packetVersionMatch(packetData)) {
            
            if (packetData[0] == PACKET_TYPE_VOXEL_JURISDICTION) {
                if (::jurisdictionListener) {
                    ::jurisdictionListener->queueReceivedPacket(nodePublicAddress, packetData, receivedBytes);
                }
            }
            NodeList::getInstance()->processNodeData(&nodePublicAddress, packetData, receivedBytes);
        }
    }
    
    pthread_join(animateVoxelThread, NULL);
    
    if (::jurisdictionListener) {
        ::jurisdictionListener->terminate();
        delete ::jurisdictionListener;
    }

    if (::voxelEditPacketSender) {
        ::voxelEditPacketSender->terminate();
        delete ::voxelEditPacketSender;
    }

    return 0;
}
예제 #19
0
파일: main.cpp 프로젝트: mvpeng/hifi
int main(int argc, const char * argv[]) {
    pthread_mutex_init(&::treeLock, NULL);
    
    qInstallMessageHandler(sharedMessageHandler);
    
    int listenPort = VOXEL_LISTEN_PORT;
    // Check to see if the user passed in a command line option for setting listen port
    const char* PORT_PARAMETER = "--port";
    const char* portParameter = getCmdOption(argc, argv, PORT_PARAMETER);
    if (portParameter) {
        listenPort = atoi(portParameter);
        if (listenPort < 1) {
            listenPort = VOXEL_LISTEN_PORT;
        }
        printf("portParameter=%s listenPort=%d\n", portParameter, listenPort);
    }

    const char* JURISDICTION_FILE = "--jurisdictionFile";
    const char* jurisdictionFile = getCmdOption(argc, argv, JURISDICTION_FILE);
    if (jurisdictionFile) {
        printf("jurisdictionFile=%s\n", jurisdictionFile);

        printf("about to readFromFile().... jurisdictionFile=%s\n", jurisdictionFile);
        jurisdiction = new JurisdictionMap(jurisdictionFile);
        printf("after readFromFile().... jurisdictionFile=%s\n", jurisdictionFile);
    } else {
        const char* JURISDICTION_ROOT = "--jurisdictionRoot";
        const char* jurisdictionRoot = getCmdOption(argc, argv, JURISDICTION_ROOT);
        if (jurisdictionRoot) {
            printf("jurisdictionRoot=%s\n", jurisdictionRoot);
        }

        const char* JURISDICTION_ENDNODES = "--jurisdictionEndNodes";
        const char* jurisdictionEndNodes = getCmdOption(argc, argv, JURISDICTION_ENDNODES);
        if (jurisdictionEndNodes) {
            printf("jurisdictionEndNodes=%s\n", jurisdictionEndNodes);
        }

        if (jurisdictionRoot || jurisdictionEndNodes) {
            ::jurisdiction = new JurisdictionMap(jurisdictionRoot, jurisdictionEndNodes);
        }
    }
    
    // should we send environments? Default is yes, but this command line suppresses sending
    const char* DUMP_VOXELS_ON_MOVE = "--dumpVoxelsOnMove";
    ::dumpVoxelsOnMove = cmdOptionExists(argc, argv, DUMP_VOXELS_ON_MOVE);
    printf("dumpVoxelsOnMove=%s\n", debug::valueOf(::dumpVoxelsOnMove));
    
    // should we send environments? Default is yes, but this command line suppresses sending
    const char* DONT_SEND_ENVIRONMENTS = "--dontSendEnvironments";
    bool dontSendEnvironments = cmdOptionExists(argc, argv, DONT_SEND_ENVIRONMENTS);
    if (dontSendEnvironments) {
        printf("Sending environments suppressed...\n");
        ::sendEnvironments = false;
    } else { 
        // should we send environments? Default is yes, but this command line suppresses sending
        const char* MINIMAL_ENVIRONMENT = "--MinimalEnvironment";
        ::sendMinimalEnvironment = cmdOptionExists(argc, argv, MINIMAL_ENVIRONMENT);
        printf("Using Minimal Environment=%s\n", debug::valueOf(::sendMinimalEnvironment));
    }
    printf("Sending environments=%s\n", debug::valueOf(::sendEnvironments));
    
    NodeList* nodeList = NodeList::createInstance(NODE_TYPE_VOXEL_SERVER, listenPort);
    setvbuf(stdout, NULL, _IOLBF, 0);
    
    // tell our NodeList about our desire to get notifications
    nodeList->addHook(&nodeWatcher);

    // Handle Local Domain testing with the --local command line
    const char* local = "--local";
    ::wantLocalDomain = cmdOptionExists(argc, argv,local);
    if (::wantLocalDomain) {
        printf("Local Domain MODE!\n");
        nodeList->setDomainIPToLocalhost();
    } else {
        const char* domainIP = getCmdOption(argc, argv, "--domain");
        if (domainIP) {
            NodeList::getInstance()->setDomainHostname(domainIP);
        }
    }

    nodeList->linkedDataCreateCallback = &attachVoxelNodeDataToNode;
    nodeList->startSilentNodeRemovalThread();
    
    srand((unsigned)time(0));
    
    const char* DISPLAY_VOXEL_STATS = "--displayVoxelStats";
    ::displayVoxelStats = cmdOptionExists(argc, argv, DISPLAY_VOXEL_STATS);
    printf("displayVoxelStats=%s\n", debug::valueOf(::displayVoxelStats));

    const char* DEBUG_VOXEL_SENDING = "--debugVoxelSending";
    ::debugVoxelSending = cmdOptionExists(argc, argv, DEBUG_VOXEL_SENDING);
    printf("debugVoxelSending=%s\n", debug::valueOf(::debugVoxelSending));

    const char* DEBUG_VOXEL_RECEIVING = "--debugVoxelReceiving";
    ::debugVoxelReceiving = cmdOptionExists(argc, argv, DEBUG_VOXEL_RECEIVING);
    printf("debugVoxelReceiving=%s\n", debug::valueOf(::debugVoxelReceiving));

    const char* WANT_ANIMATION_DEBUG = "--shouldShowAnimationDebug";
    ::shouldShowAnimationDebug = cmdOptionExists(argc, argv, WANT_ANIMATION_DEBUG);
    printf("shouldShowAnimationDebug=%s\n", debug::valueOf(::shouldShowAnimationDebug));

    // By default we will voxel persist, if you want to disable this, then pass in this parameter
    const char* NO_VOXEL_PERSIST = "--NoVoxelPersist";
    if (cmdOptionExists(argc, argv, NO_VOXEL_PERSIST)) {
        ::wantVoxelPersist = false;
    }
    printf("wantVoxelPersist=%s\n", debug::valueOf(::wantVoxelPersist));

    // if we want Voxel Persistence, load the local file now...
    bool persistantFileRead = false;
    if (::wantVoxelPersist) {

        // Check to see if the user passed in a command line option for setting packet send rate
        const char* VOXELS_PERSIST_FILENAME = "--voxelsPersistFilename";
        const char* voxelsPersistFilenameParameter = getCmdOption(argc, argv, VOXELS_PERSIST_FILENAME);
        if (voxelsPersistFilenameParameter) {
            strcpy(voxelPersistFilename, voxelsPersistFilenameParameter);
        } else {
            strcpy(voxelPersistFilename, ::wantLocalDomain ? LOCAL_VOXELS_PERSIST_FILE : VOXELS_PERSIST_FILE);
        }

        printf("loading voxels from file: %s...\n", voxelPersistFilename);

        persistantFileRead = ::serverTree.readFromSVOFile(::voxelPersistFilename);
        if (persistantFileRead) {
            PerformanceWarning warn(::shouldShowAnimationDebug,
                                    "persistVoxelsWhenDirty() - reaverageVoxelColors()", ::shouldShowAnimationDebug);
            
            // after done inserting all these voxels, then reaverage colors
            serverTree.reaverageVoxelColors(serverTree.rootNode);
            printf("Voxels reAveraged\n");
        }
        
        ::serverTree.clearDirtyBit(); // the tree is clean since we just loaded it
        printf("DONE loading voxels from file... fileRead=%s\n", debug::valueOf(persistantFileRead));
        unsigned long nodeCount         = ::serverTree.rootNode->getSubTreeNodeCount();
        unsigned long internalNodeCount = ::serverTree.rootNode->getSubTreeInternalNodeCount();
        unsigned long leafNodeCount     = ::serverTree.rootNode->getSubTreeLeafNodeCount();
        printf("Nodes after loading scene %lu nodes %lu internal %lu leaves\n", nodeCount, internalNodeCount, leafNodeCount);
        
        // now set up VoxelPersistThread
        ::voxelPersistThread = new VoxelPersistThread(&::serverTree, ::voxelPersistFilename);
        if (::voxelPersistThread) {
            ::voxelPersistThread->initialize(true);
        }
    }

    // Check to see if the user passed in a command line option for loading an old style local
    // Voxel File. If so, load it now. This is not the same as a voxel persist file
    const char* INPUT_FILE = "-i";
    const char* voxelsFilename = getCmdOption(argc, argv, INPUT_FILE);
    if (voxelsFilename) {
        serverTree.readFromSVOFile(voxelsFilename);
    }

    // Check to see if the user passed in a command line option for setting packet send rate
    const char* PACKETS_PER_SECOND = "--packetsPerSecond";
    const char* packetsPerSecond = getCmdOption(argc, argv, PACKETS_PER_SECOND);
    if (packetsPerSecond) {
        PACKETS_PER_CLIENT_PER_INTERVAL = atoi(packetsPerSecond)/INTERVALS_PER_SECOND;
        if (PACKETS_PER_CLIENT_PER_INTERVAL < 1) {
            PACKETS_PER_CLIENT_PER_INTERVAL = 1;
        }
        printf("packetsPerSecond=%s PACKETS_PER_CLIENT_PER_INTERVAL=%d\n", packetsPerSecond, PACKETS_PER_CLIENT_PER_INTERVAL);
    }
    
    // for now, initialize the environments with fixed values
    environmentData[1].setID(1);
    environmentData[1].setGravity(1.0f);
    environmentData[1].setAtmosphereCenter(glm::vec3(0.5, 0.5, (0.25 - 0.06125)) * (float)TREE_SCALE);
    environmentData[1].setAtmosphereInnerRadius(0.030625f * TREE_SCALE);
    environmentData[1].setAtmosphereOuterRadius(0.030625f * TREE_SCALE * 1.05f);
    environmentData[2].setID(2);
    environmentData[2].setGravity(1.0f);
    environmentData[2].setAtmosphereCenter(glm::vec3(0.5f, 0.5f, 0.5f) * (float)TREE_SCALE);
    environmentData[2].setAtmosphereInnerRadius(0.1875f * TREE_SCALE);
    environmentData[2].setAtmosphereOuterRadius(0.1875f * TREE_SCALE * 1.05f);
    environmentData[2].setScatteringWavelengths(glm::vec3(0.475f, 0.570f, 0.650f)); // swaps red and blue

    sockaddr senderAddress;
    
    unsigned char *packetData = new unsigned char[MAX_PACKET_SIZE];
    ssize_t packetLength;
    
    timeval lastDomainServerCheckIn = {};

    // set up our jurisdiction broadcaster...
    ::jurisdictionSender = new JurisdictionSender(::jurisdiction);
    if (::jurisdictionSender) {
        ::jurisdictionSender->initialize(true);
    }
    
    // set up our VoxelServerPacketProcessor
    ::voxelServerPacketProcessor = new VoxelServerPacketProcessor();
    if (::voxelServerPacketProcessor) {
        ::voxelServerPacketProcessor->initialize(true);
    }

    // loop to send to nodes requesting data
    while (true) {

        // send a check in packet to the domain server if DOMAIN_SERVER_CHECK_IN_USECS has elapsed
        if (usecTimestampNow() - usecTimestamp(&lastDomainServerCheckIn) >= DOMAIN_SERVER_CHECK_IN_USECS) {
            gettimeofday(&lastDomainServerCheckIn, NULL);
            NodeList::getInstance()->sendDomainServerCheckIn();
        }
        
        if (nodeList->getNodeSocket()->receive(&senderAddress, packetData, &packetLength) &&
            packetVersionMatch(packetData)) {

            int numBytesPacketHeader = numBytesForPacketHeader(packetData);

            if (packetData[0] == PACKET_TYPE_HEAD_DATA) {
                // If we got a PACKET_TYPE_HEAD_DATA, then we're talking to an NODE_TYPE_AVATAR, and we
                // need to make sure we have it in our nodeList.
                uint16_t nodeID = 0;
                unpackNodeId(packetData + numBytesPacketHeader, &nodeID);
                Node* node = NodeList::getInstance()->addOrUpdateNode(&senderAddress,
                                                       &senderAddress,
                                                       NODE_TYPE_AGENT,
                                                       nodeID);

                NodeList::getInstance()->updateNodeWithData(node, packetData, packetLength);
            } else if (packetData[0] == PACKET_TYPE_PING) {
                // If the packet is a ping, let processNodeData handle it.
                NodeList::getInstance()->processNodeData(&senderAddress, packetData, packetLength);
            } else if (packetData[0] == PACKET_TYPE_DOMAIN) {
                NodeList::getInstance()->processNodeData(&senderAddress, packetData, packetLength);
            } else if (packetData[0] == PACKET_TYPE_VOXEL_JURISDICTION_REQUEST) {
                if (::jurisdictionSender) {
                    ::jurisdictionSender->queueReceivedPacket(senderAddress, packetData, packetLength);
                }
            } else if (::voxelServerPacketProcessor) {
                ::voxelServerPacketProcessor->queueReceivedPacket(senderAddress, packetData, packetLength);
            } else {
                printf("unknown packet ignored... packetData[0]=%c\n", packetData[0]);
            }
        }
    }
    
    if (::jurisdiction) {
        delete ::jurisdiction;
    }
    
    if (::jurisdictionSender) {
        ::jurisdictionSender->terminate();
        delete ::jurisdictionSender;
    }

    if (::voxelServerPacketProcessor) {
        ::voxelServerPacketProcessor->terminate();
        delete ::voxelServerPacketProcessor;
    }

    if (::voxelPersistThread) {
        ::voxelPersistThread->terminate();
        delete ::voxelPersistThread;
    }
    
    // tell our NodeList we're done with notifications
    nodeList->removeHook(&nodeWatcher);
    
    pthread_mutex_destroy(&::treeLock);

    return 0;
}
예제 #20
0
파일: main.cpp 프로젝트: evilbinary/hifi
int main(int argc, const char * argv[]) {
    pthread_mutex_init(&::treeLock, NULL);
    
    qInstallMessageHandler(sharedMessageHandler);
    
    NodeList* nodeList = NodeList::createInstance(NODE_TYPE_VOXEL_SERVER, VOXEL_LISTEN_PORT);
    setvbuf(stdout, NULL, _IOLBF, 0);

    // Handle Local Domain testing with the --local command line
    const char* local = "--local";
    ::wantLocalDomain = cmdOptionExists(argc, argv,local);
    if (::wantLocalDomain) {
        printf("Local Domain MODE!\n");
        nodeList->setDomainIPToLocalhost();
    }

    nodeList->linkedDataCreateCallback = &attachVoxelNodeDataToNode;
    nodeList->startSilentNodeRemovalThread();
    
    srand((unsigned)time(0));
    
    const char* DISPLAY_VOXEL_STATS = "--displayVoxelStats";
    ::displayVoxelStats = cmdOptionExists(argc, argv, DISPLAY_VOXEL_STATS);
    printf("displayVoxelStats=%s\n", debug::valueOf(::displayVoxelStats));

    const char* DEBUG_VOXEL_SENDING = "--debugVoxelSending";
    ::debugVoxelSending = cmdOptionExists(argc, argv, DEBUG_VOXEL_SENDING);
    printf("debugVoxelSending=%s\n", debug::valueOf(::debugVoxelSending));

    const char* DEBUG_VOXEL_RECEIVING = "--debugVoxelReceiving";
    ::debugVoxelReceiving = cmdOptionExists(argc, argv, DEBUG_VOXEL_RECEIVING);
    printf("debugVoxelReceiving=%s\n", debug::valueOf(::debugVoxelReceiving));

    const char* WANT_ANIMATION_DEBUG = "--shouldShowAnimationDebug";
    ::shouldShowAnimationDebug = cmdOptionExists(argc, argv, WANT_ANIMATION_DEBUG);
    printf("shouldShowAnimationDebug=%s\n", debug::valueOf(::shouldShowAnimationDebug));

    const char* WANT_COLOR_RANDOMIZER = "--wantColorRandomizer";
    ::wantColorRandomizer = cmdOptionExists(argc, argv, WANT_COLOR_RANDOMIZER);
    printf("wantColorRandomizer=%s\n", debug::valueOf(::wantColorRandomizer));

    // By default we will voxel persist, if you want to disable this, then pass in this parameter
    const char* NO_VOXEL_PERSIST = "--NoVoxelPersist";
    if (cmdOptionExists(argc, argv, NO_VOXEL_PERSIST)) {
        ::wantVoxelPersist = false;
    }
    printf("wantVoxelPersist=%s\n", debug::valueOf(::wantVoxelPersist));

    // if we want Voxel Persistance, load the local file now...
    bool persistantFileRead = false;
    if (::wantVoxelPersist) {
        printf("loading voxels from file...\n");
        persistantFileRead = ::serverTree.readFromSVOFile(::wantLocalDomain ? LOCAL_VOXELS_PERSIST_FILE : VOXELS_PERSIST_FILE);
        if (persistantFileRead) {
            PerformanceWarning warn(::shouldShowAnimationDebug,
                                    "persistVoxelsWhenDirty() - reaverageVoxelColors()", ::shouldShowAnimationDebug);
            
            // after done inserting all these voxels, then reaverage colors
            serverTree.reaverageVoxelColors(serverTree.rootNode);
            printf("Voxels reAveraged\n");
        }
        
        ::serverTree.clearDirtyBit(); // the tree is clean since we just loaded it
        printf("DONE loading voxels from file... fileRead=%s\n", debug::valueOf(persistantFileRead));
        unsigned long nodeCount         = ::serverTree.rootNode->getSubTreeNodeCount();
        unsigned long internalNodeCount = ::serverTree.rootNode->getSubTreeInternalNodeCount();
        unsigned long leafNodeCount     = ::serverTree.rootNode->getSubTreeLeafNodeCount();
        printf("Nodes after loading scene %lu nodes %lu internal %lu leaves\n", nodeCount, internalNodeCount, leafNodeCount);
    }

    // Check to see if the user passed in a command line option for loading an old style local
    // Voxel File. If so, load it now. This is not the same as a voxel persist file
    const char* INPUT_FILE = "-i";
    const char* voxelsFilename = getCmdOption(argc, argv, INPUT_FILE);
    if (voxelsFilename) {
        serverTree.readFromSVOFile(voxelsFilename);
    }

    // Check to see if the user passed in a command line option for setting packet send rate
    const char* PACKETS_PER_SECOND = "--packetsPerSecond";
    const char* packetsPerSecond = getCmdOption(argc, argv, PACKETS_PER_SECOND);
    if (packetsPerSecond) {
        PACKETS_PER_CLIENT_PER_INTERVAL = atoi(packetsPerSecond)/10;
        if (PACKETS_PER_CLIENT_PER_INTERVAL < 1) {
            PACKETS_PER_CLIENT_PER_INTERVAL = 1;
        }
        printf("packetsPerSecond=%s PACKETS_PER_CLIENT_PER_INTERVAL=%d\n", packetsPerSecond, PACKETS_PER_CLIENT_PER_INTERVAL);
    }
    
    const char* ADD_RANDOM_VOXELS = "--AddRandomVoxels";
    if (cmdOptionExists(argc, argv, ADD_RANDOM_VOXELS)) {
        // create an octal code buffer and load it with 0 so that the recursive tree fill can give
        // octal codes to the tree nodes that it is creating
        randomlyFillVoxelTree(MAX_VOXEL_TREE_DEPTH_LEVELS, serverTree.rootNode);
    }

    const char* ADD_SCENE = "--AddScene";
    bool addScene = cmdOptionExists(argc, argv, ADD_SCENE);
    const char* NO_ADD_SCENE = "--NoAddScene";
    bool noAddScene = cmdOptionExists(argc, argv, NO_ADD_SCENE);
    if (addScene && noAddScene) {
        printf("WARNING! --AddScene and --NoAddScene are mutually exclusive. We will honor --NoAddScene\n");
    }

    // We will add a scene if...
    //      1) we attempted to load a persistant file and it wasn't there
    //      2) you asked us to add a scene
    // HOWEVER -- we will NEVER add a scene if you explicitly tell us not to!
    //
    // TEMPORARILY DISABLED!!!
    bool actuallyAddScene = false; // !noAddScene && (addScene || (::wantVoxelPersist && !persistantFileRead));
    if (actuallyAddScene) {
        addSphereScene(&serverTree);
    }
    
    // for now, initialize the environments with fixed values
    environmentData[1].setID(1);
    environmentData[1].setGravity(1.0f);
    environmentData[1].setAtmosphereCenter(glm::vec3(0.5, 0.5, (0.25 - 0.06125)) * (float)TREE_SCALE);
    environmentData[1].setAtmosphereInnerRadius(0.030625f * TREE_SCALE);
    environmentData[1].setAtmosphereOuterRadius(0.030625f * TREE_SCALE * 1.05f);
    environmentData[2].setID(2);
    environmentData[2].setGravity(1.0f);
    environmentData[2].setAtmosphereCenter(glm::vec3(0.5f, 0.5f, 0.5f) * (float)TREE_SCALE);
    environmentData[2].setAtmosphereInnerRadius(0.1875f * TREE_SCALE);
    environmentData[2].setAtmosphereOuterRadius(0.1875f * TREE_SCALE * 1.05f);
    environmentData[2].setScatteringWavelengths(glm::vec3(0.475f, 0.570f, 0.650f)); // swaps red and blue
    
    pthread_t sendVoxelThread;
    pthread_create(&sendVoxelThread, NULL, distributeVoxelsToListeners, NULL);

    sockaddr nodePublicAddress;
    
    unsigned char *packetData = new unsigned char[MAX_PACKET_SIZE];
    ssize_t receivedBytes;
    
    timeval lastDomainServerCheckIn = {};

    // loop to send to nodes requesting data
    
    while (true) {

        // send a check in packet to the domain server if DOMAIN_SERVER_CHECK_IN_USECS has elapsed
        if (usecTimestampNow() - usecTimestamp(&lastDomainServerCheckIn) >= DOMAIN_SERVER_CHECK_IN_USECS) {
            gettimeofday(&lastDomainServerCheckIn, NULL);
            NodeList::getInstance()->sendDomainServerCheckIn();
        }
        
        // check to see if we need to persist our voxel state
        persistVoxelsWhenDirty();
    
        if (nodeList->getNodeSocket()->receive(&nodePublicAddress, packetData, &receivedBytes) &&
            packetVersionMatch(packetData)) {
            
            int numBytesPacketHeader = numBytesForPacketHeader(packetData);
            
            if (packetData[0] == PACKET_TYPE_SET_VOXEL || packetData[0] == PACKET_TYPE_SET_VOXEL_DESTRUCTIVE) {
                bool destructive = (packetData[0] == PACKET_TYPE_SET_VOXEL_DESTRUCTIVE);
                PerformanceWarning warn(::shouldShowAnimationDebug,
                                        destructive ? "PACKET_TYPE_SET_VOXEL_DESTRUCTIVE" : "PACKET_TYPE_SET_VOXEL",
                                        ::shouldShowAnimationDebug);
                
                ::receivedPacketCount++;
                
                unsigned short int itemNumber = (*((unsigned short int*)(packetData + numBytesPacketHeader)));
                if (::shouldShowAnimationDebug) {
                    printf("got %s - command from client receivedBytes=%ld itemNumber=%d\n",
                        destructive ? "PACKET_TYPE_SET_VOXEL_DESTRUCTIVE" : "PACKET_TYPE_SET_VOXEL",
                        receivedBytes,itemNumber);
                }
                
                if (::debugVoxelReceiving) {
                    printf("got %s - %d command from client receivedBytes=%ld itemNumber=%d\n",
                        destructive ? "PACKET_TYPE_SET_VOXEL_DESTRUCTIVE" : "PACKET_TYPE_SET_VOXEL",
                        ::receivedPacketCount, receivedBytes,itemNumber);
                }
                int atByte = numBytesPacketHeader + sizeof(itemNumber);
                unsigned char* voxelData = (unsigned char*)&packetData[atByte];
                while (atByte < receivedBytes) {
                    unsigned char octets = (unsigned char)*voxelData;
                    const int COLOR_SIZE_IN_BYTES = 3;
                    int voxelDataSize = bytesRequiredForCodeLength(octets) + COLOR_SIZE_IN_BYTES;
                    int voxelCodeSize = bytesRequiredForCodeLength(octets);

                    // color randomization on insert
                    int colorRandomizer = ::wantColorRandomizer ? randIntInRange (-50, 50) : 0;
                    int red   = voxelData[voxelCodeSize + 0];
                    int green = voxelData[voxelCodeSize + 1];
                    int blue  = voxelData[voxelCodeSize + 2];

                    if (::shouldShowAnimationDebug) {
                        printf("insert voxels - wantColorRandomizer=%s old r=%d,g=%d,b=%d \n",
                            (::wantColorRandomizer?"yes":"no"),red,green,blue);
                    }
                
                    red   = std::max(0, std::min(255, red   + colorRandomizer));
                    green = std::max(0, std::min(255, green + colorRandomizer));
                    blue  = std::max(0, std::min(255, blue  + colorRandomizer));

                    if (::shouldShowAnimationDebug) {
                        printf("insert voxels - wantColorRandomizer=%s NEW r=%d,g=%d,b=%d \n",
                            (::wantColorRandomizer?"yes":"no"),red,green,blue);
                    }
                    voxelData[voxelCodeSize + 0] = red;
                    voxelData[voxelCodeSize + 1] = green;
                    voxelData[voxelCodeSize + 2] = blue;

                    if (::shouldShowAnimationDebug) {
                        float* vertices = firstVertexForCode(voxelData);
                        printf("inserting voxel at: %f,%f,%f\n", vertices[0], vertices[1], vertices[2]);
                        delete []vertices;
                    }
                
                    serverTree.readCodeColorBufferToTree(voxelData, destructive);
                    // skip to next
                    voxelData += voxelDataSize;
                    atByte += voxelDataSize;
                }
            } else if (packetData[0] == PACKET_TYPE_ERASE_VOXEL) {

                // Send these bits off to the VoxelTree class to process them
                pthread_mutex_lock(&::treeLock);
                serverTree.processRemoveVoxelBitstream((unsigned char*)packetData, receivedBytes);
                pthread_mutex_unlock(&::treeLock);
            } else if (packetData[0] == PACKET_TYPE_Z_COMMAND) {

                // the Z command is a special command that allows the sender to send the voxel server high level semantic
                // requests, like erase all, or add sphere scene
                
                char* command = (char*) &packetData[numBytesPacketHeader]; // start of the command
                int commandLength = strlen(command); // commands are null terminated strings
                int totalLength = numBytesPacketHeader + commandLength + 1; // 1 for null termination
                printf("got Z message len(%ld)= %s\n", receivedBytes, command);
                bool rebroadcast = true; // by default rebroadcast

                while (totalLength <= receivedBytes) {
                    if (strcmp(command, ERASE_ALL_COMMAND) == 0) {
                        printf("got Z message == erase all\n");
                        eraseVoxelTreeAndCleanupNodeVisitData();
                        rebroadcast = false;
                    }
                    if (strcmp(command, ADD_SCENE_COMMAND) == 0) {
                        printf("got Z message == add scene\n");
                        addSphereScene(&serverTree);
                        rebroadcast = false;
                    }
                    if (strcmp(command, TEST_COMMAND) == 0) {
                        printf("got Z message == a message, nothing to do, just report\n");
                    }
                    totalLength += commandLength + 1; // 1 for null termination
                }

                if (rebroadcast) {
                    // Now send this to the connected nodes so they can also process these messages
                    printf("rebroadcasting Z message to connected nodes... nodeList.broadcastToNodes()\n");
                    nodeList->broadcastToNodes(packetData, receivedBytes, &NODE_TYPE_AGENT, 1);
                }
            } else if (packetData[0] == PACKET_TYPE_HEAD_DATA) {
                // If we got a PACKET_TYPE_HEAD_DATA, then we're talking to an NODE_TYPE_AVATAR, and we
                // need to make sure we have it in our nodeList.
                
                uint16_t nodeID = 0;
                unpackNodeId(packetData + numBytesPacketHeader, &nodeID);
                Node* node = nodeList->addOrUpdateNode(&nodePublicAddress,
                                                       &nodePublicAddress,
                                                       NODE_TYPE_AGENT,
                                                       nodeID);
                
                nodeList->updateNodeWithData(node, packetData, receivedBytes);
            } else if (packetData[0] == PACKET_TYPE_PING) {
                // If the packet is a ping, let processNodeData handle it.
                nodeList->processNodeData(&nodePublicAddress, packetData, receivedBytes);
            }
        }
    }
    
    pthread_join(sendVoxelThread, NULL);
    pthread_mutex_destroy(&::treeLock);

    return 0;
}
예제 #21
0
파일: main.cpp 프로젝트: Ian-Mills/hifi
int main(int argc, const char* argv[]) {
#ifdef Q_OS_WIN
    // Run only one instance of Interface at a time.
    HANDLE mutex = CreateMutex(NULL, FALSE, "High Fidelity Interface - " + qgetenv("USERNAME"));
    DWORD result = GetLastError();
    if (result == ERROR_ALREADY_EXISTS || result == ERROR_ACCESS_DENIED) {
        // Interface is already running.
        HWND otherInstance = NULL;
        EnumWindows(enumWindowsCallback, (LPARAM)&otherInstance);
        if (otherInstance) {
            // Show other instance.
            SendMessage(otherInstance, UWM_SHOW_APPLICATION, 0, 0);

            // Send command line --url value to other instance.
            if (argc >= 3) {
                QStringList arguments;
                for (int i = 0; i < argc; i += 1) {
                    arguments << argv[i];
                }

                QCommandLineParser parser;
                QCommandLineOption urlOption("url", "", "value");
                parser.addOption(urlOption);
                parser.process(arguments);

                if (parser.isSet(urlOption)) {
                    QUrl url = QUrl(parser.value(urlOption));
                    if (url.isValid() && url.scheme() == HIFI_URL_SCHEME) {
                        QByteArray urlBytes = url.toString().toLatin1();
                        const char* urlChars = urlBytes.data();
                        COPYDATASTRUCT cds;
                        cds.cbData = urlBytes.length() + 1;
                        cds.lpData = (PVOID)urlChars;
                        SendMessage(otherInstance, WM_COPYDATA, 0, (LPARAM)&cds);
                    }
                }
            }
        }
        return 0;
    }
#endif

    QElapsedTimer startupTime;
    startupTime.start();
    
    // Debug option to demonstrate that the client's local time does not 
    // need to be in sync with any other network node. This forces clock 
    // skew for the individual client
    const char* CLOCK_SKEW = "--clockSkew";
    const char* clockSkewOption = getCmdOption(argc, argv, CLOCK_SKEW);
    if (clockSkewOption) {
        int clockSkew = atoi(clockSkewOption);
        usecTimestampNowForceClockSkew(clockSkew);
        qCDebug(interfaceapp, "clockSkewOption=%s clockSkew=%d", clockSkewOption, clockSkew);
    }
    // Oculus initialization MUST PRECEDE OpenGL context creation.
    // The nature of the Application constructor means this has to be either here,
    // or in the main window ctor, before GL startup.
    Application::initPlugins();

    int exitCode;
    {
        QSettings::setDefaultFormat(QSettings::IniFormat);
        Application app(argc, const_cast<char**>(argv), startupTime);

        QTranslator translator;
        translator.load("interface_en");
        app.installTranslator(&translator);
    
        qCDebug(interfaceapp, "Created QT Application.");
        exitCode = app.exec();
    }

    Application::shutdownPlugins();
#ifdef Q_OS_WIN
    ReleaseMutex(mutex);
#endif

    qCDebug(interfaceapp, "Normal exit.");
    return exitCode;
}   
예제 #22
0
int parseCmdOptions(int argc, char *argv[], sim_config_t& config)
{
	char aux[256];
	PropertyFileReader configreader("config.ini");

	//sensing - configuration (NOT USED)
	//configreader.getProperty("SEN_CAMID", &(config.camID));
	//configreader.getProperty("SEN_WIDTH", &(config.width));
	//configreader.getProperty("SEN_HEIGHT", &(config.height));
	//configreader.getProperty("SEN_FPS", &(config.fps));

	//processing - configuration
	//configreader.getProperty("PRO_FREQ", &(config.freq));

	//comms - configuration
	//configreader.getProperty("COM_MaxBITRATE", &(config.maxBitrate));
	//configreader.getProperty("COM_INTERFACE", aux); //network interface
	//config.interface=aux;
	//configreader.getProperty("COM_HOSTIP", aux); //IP for the appvideo_server
	//config.hostIP=aux;
	//configreader.getProperty("COM_HOSTPORT", &(config.hostPort)); //Port for the appvideo_server

	//simulation settings
	configreader.getProperty("POWER_MEAS_REPEAT", &(config.repeat));
	configreader.getProperty("POWER_MEAS_TIME", &(config.time));
	configreader.getProperty("POWER_MEAS_INITTIME", &(config.initialwait));
	configreader.getProperty("POWER_MEAS_SAMPLES", &(config.samples));

	//system settings
	configreader.getProperty("ADMIN_PASSWORD", aux);
	config.adminPass=aux;

	config.filesave="result.dat";

	int tmp;
	configreader.getProperty("VERBOSE", &tmp);
	config.verbose=(bool)tmp;

	//default settings
	config.calibrate = false;

	if(cmdOptionExists(argv, argv+argc, "-help"))
		printhelp();

	if(cmdOptionExists(argv, argv+argc, "-c"))
		config.calibrate = true;

	if(cmdOptionExists(argv, argv+argc, "-f"))
			config.freq = atof(getCmdOption(argv, argv + argc, "-f"));

	if(cmdOptionExists(argv, argv+argc, "-r"))
		config.repeat = atof(getCmdOption(argv, argv + argc, "-r"));

	if(cmdOptionExists(argv, argv+argc, "-t"))
		config.time = atof(getCmdOption(argv, argv + argc, "-t"));

	if(cmdOptionExists(argv, argv+argc, "-n"))
		config.samples = atof(getCmdOption(argv, argv + argc, "-n"));

	if(cmdOptionExists(argv, argv+argc, "-o"))
		config.filesave=getCmdOption(argv, argv + argc, "-o");

	if(cmdOptionExists(argv, argv+argc, "-v"))
		config.verbose = true;

	if(cmdOptionExists(argv, argv+argc, "-nw"))
		config.wait = false;

	if(cmdOptionExists(argv, argv+argc, "-iw"))
		config.initialwait = atof(getCmdOption(argv, argv + argc, "-iw"));

	return 1;
}
예제 #23
0
파일: WHAM.cpp 프로젝트: awritchie/wham
int main(int argc, char * argv[])
{
    /* set defaults */
    const char *    filename; //= "/Users/ritchie/Desktop/MD/Rap1a/cpp_scripts/mcWHAM/mcWHAM/1dof.file";
    const char *    outname;
    char            out[100];
    char            infile[100];
    double          T = 300; // K
    range           begins,ends,bin_sizes;
    double          kb = 0.0083144621; // kJ/(mol*k)
    int             dof = 1;
    bool            bVerbose = false;
    int             niter = 50000;
    double          tol = 1e-9;
    int             firstframe = 0, lastframe = -1;
    
    /* parse through arguments */
    if (cmdOptionExists(argv, argv+argc, "--t")) {
        char * temp = getCmdOption(argv, argv+argc, "--t");
        sscanf(temp, "%lf", &T);
        if ( T < 0 ) { std::cout << "ERROR: Temperature < 0" << std::endl; exit(1); }
    }
    if (cmdOptionExists(argv, argv+argc, "--dof")) {
        char * chardof = getCmdOption(argv, argv+argc, "--dof")  ;
        sscanf(chardof, "%d", &dof);
        if ( dof < 1 ) { std::cout << "ERROR: Fewer than 1 degree of freedom" << std::endl; exit(1); }
    }
    if (cmdOptionExists(argv, argv+argc, "--s")) {
        begins = getMultiCmdOption(argv, argv+argc, "--s");
    }
    else 
    {
        begins.values=new double [dof];
        for (int i=0;i<dof;i++){begins.values[i]=-180;}
        begins.n_values=dof;
    }
    if (cmdOptionExists(argv, argv+argc, "--e")) {
        ends = getMultiCmdOption(argv, argv+argc, "--e");
    }
    else 
    {
        ends.values=new double [dof];
        for (int i=0;i<dof;i++){ends.values[i]=180;}
        ends.n_values=dof;
    }
    if (cmdOptionExists(argv, argv+argc, "--b")) {
        bin_sizes = getMultiCmdOption(argv, argv+argc, "--b");
        for (int i=0 ; i<bin_sizes.n_values ; i++)
        {
            if ( bin_sizes.values[i] <= 0 ) { std::cout << "ERROR: Bin size <= 0" << std::endl; exit(1); }
        }
    }
    else 
    {
        bin_sizes.values=new double [dof];
        for (int i=0;i<dof;i++){bin_sizes.values[i]=5;}
        bin_sizes.n_values=dof;
    }
    if (cmdOptionExists(argv, argv+argc, "--tol")) {
        char * tolerance = getCmdOption(argv, argv+argc, "--tol");
        sscanf(tolerance, "%lf", &tol);
    }
    if (cmdOptionExists(argv, argv+argc, "--iter")) {
        char * iter = getCmdOption(argv, argv+argc, "--iter");
        sscanf(iter, "%d", &niter);
    }
    if (cmdOptionExists(argv, argv+argc, "--v")) {
        bVerbose = true;
    }
    if (cmdOptionExists(argv, argv+argc, "--fb")) {
        char * frame0 = getCmdOption(argv, argv+argc, "--fb");
        sscanf(frame0,"%d",&firstframe);
    }
    if (cmdOptionExists(argv, argv+argc, "--fe")) {
        char * frameN = getCmdOption(argv, argv+argc, "--fe");
        sscanf(frameN,"%d",&lastframe);
    }
    if (cmdOptionExists(argv, argv+argc, "--f")) {
        filename = getCmdOption(argv, argv+argc, "--f");
    }
    else { 
        userinfo(T, begins.values[0], ends.values[0], bin_sizes.values[0], dof, tol, niter, bVerbose);
        exit(1);
    }
    if (cmdOptionExists(argv, argv+argc, "--o")) {
        outname = getCmdOption(argv, argv+argc, "--o");
    }
    else { outname = filename; }
    if (cmdOptionExists(argv, argv+argc , "--h") || cmdOptionExists(argv, argv+argc, "--help") || cmdOptionExists(argv, argv+argc, "-h") || argc == 1) {
        userinfo(T, begins.values[0], ends.values[0], bin_sizes.values[0], dof, tol, niter, bVerbose);
        exit(1);
    }

    else { userinfo(T,begins.values[0],ends.values[0],bin_sizes.values[0],dof,tol,niter,bVerbose); }
    compare_len(dof, "degrees of freedom", begins.n_values, "coordinate starting ranges" );
    compare_len(dof, "degrees of freedom", ends.n_values, "coordinate ending ranges" );
    compare_len(dof, "degrees of freedom", bin_sizes.n_values, "bin sizes" );

    strcpy(infile,filename);
    strcpy(out,outname);
    strcat(out,".mean");
    
    /* This is purely for output information purposes */
    char finalframe[100];
    if (lastframe != -1) { sprintf(finalframe,"%d",lastframe); }
    else { sprintf(finalframe,"end"); }
    
    std::cout << "--------------------------------------------------------------------------------" << std::endl;
    std::cout << "Will read " << infile << " from frame " << firstframe << " to " << finalframe << "." << std::endl;
    std::cout << "Temperature = " << T << " K" << std::endl;
    std::cout << "Thermal Energy = " << kb*T << " kJ/mol" << std::endl;
    std::cout << "Biasing coordinate range(s) = ";
    for (int i=0; i<dof; i++) 
    {  
        std::cout << begins.values[i] << " to " << ends.values[i] << "    ";
    }        
    std::cout << "\nBin size(s) = ";
    for (int i=0; i<dof; i++) 
    {
        std::cout << bin_sizes.values[i] << "    ";
    }
    std::cout << "\nDegrees of freedom = " << dof << std::endl;
    std::cout << "Will iterate up to " << niter << " times until converged to " << tol <<"."<< std::endl;
    std::cout << "Will write to " << out << std::endl;
    std::cout << "--------------------------------------------------------------------------------" << std::endl;

    /* Extract biasing coordinate information from files listed in infile */
    int n_files=get_n_lines(infile);
    TorsionExperiment * experiment = new TorsionExperiment [n_files];
    
    std::string line;
    std::ifstream file (infile);
    int first_experiment=1000;
    int previous_experiment=-1;
    int previous_dof=-1;
    int i=0;
    if ( file.is_open() )
    {
        while ( file.good() )
        {
            getline( file, line) ;
            if ( line == "\n" || line == "" ) { break;}
            std::cout << "Opening " << infile << std::endl;

            experiment[i].read_filelist( line, previous_experiment, previous_dof, begins.values, ends.values, bin_sizes.values, kb, bVerbose );
            previous_experiment=experiment[i].Experiment();
            previous_dof=experiment[i].DoF();
            if ( experiment[i].Experiment() < first_experiment ) { first_experiment=experiment[i].Experiment(); }
            i++;
        }
    }
    else if (!file) {std::cout << "Error opening " << infile << "." << std::endl; exit(1);} 
                
    /* Find out how many total bins */
    int nstates=1;
    for (int d=0; d<dof; d++)
    {
        for (int i=0; i<n_files; i++)
        {
            if ( experiment[i].DoF() == d )
            {
                nstates *= experiment[i].trajectory.nBins();
                break; // the nth DoF for experiment 1 should have the same number of bins as the nth DoF for experiment 2, which should have the same number of bins as experiment 3, which...  so only look at the first experiment worth of DoFs
            }
        }
    }
    
    int * counts = new int [nstates];
    int * samples = new int [n_files/dof];
    long double ** omegas = new long double * [n_files/dof];
    for (int i=0;i<nstates;i++){counts[i]=0;}
    std::cout<<std::endl;
    
    int ** group_traj;
    nD_WHAM_grouping(experiment, dof, n_files, first_experiment, group_traj, bVerbose);

    /* Count the number of times each bin is visited throughout the overall simulation */
    for (int trajectory=0; trajectory<n_files/dof; trajectory++)
    {        
        std::ofstream binfile;
        char binname[100];
        sprintf(binname,"%s.%i.bin",outname,trajectory);
        binfile.open(binname);
        if (bVerbose){std::cout << "Writing bin assignments for experiment " << trajectory << " to " << binname << "." << std::endl;}
        int final_frame_to_read = experiment[group_traj[trajectory][0]].trajectory.nFrames();
        if ( lastframe < final_frame_to_read && lastframe != -1 ) { final_frame_to_read = lastframe+1; }
        for (int frame=firstframe; frame<final_frame_to_read; frame++)
        {
            int this_bin=0;
            int dofprod=1;
            for (int this_dof=0; this_dof<dof ; this_dof++)
            {
                if (this_dof > 0)
                {
                    dofprod *= experiment[group_traj[trajectory][this_dof-1]].trajectory.nBins();
                }
                this_bin += experiment[group_traj[trajectory][this_dof]].trajectory.BinID()[frame]*dofprod;
            }
//            cout << experiment[group_traj[trajectory][0]].trajectory.BinID()[frame] << " " << experiment[group_traj[trajectory][1]].trajectory.BinID()[frame] << " " << this_bin << endl;
            counts[this_bin]++;
            binfile << this_bin << "\n";
        }
        binfile.close();
        
        /* Also, while looking through trajectories, we need to build nD omega array for each
         I could not figure out a good (any) way to do this for n dimensions, so I'm going up to 3... */
        omegas[trajectory]=new long double [nstates];
        
        switch ( dof )
        {
            case 1:
            {
                omegas[trajectory]=experiment[group_traj[trajectory][dof-1]].Omega();
                break;
            }
            case 2:
            {
                int m=0;
                for (int j=0; j<experiment[group_traj[trajectory][dof-1]].trajectory.nBins(); j++)
                {
                    for (int i=0; i<experiment[group_traj[trajectory][dof-2]].trajectory.nBins(); i++)
                    {
                        omegas[trajectory][m]=experiment[group_traj[trajectory][dof-2]].Omega()[i]*experiment[group_traj[trajectory][dof-1]].Omega()[j];
                        m++;
                    }
                }
                break;
            }
            case 3:
            {
                int m=0;
                for (int k=0; k<experiment[group_traj[trajectory][dof-1]].trajectory.nBins(); k++)
                {
                    for (int j=0; j<experiment[group_traj[trajectory][dof-2]].trajectory.nBins(); j++)
                    {
                        for (int i=0; i<experiment[group_traj[trajectory][dof-3]].trajectory.nBins(); i++)
                        {
                            omegas[trajectory][m]=experiment[group_traj[trajectory][dof-1]].Omega()[i]*experiment[group_traj[trajectory][dof-2]].Omega()[j]*experiment[group_traj[trajectory][dof-3]].trajectory.nBins();
                            m++;
                        }
                    }
                }
                break;
            }
            default :
            {
                std::cout << "You have " << dof << " degrees of freedom.  Currently, only up to 3 degrees of freedom can be handled.  Exiting..." << std::endl;
                exit(1);
            }
        }
    }
    
    std::cout << "Built (" << n_files/dof << "x" << nstates << ") omega matrix." << std::endl;
    int nzeros=0;
    std::cout << dof << "-Dimensional State counts: [ ";
    for (int i=0;i<nstates;i++){
        std::cout<<counts[i]<<" ";
        if (counts[i] == 0){nzeros++;}
    }
    std::cout << "]\n" << std::endl;
   
    if (bVerbose) 
    {
        for (int n=0;n<n_files/dof;n++)
        {
            std::cout << "Omega for experiment " << n << ": [ ";
            for (int i=0;i<nstates;i++){
                std::cout<<omegas[n][i]<<" ";
            }
            std::cout << "]\n" << std::endl;
        }
    }
   
    if ( nzeros > 0 )
    {
        float percent = 100.0;
        percent *= nzeros;
        percent /= nstates;
        std::cout << nzeros << " (" << percent << "%) bins unvisited.  Consider additional sampling if this number is large." << std::endl;
    }
    
    std::cout << "Samples: [ ";
    int n=0;
    for (int i=0;i<n_files;i+=dof)
    {
        std::cout<<experiment[i].trajectory.nFrames()<<" ";
        samples[n]=experiment[i].trajectory.nFrames();
        n++;
    }
    std::cout << "]" << std::endl;
    
    // settings and inital conditions 
    long double * w0 = new long double [nstates];
    long double pnstates = 1.0/nstates;
    for (int i=0; i<nstates; i++)
    {
        w0[i]=pnstates;
    }
    
    std::cout << "OPTIMIZING" << std::endl;
    DOWHAM opttrajectory;
    opttrajectory.DoWham(w0, counts, samples, omegas, nstates, n_files/dof, niter, tol);
    std::cout << "Ran " << opttrajectory.Points() << " points of optimization." << "\n[ ";
    for (int i=0;i<nstates;i++){
        std::cout << opttrajectory.OptTrajectory()[i] << " ";
    }
    std::cout << "]" << std::endl;
  
/* Not doing the Monte Carlo part; it seems unneccessary */
    
    /* I don't know if this is the best way to handle the experimental temperatures... */
    double exp_T = 0;
    int total_frames=0;
    for (int i=0; i<n_files/dof; i++)
    {
        total_frames += experiment[group_traj[i][0]].trajectory.nFrames();
        exp_T += experiment[group_traj[i][0]].T()*experiment[group_traj[i][0]].trajectory.nFrames();
    }
    exp_T /= total_frames;
    
    /* Calculate the PMF_bin(i) as -kT ln(w(i)).  Assume for any bin that had '0' visits, the potential is 1000 */
    double long * potential = new double long [nstates];
    for (int i=0; i<nstates; i++)
    {
        if ( opttrajectory.OptTrajectory()[i] == 0 )
        {
            potential[i]=100;
        }
        else 
        {
            potential[i]=-kb*exp_T*log( opttrajectory.OptTrajectory()[i] );
        }
    }

    
    /* Now go back and calculate the probability for the now-appropriate temperature */
    double long * probability = new double long [nstates];
    double long prob_sum=0;
    for (int i=0; i<nstates; i++)
    {
        probability[i]=exp(-1/(kb*T)*potential[i]);
        prob_sum += probability[i];
    }
    std::cout << std::endl;
    for (int i=0; i<nstates; i++)
    {
        probability[i] /= prob_sum;
    }

    /* Make output files */
    /* Start with 1 DoF PMF and probability files.  I've not had much reason to use the PMF file, but the 1 DoF probability file is best used with the .bin files for boltzmann weighting, since they are assigned in 1 dimension, no matter the number of DoF used. */
    std::ofstream prob;
    std::ofstream pmf;
    std::ofstream count;
    char probname[100];
    char pmfname[100];
    char countname[100];
    sprintf(probname, "%s.prob", outname);
    sprintf(pmfname, "%s.mean", outname);
    sprintf(countname,"%s.count", outname);
    prob.open(probname);
    pmf.open(pmfname);
    count.open(countname);
    for (int i=0; i<nstates; i++)
    {
        prob << probability[i] << std::endl;
        pmf << potential[i] << std::endl;
        count << counts[i] << std::endl;
    }
    prob.close();
    pmf.close();
    count.close();
    std::cout << "Potential of mean force written to " << pmfname << "." << std::endl;
    std::cout << "Probabilities written to " << probname << "." << std::endl;

    
    if ( dof == 2 )
    {
        std::ofstream d2prob;
        std::ofstream ncount;
        std::ofstream d2pmf;
        char countname[100];
        sprintf(countname,"%s.2dcount", outname);
        ncount.open(countname);
        char d2name[100];
        sprintf(d2name,"%s.2dprob",outname);
        d2prob.open(d2name);
        char d2pmfname[100];
        sprintf(d2pmfname,"%s.2dmean",outname);
        d2pmf.open(d2pmfname);
        int bin=0;
        for (int j=0; j < experiment[group_traj[0][1]].trajectory.nBins() ; j++)
        {
            for (int i=0; i < experiment[group_traj[0][0]].trajectory.nBins() ; i++)
            {
                d2prob << i*bin_sizes.values[0]-ends.values[0] << " " << j*bin_sizes.values[1]-ends.values[1] << " " << probability[bin] << std::endl;

                ncount << i*bin_sizes.values[0]-ends.values[0] << " " << j*bin_sizes.values[1]-ends.values[1] << " " << counts[bin] << std::endl;
                d2pmf  << i*bin_sizes.values[0]-ends.values[0] << " " << j*bin_sizes.values[1]-ends.values[1] << " " << potential[bin] << std::endl;
                bin++;
            }
            d2prob << std::endl;
            ncount << std::endl;
            d2pmf << std::endl;
        }
        d2prob.close();
        ncount.close();
        d2pmf.close();
    }
    
    else if ( dof == 3 )
    {
        std::ofstream d3prob;
        std::ofstream ncount;
        char countname[100];
        sprintf(countname,"%s.3dcount", outname);
        ncount.open(countname);
        char d3name[100];
        sprintf(d3name,"%s.3dprob",outname);
        d3prob.open(d3name);
        int bin=0;
        for (int k=0; k < experiment[group_traj[0][2]].trajectory.nBins() ; k++)
        {
            for (int j=0; j < experiment[group_traj[0][1]].trajectory.nBins() ; j++)
            {
                for (int i=0; i < experiment[group_traj[0][0]].trajectory.nBins() ; i++)
                {
                    d3prob << j*bin_sizes.values[0]-ends.values[0] << " " << i*bin_sizes.values[1]-ends.values[1] << " " << k*bin_sizes.values[2]-ends.values[2] << " " << probability[bin] << std::endl;
                    ncount << j*bin_sizes.values[0]-ends.values[0] << " " << i*bin_sizes.values[1]-ends.values[1] << " " << k*bin_sizes.values[2]-ends.values[2] << " " << counts[bin] << std::endl;
                    bin++;
                }
            }
            d3prob << std::endl;
            ncount << std::endl;
        }
        d3prob.close();   
    }

    std::cout << "--------------------------------------------------------------------------------" << std::endl;
    std::cout << "Read " << infile << " from frame " << firstframe << " to " << finalframe << "." << std::endl;
    std::cout << "Temperature = " << T << " K" << std::endl;
    std::cout << "Thermal Energy = " << kb*T << " kJ/mol" << std::endl;
    std::cout << "Biasing coordinate range(s) = ";
    for (int i=0; i<dof; i++) 
    {  
        std::cout << begins.values[i] << " to " << ends.values[i] << "    ";
    }        
    std::cout << "\nBin size(s) = ";
    for (int i=0; i<dof; i++) 
    {
        std::cout << bin_sizes.values[i] << "    ";
    }
    std::cout << "\nDegrees of freedom = " << dof << std::endl;
    std::cout << "Converged to " << tol <<"."<< std::endl;
    std::cout << "--------------------------------------------------------------------------------" << std::endl;
    return 0;
}
예제 #24
0
void OctreeServer::run() {
    // Before we do anything else, create our tree...
    _tree = createTree();
    
    // change the logging target name while this is running
    Logging::setTargetName(getMyLoggingServerTargetName());

    // Now would be a good time to parse our arguments, if we got them as assignment
    if (getNumPayloadBytes() > 0) {
        parsePayload();
    }

    beforeRun(); // after payload has been processed

    qInstallMessageHandler(Logging::verboseMessageHandler);
    
    const char* STATUS_PORT = "--statusPort";
    const char* statusPort = getCmdOption(_argc, _argv, STATUS_PORT);
    if (statusPort) {
        int statusPortNumber = atoi(statusPort);
        initMongoose(statusPortNumber);
    }

    
    const char* JURISDICTION_FILE = "--jurisdictionFile";
    const char* jurisdictionFile = getCmdOption(_argc, _argv, JURISDICTION_FILE);
    if (jurisdictionFile) {
        qDebug("jurisdictionFile=%s\n", jurisdictionFile);

        qDebug("about to readFromFile().... jurisdictionFile=%s\n", jurisdictionFile);
        _jurisdiction = new JurisdictionMap(jurisdictionFile);
        qDebug("after readFromFile().... jurisdictionFile=%s\n", jurisdictionFile);
    } else {
        const char* JURISDICTION_ROOT = "--jurisdictionRoot";
        const char* jurisdictionRoot = getCmdOption(_argc, _argv, JURISDICTION_ROOT);
        if (jurisdictionRoot) {
            qDebug("jurisdictionRoot=%s\n", jurisdictionRoot);
        }

        const char* JURISDICTION_ENDNODES = "--jurisdictionEndNodes";
        const char* jurisdictionEndNodes = getCmdOption(_argc, _argv, JURISDICTION_ENDNODES);
        if (jurisdictionEndNodes) {
            qDebug("jurisdictionEndNodes=%s\n", jurisdictionEndNodes);
        }

        if (jurisdictionRoot || jurisdictionEndNodes) {
            _jurisdiction = new JurisdictionMap(jurisdictionRoot, jurisdictionEndNodes);
        }
    }

    NodeList* nodeList = NodeList::getInstance();
    nodeList->setOwnerType(getMyNodeType());
    
    // we need to ask the DS about agents so we can ping/reply with them
    const char nodeTypesOfInterest[] = { NODE_TYPE_AGENT, NODE_TYPE_ANIMATION_SERVER};
    nodeList->setNodeTypesOfInterest(nodeTypesOfInterest, sizeof(nodeTypesOfInterest));
    
    setvbuf(stdout, NULL, _IOLBF, 0);

    // tell our NodeList about our desire to get notifications
    nodeList->addHook(this);
    nodeList->linkedDataCreateCallback = &OctreeServer::attachQueryNodeToNode;

    srand((unsigned)time(0));
    
    const char* VERBOSE_DEBUG = "--verboseDebug";
    _verboseDebug =  cmdOptionExists(_argc, _argv, VERBOSE_DEBUG);
    qDebug("verboseDebug=%s\n", debug::valueOf(_verboseDebug));

    const char* DEBUG_SENDING = "--debugSending";
    _debugSending =  cmdOptionExists(_argc, _argv, DEBUG_SENDING);
    qDebug("debugSending=%s\n", debug::valueOf(_debugSending));

    const char* DEBUG_RECEIVING = "--debugReceiving";
    _debugReceiving =  cmdOptionExists(_argc, _argv, DEBUG_RECEIVING);
    qDebug("debugReceiving=%s\n", debug::valueOf(_debugReceiving));

    // By default we will persist, if you want to disable this, then pass in this parameter
    const char* NO_PERSIST = "--NoPersist";
    if (cmdOptionExists(_argc, _argv, NO_PERSIST)) {
        _wantPersist = false;
    }
    qDebug("wantPersist=%s\n", debug::valueOf(_wantPersist));

    // if we want Persistence, set up the local file and persist thread
    if (_wantPersist) {

        // Check to see if the user passed in a command line option for setting packet send rate
        const char* PERSIST_FILENAME = "--persistFilename";
        const char* persistFilenameParameter = getCmdOption(_argc, _argv, PERSIST_FILENAME);
        if (persistFilenameParameter) {
            strcpy(_persistFilename, persistFilenameParameter);
        } else {
            strcpy(_persistFilename, getMyDefaultPersistFilename());
        }

        qDebug("persistFilename=%s\n", _persistFilename);

        // now set up PersistThread
        _persistThread = new OctreePersistThread(_tree, _persistFilename);
        if (_persistThread) {
            _persistThread->initialize(true);
        }
    }
    
    // Debug option to demonstrate that the server's local time does not 
    // need to be in sync with any other network node. This forces clock 
    // skew for the individual server node
    const char* CLOCK_SKEW = "--clockSkew";
    const char* clockSkewOption = getCmdOption(_argc, _argv, CLOCK_SKEW);
    if (clockSkewOption) {
        int clockSkew = atoi(clockSkewOption);
        usecTimestampNowForceClockSkew(clockSkew);
        qDebug("clockSkewOption=%s clockSkew=%d\n", clockSkewOption, clockSkew);
    }

    // Check to see if the user passed in a command line option for setting packet send rate
    const char* PACKETS_PER_SECOND = "--packetsPerSecond";
    const char* packetsPerSecond = getCmdOption(_argc, _argv, PACKETS_PER_SECOND);
    if (packetsPerSecond) {
        _packetsPerClientPerInterval = atoi(packetsPerSecond) / INTERVALS_PER_SECOND;
        if (_packetsPerClientPerInterval < 1) {
            _packetsPerClientPerInterval = 1;
        }
        qDebug("packetsPerSecond=%s PACKETS_PER_CLIENT_PER_INTERVAL=%d\n", packetsPerSecond, _packetsPerClientPerInterval);
    }

    HifiSockAddr senderSockAddr;
    
    // set up our jurisdiction broadcaster...
    if (_jurisdiction) {
        _jurisdiction->setNodeType(getMyNodeType());
    }
    _jurisdictionSender = new JurisdictionSender(_jurisdiction, getMyNodeType());
    _jurisdictionSender->initialize(true);
    
    // set up our OctreeServerPacketProcessor
    _octreeInboundPacketProcessor = new OctreeInboundPacketProcessor(this);
    _octreeInboundPacketProcessor->initialize(true);

    // Convert now to tm struct for local timezone
    tm* localtm = localtime(&_started);
    const int MAX_TIME_LENGTH = 128;
    char localBuffer[MAX_TIME_LENGTH] = { 0 };
    char utcBuffer[MAX_TIME_LENGTH] = { 0 };
    strftime(localBuffer, MAX_TIME_LENGTH, "%m/%d/%Y %X", localtm);
    // Convert now to tm struct for UTC
    tm* gmtm = gmtime(&_started);
    if (gmtm != NULL) {
        strftime(utcBuffer, MAX_TIME_LENGTH, " [%m/%d/%Y %X UTC]", gmtm);
    }
    qDebug() << "Now running... started at: " << localBuffer << utcBuffer << "\n";
    
    QTimer* domainServerTimer = new QTimer(this);
    connect(domainServerTimer, SIGNAL(timeout()), this, SLOT(checkInWithDomainServerOrExit()));
    domainServerTimer->start(DOMAIN_SERVER_CHECK_IN_USECS / 1000);
    
    QTimer* silentNodeTimer = new QTimer(this);
    connect(silentNodeTimer, SIGNAL(timeout()), nodeList, SLOT(removeSilentNodes()));
    silentNodeTimer->start(NODE_SILENCE_THRESHOLD_USECS / 1000);
    
    QTimer* pingNodesTimer = new QTimer(this);
    connect(pingNodesTimer, SIGNAL(timeout()), nodeList, SLOT(pingInactiveNodes()));
    pingNodesTimer->start(PING_INACTIVE_NODE_INTERVAL_USECS / 1000);
}
예제 #25
0
파일: main.cpp 프로젝트: mvpeng/hifi
int main(int argc, const char* argv[]) {
    
    qInstallMessageHandler(Logging::verboseMessageHandler);
    
    NodeList* nodeList = NodeList::createInstance(NODE_TYPE_DOMAIN, DOMAIN_LISTEN_PORT);

    setvbuf(stdout, NULL, _IOLBF, 0);
    
    ssize_t receivedBytes = 0;
    char nodeType = '\0';
    
    unsigned char broadcastPacket[MAX_PACKET_SIZE];
    
    unsigned char* currentBufferPos;
    unsigned char* startPointer;
    
    sockaddr_in nodePublicAddress, nodeLocalAddress, replyDestinationSocket;
    nodeLocalAddress.sin_family = AF_INET;
    
    in_addr_t serverLocalAddress = getLocalAddress();
    
    nodeList->startSilentNodeRemovalThread();
    
    timeval lastStatSendTime = {};
    const char ASSIGNMENT_SERVER_OPTION[] = "-a";
    
    // grab the overriden assignment-server hostname from argv, if it exists
    const char* customAssignmentServer = getCmdOption(argc, argv, ASSIGNMENT_SERVER_OPTION);
    if (customAssignmentServer) {
        sockaddr_in customAssignmentSocket = socketForHostnameAndHostOrderPort(customAssignmentServer, ASSIGNMENT_SERVER_PORT);
        nodeList->setAssignmentServerSocket((sockaddr*) &customAssignmentSocket);
    }
    
    // use a map to keep track of iterations of silence for assignment creation requests
    const long long GLOBAL_ASSIGNMENT_REQUEST_INTERVAL_USECS = 1 * 1000 * 1000;
    timeval lastGlobalAssignmentRequest = {};
    
    // as a domain-server we will always want an audio mixer and avatar mixer
    // setup the create assignments for those
    Assignment audioMixerAssignment(Assignment::CreateCommand,
                                    Assignment::AudioMixerType,
                                    Assignment::LocalLocation);
    
    Assignment avatarMixerAssignment(Assignment::CreateCommand,
                                     Assignment::AvatarMixerType,
                                     Assignment::LocalLocation);
    
    // construct a local socket to send with our created assignments to the global AS
    sockaddr_in localSocket = {};
    localSocket.sin_family = AF_INET;
    localSocket.sin_port = htons(nodeList->getInstance()->getNodeSocket()->getListeningPort());
    localSocket.sin_addr.s_addr = serverLocalAddress;
    
    // setup the mongoose web server
    struct mg_context *ctx;
    struct mg_callbacks callbacks = {};
    
    // list of options. Last element must be NULL.
    const char *options[] = {"listening_ports", "8080",
                             "document_root", "./resources/web", NULL};
    
    callbacks.begin_request = mongooseRequestHandler;
    callbacks.upload = mongooseUploadHandler;
    
    // Start the web server.
    ctx = mg_start(&callbacks, NULL, options);
    
    while (true) {
        
        ::assignmentQueueMutex.lock();
        // check if our audio-mixer or avatar-mixer are dead and we don't have existing assignments in the queue
        // so we can add those assignments back to the front of the queue since they are high-priority
        if (!nodeList->soloNodeOfType(NODE_TYPE_AVATAR_MIXER) &&
            std::find(::assignmentQueue.begin(), assignmentQueue.end(), &avatarMixerAssignment) == ::assignmentQueue.end()) {
            qDebug("Missing an avatar mixer and assignment not in queue. Adding.\n");
            ::assignmentQueue.push_front(&avatarMixerAssignment);
        }
        
        if (!nodeList->soloNodeOfType(NODE_TYPE_AUDIO_MIXER) &&
            std::find(::assignmentQueue.begin(), ::assignmentQueue.end(), &audioMixerAssignment) == ::assignmentQueue.end()) {
            qDebug("Missing an audio mixer and assignment not in queue. Adding.\n");
            ::assignmentQueue.push_front(&audioMixerAssignment);
        }
        ::assignmentQueueMutex.unlock();
        
        while (nodeList->getNodeSocket()->receive((sockaddr *)&nodePublicAddress, packetData, &receivedBytes) &&
               packetVersionMatch(packetData)) {
            if (packetData[0] == PACKET_TYPE_DOMAIN_REPORT_FOR_DUTY || packetData[0] == PACKET_TYPE_DOMAIN_LIST_REQUEST) {
                // this is an RFD or domain list request packet, and there is a version match
                std::map<char, Node *> newestSoloNodes;
                
                int numBytesSenderHeader = numBytesForPacketHeader(packetData);
                
                nodeType = *(packetData + numBytesSenderHeader);
                int numBytesSocket = unpackSocket(packetData + numBytesSenderHeader + sizeof(NODE_TYPE),
                                                  (sockaddr*) &nodeLocalAddress);
                
                replyDestinationSocket = nodePublicAddress;
                
                // check the node public address
                // if it matches our local address
                // or if it's the loopback address we're on the same box
                if (nodePublicAddress.sin_addr.s_addr == serverLocalAddress ||
                    nodePublicAddress.sin_addr.s_addr == htonl(INADDR_LOOPBACK)) {
                    
                    nodePublicAddress.sin_addr.s_addr = 0;
                }
                
                Node* newNode = nodeList->addOrUpdateNode((sockaddr*) &nodePublicAddress,
                                                          (sockaddr*) &nodeLocalAddress,
                                                          nodeType,
                                                          nodeList->getLastNodeID());
                
                // if addOrUpdateNode returns NULL this was a solo node we already have, don't talk back to it
                if (newNode) {
                    if (newNode->getNodeID() == nodeList->getLastNodeID()) {
                        nodeList->increaseNodeID();
                    }
                    
                    int numHeaderBytes = populateTypeAndVersion(broadcastPacket, PACKET_TYPE_DOMAIN);
                    
                    currentBufferPos = broadcastPacket + numHeaderBytes;
                    startPointer = currentBufferPos;
                    
                    unsigned char* nodeTypesOfInterest = packetData + numBytesSenderHeader + sizeof(NODE_TYPE)
                    + numBytesSocket + sizeof(unsigned char);
                    int numInterestTypes = *(nodeTypesOfInterest - 1);
                    
                    if (numInterestTypes > 0) {
                        // if the node has sent no types of interest, assume they want nothing but their own ID back
                        for (NodeList::iterator node = nodeList->begin(); node != nodeList->end(); node++) {
                            if (!node->matches((sockaddr*) &nodePublicAddress, (sockaddr*) &nodeLocalAddress, nodeType) &&
                                memchr(nodeTypesOfInterest, node->getType(), numInterestTypes)) {
                                // this is not the node themselves
                                // and this is an node of a type in the passed node types of interest
                                // or the node did not pass us any specific types they are interested in
                                
                                if (memchr(SOLO_NODE_TYPES, node->getType(), sizeof(SOLO_NODE_TYPES)) == NULL) {
                                    // this is an node of which there can be multiple, just add them to the packet
                                    // don't send avatar nodes to other avatars, that will come from avatar mixer
                                    if (nodeType != NODE_TYPE_AGENT || node->getType() != NODE_TYPE_AGENT) {
                                        currentBufferPos = addNodeToBroadcastPacket(currentBufferPos, &(*node));
                                    }
                                    
                                } else {
                                    // solo node, we need to only send newest
                                    if (newestSoloNodes[node->getType()] == NULL ||
                                        newestSoloNodes[node->getType()]->getWakeMicrostamp() < node->getWakeMicrostamp()) {
                                        // we have to set the newer solo node to add it to the broadcast later
                                        newestSoloNodes[node->getType()] = &(*node);
                                    }
                                }
                            }
                        }
                        
                        for (std::map<char, Node *>::iterator soloNode = newestSoloNodes.begin();
                             soloNode != newestSoloNodes.end();
                             soloNode++) {
                            // this is the newest alive solo node, add them to the packet
                            currentBufferPos = addNodeToBroadcastPacket(currentBufferPos, soloNode->second);
                        }
                    }
                    
                    // update last receive to now
                    uint64_t timeNow = usecTimestampNow();
                    newNode->setLastHeardMicrostamp(timeNow);
                    
                    if (packetData[0] == PACKET_TYPE_DOMAIN_REPORT_FOR_DUTY
                        && memchr(SOLO_NODE_TYPES, nodeType, sizeof(SOLO_NODE_TYPES))) {
                        newNode->setWakeMicrostamp(timeNow);
                    }
                    
                    // add the node ID to the end of the pointer
                    currentBufferPos += packNodeId(currentBufferPos, newNode->getNodeID());
                    
                    // send the constructed list back to this node
                    nodeList->getNodeSocket()->send((sockaddr*)&replyDestinationSocket,
                                                    broadcastPacket,
                                                    (currentBufferPos - startPointer) + numHeaderBytes);
                }
            } else if (packetData[0] == PACKET_TYPE_REQUEST_ASSIGNMENT) {
                
                qDebug("Received a request for assignment.\n");
                
                ::assignmentQueueMutex.lock();
                
                // this is an unassigned client talking to us directly for an assignment
                // go through our queue and see if there are any assignments to give out
                std::deque<Assignment*>::iterator assignment = ::assignmentQueue.begin();
                
                while (assignment != ::assignmentQueue.end()) {
                    
                    // give this assignment out, no conditions stop us from giving it to the local assignment client
                    int numHeaderBytes = populateTypeAndVersion(broadcastPacket, PACKET_TYPE_CREATE_ASSIGNMENT);
                    int numAssignmentBytes = (*assignment)->packToBuffer(broadcastPacket + numHeaderBytes);
                    
                    nodeList->getNodeSocket()->send((sockaddr*) &nodePublicAddress,
                                                    broadcastPacket,
                                                    numHeaderBytes + numAssignmentBytes);
                    
                    // remove the assignment from the queue
                    ::assignmentQueue.erase(assignment);
                    
                    if ((*assignment)->getType() == Assignment::AgentType) {
                        // if this is a script assignment we need to delete it to avoid a memory leak
                        delete *assignment;
                    }
                    
                    // stop looping, we've handed out an assignment
                    break;
                }
                
                ::assignmentQueueMutex.unlock();
            }
        }
        
        // if ASSIGNMENT_REQUEST_INTERVAL_USECS have passed since last global assignment request then fire off another
        if (usecTimestampNow() - usecTimestamp(&lastGlobalAssignmentRequest) >= GLOBAL_ASSIGNMENT_REQUEST_INTERVAL_USECS) {
            gettimeofday(&lastGlobalAssignmentRequest, NULL);
            
            ::assignmentQueueMutex.lock();
            
            // go through our queue and see if there are any assignments to send to the global assignment server
            std::deque<Assignment*>::iterator assignment = ::assignmentQueue.begin();
            
            while (assignment != assignmentQueue.end()) {
                
                if ((*assignment)->getLocation() != Assignment::LocalLocation) {                    
                    // attach our local socket to the assignment so the assignment-server can optionally hand it out
                    (*assignment)->setAttachedLocalSocket((sockaddr*) &localSocket);
                    
                    nodeList->sendAssignment(*(*assignment));
                    
                    // remove the assignment from the queue
                    ::assignmentQueue.erase(assignment);
                    
                    if ((*assignment)->getType() == Assignment::AgentType) {
                        // if this is a script assignment we need to delete it to avoid a memory leak
                        delete *assignment;
                    }
                    
                    // stop looping, we've handed out an assignment
                    break;
                } else {
                    // push forward the iterator to check the next assignment
                    assignment++;
                }
            }
            
            ::assignmentQueueMutex.unlock();
        }
        
        if (Logging::shouldSendStats()) {
            if (usecTimestampNow() - usecTimestamp(&lastStatSendTime) >= (NODE_COUNT_STAT_INTERVAL_MSECS * 1000)) {
                // time to send our count of nodes and servers to logstash
                const char NODE_COUNT_LOGSTASH_KEY[] = "ds-node-count";
                
                Logging::stashValue(STAT_TYPE_TIMER, NODE_COUNT_LOGSTASH_KEY, nodeList->getNumAliveNodes());
                
                gettimeofday(&lastStatSendTime, NULL);
            }
        }
    }

    return 0;
}
예제 #26
0
파일: main.cpp 프로젝트: mad-s/shadertoy
int main(int argc, char* argv[]){

	if(argc<=1){
		std::cerr<<"Usage: "<<argv[0]<<" <vertexShader.glsl> [-w <width>] [-h <height>] [-c{0,1,2,3,4} index]\n";
		return 1;
	}


	char* wArg = getCmdOption(argv, argv+argc, "-w");
	if(wArg){
		width = std::atoi(wArg);
	}

	char* hArg = getCmdOption(argv, argv+argc, "-h");
	if(hArg){
		height = std::atoi(hArg);
	}

	char* c0Arg = getCmdOption(argv, argv+argc, "-c0");
	if(c0Arg){
		iChannel0Index=std::atoi(c0Arg);
	}
	char* c1Arg = getCmdOption(argv, argv+argc, "-c1");
	if(c1Arg){
		iChannel1Index=std::atoi(c1Arg);
	}
	char* c2Arg = getCmdOption(argv, argv+argc, "-c2");
	if(c2Arg){
		iChannel2Index=std::atoi(c2Arg);
	}
	char* c3Arg = getCmdOption(argv, argv+argc, "-c3");
	if(c3Arg){
		iChannel3Index=std::atoi(c3Arg);
	}
	



	SDL_Init(SDL_INIT_VIDEO);
	SDL_Window* window;
	SDL_GLContext maincontext;

	SDL_GL_SetAttribute(SDL_GL_ACCELERATED_VISUAL,1);
	SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);

	window = SDL_CreateWindow("Shadertoy", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, width, height, SDL_WINDOW_OPENGL  );

	maincontext = SDL_GL_CreateContext(window);

	glViewport(0,0,width,height);
	
	SDL_GL_SetSwapInterval(1);

	std::cout<<glGetString(GL_VERSION)<<"\n";
	
	std::ifstream shaderInStream(argv[1]);
	std::stringstream buffer;
	buffer << uniforms << shaderInStream.rdbuf()<<mainMethod;
	std::string contents = buffer.str();
	
	GLuint programIndex = compile(contents);
	glUseProgram(programIndex);

	iResolutionLocation = glGetUniformLocation(programIndex, "iResolution");
	iGlobalTimeLocation = glGetUniformLocation(programIndex, "iGlobalTime");
	iMouseLocation = glGetUniformLocation(programIndex, "iMouse");
	iChannel0Location = glGetUniformLocation(programIndex, "iChannel0");
	iChannel1Location = glGetUniformLocation(programIndex, "iChannel1");
	iChannel2Location = glGetUniformLocation(programIndex, "iChannel2");
	iChannel3Location = glGetUniformLocation(programIndex, "iChannel3");
	iChannelResolutionLocation = glGetUniformLocation(programIndex, "iChannelResolution");


	
	loadTextures();
	
	
	setStaticUniforms();
	
	
	unsigned int lastTime=SDL_GetTicks();
	unsigned int deltaCounter=0;
	unsigned int fps=0;
	unsigned int secondCounter=0;

	bool hasQuit=false;
	while(!hasQuit){
		unsigned int now=SDL_GetTicks();
		deltaCounter+=now-lastTime;
		secondCounter+=now-lastTime;
		lastTime=now;

		while(deltaCounter>17){
			deltaCounter-=17;
		}
		
		SDL_Event e;
		while(SDL_PollEvent(&e)){
			switch(e.type){
				case SDL_QUIT:
					hasQuit=true;
					break;
				case SDL_MOUSEBUTTONDOWN:
					mouseXPos=mouseXClick=e.button.x;
					mouseYPos=mouseYClick=e.button.y;
					break;
				case SDL_MOUSEMOTION:
					if(e.motion.state&SDL_BUTTON(1)){
						mouseXPos=e.motion.x;
						mouseYPos=e.motion.y;
					}
					
				

			}
		}
		setDynamicUniforms();
		glRects(-1,-1,1,1);
		SDL_GL_SwapWindow(window);
		fps++;
		if(secondCounter>1000){
			std::cout<<fps<<" FPS\n";
			fps=0;
			secondCounter-=1000;
		}
//		SDL_Delay(10);
	}


	SDL_DestroyWindow(window);
	SDL_Quit();
}
예제 #27
0
int main(int argc, const char * argv[])
{
    VoxelTree myTree;

    qInstallMessageHandler(sharedMessageHandler);
    
    unitTest(&myTree);
    
    
    const char* GET_OCTCODE = "--getOctCode";
    const char* octcodeParams = getCmdOption(argc, argv, GET_OCTCODE);
    if (octcodeParams) {

        QString octcodeParamsString(octcodeParams);
        QStringList octcodeParamsList = octcodeParamsString.split(QString(","));

        enum { X_AT, Y_AT, Z_AT, S_AT, EXPECTED_PARAMS };
        if (octcodeParamsList.size() == EXPECTED_PARAMS) {
            QString xStr = octcodeParamsList.at(X_AT);
            QString yStr = octcodeParamsList.at(Y_AT);
            QString zStr = octcodeParamsList.at(Z_AT);
            QString sStr = octcodeParamsList.at(S_AT);

            float x = xStr.toFloat()/TREE_SCALE; // 0.14745788574219;
            float y = yStr.toFloat()/TREE_SCALE; // 0.01502178955078;
            float z = zStr.toFloat()/TREE_SCALE; // 0.56540045166016;
            float s = sStr.toFloat()/TREE_SCALE; // 0.015625;

            qDebug() << "Get Octal Code for:\n";
            qDebug() << "    x:" << xStr << " [" << x << "] \n";
            qDebug() << "    y:" << yStr << " [" << y << "] \n";
            qDebug() << "    z:" << zStr << " [" << z << "] \n";
            qDebug() << "    s:" << sStr << " [" << s << "] \n";

            unsigned char* octalCode = pointToVoxel(x, y, z, s);
            QString octalCodeStr = octalCodeToHexString(octalCode);
            qDebug() << "octal code: " << octalCodeStr << "\n";

        } else {
            qDebug() << "Unexpected number of parameters for getOctCode\n";
        }
        return 0;
    }
    
    const char* DECODE_OCTCODE = "--decodeOctCode";
    const char* decodeParam = getCmdOption(argc, argv, DECODE_OCTCODE);
    if (decodeParam) {

        QString decodeParamsString(decodeParam);
        unsigned char* octalCodeToDecode = hexStringToOctalCode(decodeParamsString);

        VoxelPositionSize details;
        voxelDetailsForCode(octalCodeToDecode, details);
        
        delete[] octalCodeToDecode;

        qDebug() << "octal code to decode: " << decodeParamsString << "\n";
        qDebug() << "Details for Octal Code:\n";
        qDebug() << "    x:" << details.x << "[" << details.x * TREE_SCALE << "]" << "\n";
        qDebug() << "    y:" << details.y << "[" << details.y * TREE_SCALE << "]" << "\n";
        qDebug() << "    z:" << details.z << "[" << details.z * TREE_SCALE << "]" << "\n";
        qDebug() << "    s:" << details.s << "[" << details.s * TREE_SCALE << "]" << "\n";
        return 0;
    }    
    

    // Handles taking and SVO and splitting it into multiple SVOs based on
    // jurisdiction details
    const char* SPLIT_SVO = "--splitSVO";
    const char* splitSVOFile = getCmdOption(argc, argv, SPLIT_SVO);
    const char* SPLIT_JURISDICTION_ROOT = "--splitJurisdictionRoot";
    const char* SPLIT_JURISDICTION_ENDNODES = "--splitJurisdictionEndNodes";
    const char* splitJurisdictionRoot = getCmdOption(argc, argv, SPLIT_JURISDICTION_ROOT);
    const char* splitJurisdictionEndNodes = getCmdOption(argc, argv, SPLIT_JURISDICTION_ENDNODES);
    if (splitSVOFile && splitJurisdictionRoot && splitJurisdictionEndNodes) {
        processSplitSVOFile(splitSVOFile, splitJurisdictionRoot, splitJurisdictionEndNodes);
        return 0;
    }


    // Handles taking an SVO and filling in the empty space below the voxels to make it solid.
    const char* FILL_SVO = "--fillSVO";
    const char* fillSVOFile = getCmdOption(argc, argv, FILL_SVO);
    if (fillSVOFile) {
        processFillSVOFile(fillSVOFile);
        return 0;
    }
    
    const char* DONT_CREATE_FILE = "--dontCreateSceneFile";
    bool dontCreateFile = cmdOptionExists(argc, argv, DONT_CREATE_FILE);

    if (dontCreateFile) {
        printf("You asked us not to create a scene file, so we will not.\n");
    } else {
        printf("Creating Scene File...\n");
    
        const char* RUN_TUTORIAL = "--runTutorial";
        if (cmdOptionExists(argc, argv, RUN_TUTORIAL)) {
            voxelTutorial(&myTree);
        }

        const char* ADD_CORNERS_AND_AXIS_LINES = "--addCornersAndAxisLines";
        if (cmdOptionExists(argc, argv, ADD_CORNERS_AND_AXIS_LINES)) {
            addCornersAndAxisLines(&myTree);
        }

        const char* ADD_SPHERE_SCENE = "--addSphereScene";
        if (cmdOptionExists(argc, argv, ADD_SPHERE_SCENE)) {
            addSphereScene(&myTree);
        }

        const char* ADD_SURFACE_SCENE = "--addSurfaceScene";
        if (cmdOptionExists(argc, argv, ADD_SURFACE_SCENE)) {
            addSurfaceScene(&myTree);
        }

        unsigned long nodeCount = myTree.getOctreeElementsCount();
        printf("Nodes after adding scenes: %ld nodes\n", nodeCount);

        myTree.writeToSVOFile("voxels.svo");
    }
    return 0;
}
예제 #28
0
AssignmentClient::AssignmentClient(int &argc, char **argv) :
    QCoreApplication(argc, argv),
    _currentAssignment(NULL)
{
    // register meta type is required for queued invoke method on Assignment subclasses
    
    // set the logging target to the the CHILD_TARGET_NAME
    Logging::setTargetName(ASSIGNMENT_CLIENT_TARGET_NAME);
    
    const char ASSIGNMENT_TYPE_OVVERIDE_OPTION[] = "-t";
    const char* assignmentTypeString = getCmdOption(argc, (const char**)argv, ASSIGNMENT_TYPE_OVVERIDE_OPTION);
    
    Assignment::Type requestAssignmentType = Assignment::AllTypes;
    
    if (assignmentTypeString) {
        // the user is asking to only be assigned to a particular type of assignment
        // so set that as the ::overridenAssignmentType to be used in requests
        requestAssignmentType = (Assignment::Type) atoi(assignmentTypeString);
    }
    
    const char ASSIGNMENT_POOL_OPTION[] = "--pool";
    const char* requestAssignmentPool = getCmdOption(argc, (const char**) argv, ASSIGNMENT_POOL_OPTION);
    
    
    // setup our _requestAssignment member variable from the passed arguments
    _requestAssignment = Assignment(Assignment::RequestCommand, requestAssignmentType, requestAssignmentPool);
    
    // create a NodeList as an unassigned client
    NodeList* nodeList = NodeList::createInstance(NodeType::Unassigned);
    
    const char CUSTOM_ASSIGNMENT_SERVER_HOSTNAME_OPTION[] = "-a";
    const char CUSTOM_ASSIGNMENT_SERVER_PORT_OPTION[] = "-p";
    
    // grab the overriden assignment-server hostname from argv, if it exists
    const char* customAssignmentServerHostname = getCmdOption(argc, (const char**)argv, CUSTOM_ASSIGNMENT_SERVER_HOSTNAME_OPTION);
    const char* customAssignmentServerPortString = getCmdOption(argc,(const char**)argv, CUSTOM_ASSIGNMENT_SERVER_PORT_OPTION);
    
    HifiSockAddr customAssignmentSocket;
    
    if (customAssignmentServerHostname || customAssignmentServerPortString) {
        
        // set the custom port or default if it wasn't passed
        unsigned short assignmentServerPort = customAssignmentServerPortString
        ? atoi(customAssignmentServerPortString) : DEFAULT_DOMAIN_SERVER_PORT;
        
        // set the custom hostname or default if it wasn't passed
        if (!customAssignmentServerHostname) {
            customAssignmentServerHostname = DEFAULT_ASSIGNMENT_SERVER_HOSTNAME;
        }
        
        customAssignmentSocket = HifiSockAddr(customAssignmentServerHostname, assignmentServerPort);
    }
    
    // set the custom assignment socket if we have it
    if (!customAssignmentSocket.isNull()) {
        nodeList->setAssignmentServerSocket(customAssignmentSocket);
    }
    
    // call a timer function every ASSIGNMENT_REQUEST_INTERVAL_MSECS to ask for assignment, if required
    qDebug() << "Waiting for assignment -" << _requestAssignment;
    
    QTimer* timer = new QTimer(this);
    connect(timer, SIGNAL(timeout()), SLOT(sendAssignmentRequest()));
    timer->start(ASSIGNMENT_REQUEST_INTERVAL_MSECS);
    
    // connect our readPendingDatagrams method to the readyRead() signal of the socket
    connect(&nodeList->getNodeSocket(), &QUdpSocket::readyRead, this, &AssignmentClient::readPendingDatagrams,
            Qt::QueuedConnection);
}
예제 #29
0
파일: main.cpp 프로젝트: AaronHillaker/hifi
int main(int argc, const char* argv[]) {
    disableQtBearerPoll(); // Fixes wifi ping spikes
    
    QString applicationName = "High Fidelity Interface - " + qgetenv("USERNAME");

    bool instanceMightBeRunning = true;

#ifdef Q_OS_WIN
    // Try to create a shared memory block - if it can't be created, there is an instance of
    // interface already running. We only do this on Windows for now because of the potential
    // for crashed instances to leave behind shared memory instances on unix.
    QSharedMemory sharedMemory { applicationName };
    instanceMightBeRunning = !sharedMemory.create(1, QSharedMemory::ReadOnly);
#endif

    if (instanceMightBeRunning) {
        // Try to connect and send message to existing interface instance
        QLocalSocket socket;

        socket.connectToServer(applicationName);

        static const int LOCAL_SERVER_TIMEOUT_MS = 500;

        // Try to connect - if we can't connect, interface has probably just gone down
        if (socket.waitForConnected(LOCAL_SERVER_TIMEOUT_MS)) {

            QStringList arguments;
            for (int i = 0; i < argc; ++i) {
                arguments << argv[i];
            }

            QCommandLineParser parser;
            QCommandLineOption urlOption("url", "", "value");
            parser.addOption(urlOption);
            parser.process(arguments);

            if (parser.isSet(urlOption)) {
                QUrl url = QUrl(parser.value(urlOption));
                if (url.isValid() && url.scheme() == HIFI_URL_SCHEME) {
                    qDebug() << "Writing URL to local socket";
                    socket.write(url.toString().toUtf8());
                    if (!socket.waitForBytesWritten(5000)) {
                        qDebug() << "Error writing URL to local socket";
                    }
                }
            }

            socket.close();

            qDebug() << "Interface instance appears to be running, exiting";

            return EXIT_SUCCESS;
        }

#ifdef Q_OS_WIN
        return EXIT_SUCCESS;
#endif
    }

    // Check OpenGL version.
    // This is done separately from the main Application so that start-up and shut-down logic within the main Application is
    // not made more complicated than it already is.
    {
        OpenGLVersionChecker openGLVersionChecker(argc, const_cast<char**>(argv));
        if (!openGLVersionChecker.isValidVersion()) {
            qCDebug(interfaceapp, "Early exit due to OpenGL version.");
            return 0;
        }
    }

    QElapsedTimer startupTime;
    startupTime.start();

    // Debug option to demonstrate that the client's local time does not
    // need to be in sync with any other network node. This forces clock
    // skew for the individual client
    const char* CLOCK_SKEW = "--clockSkew";
    const char* clockSkewOption = getCmdOption(argc, argv, CLOCK_SKEW);
    if (clockSkewOption) {
        int clockSkew = atoi(clockSkewOption);
        usecTimestampNowForceClockSkew(clockSkew);
        qCDebug(interfaceapp, "clockSkewOption=%s clockSkew=%d", clockSkewOption, clockSkew);
    }

    // Oculus initialization MUST PRECEDE OpenGL context creation.
    // The nature of the Application constructor means this has to be either here,
    // or in the main window ctor, before GL startup.
    Application::initPlugins();

    int exitCode;
    {
        QSettings::setDefaultFormat(QSettings::IniFormat);
        Application app(argc, const_cast<char**>(argv), startupTime);

        // Setup local server
        QLocalServer server { &app };

        // We failed to connect to a local server, so we remove any existing servers.
        server.removeServer(applicationName);
        server.listen(applicationName);

        QObject::connect(&server, &QLocalServer::newConnection, &app, &Application::handleLocalServerConnection);

        QTranslator translator;
        translator.load("i18n/interface_en");
        app.installTranslator(&translator);

        qCDebug(interfaceapp, "Created QT Application.");
        exitCode = app.exec();
        server.close();
    }

    Application::shutdownPlugins();

    qCDebug(interfaceapp, "Normal exit.");
    return exitCode;
}
예제 #30
0
//int main(int argc, const char * argv[]) {
void VoxelServer::run() {
    
    const char VOXEL_SERVER_LOGGING_TARGET_NAME[] = "voxel-server";
    
    // change the logging target name while this is running
    Logging::setTargetName(VOXEL_SERVER_LOGGING_TARGET_NAME);

    // Now would be a good time to parse our arguments, if we got them as assignment
    if (getNumPayloadBytes() > 0) {
        parsePayload();
    }

    pthread_mutex_init(&_treeLock, NULL);
    
    qInstallMessageHandler(Logging::verboseMessageHandler);
    
    const char* JURISDICTION_FILE = "--jurisdictionFile";
    const char* jurisdictionFile = getCmdOption(_argc, _argv, JURISDICTION_FILE);
    if (jurisdictionFile) {
        qDebug("jurisdictionFile=%s\n", jurisdictionFile);

        qDebug("about to readFromFile().... jurisdictionFile=%s\n", jurisdictionFile);
        _jurisdiction = new JurisdictionMap(jurisdictionFile);
        qDebug("after readFromFile().... jurisdictionFile=%s\n", jurisdictionFile);
    } else {
        const char* JURISDICTION_ROOT = "--jurisdictionRoot";
        const char* jurisdictionRoot = getCmdOption(_argc, _argv, JURISDICTION_ROOT);
        if (jurisdictionRoot) {
            qDebug("jurisdictionRoot=%s\n", jurisdictionRoot);
        }

        const char* JURISDICTION_ENDNODES = "--jurisdictionEndNodes";
        const char* jurisdictionEndNodes = getCmdOption(_argc, _argv, JURISDICTION_ENDNODES);
        if (jurisdictionEndNodes) {
            qDebug("jurisdictionEndNodes=%s\n", jurisdictionEndNodes);
        }

        if (jurisdictionRoot || jurisdictionEndNodes) {
            _jurisdiction = new JurisdictionMap(jurisdictionRoot, jurisdictionEndNodes);
        }
    }

    // should we send environments? Default is yes, but this command line suppresses sending
    const char* DUMP_VOXELS_ON_MOVE = "--dumpVoxelsOnMove";
    _dumpVoxelsOnMove = cmdOptionExists(_argc, _argv, DUMP_VOXELS_ON_MOVE);
    qDebug("dumpVoxelsOnMove=%s\n", debug::valueOf(_dumpVoxelsOnMove));
    
    // should we send environments? Default is yes, but this command line suppresses sending
    const char* DONT_SEND_ENVIRONMENTS = "--dontSendEnvironments";
    bool dontSendEnvironments =  getCmdOption(_argc, _argv, DONT_SEND_ENVIRONMENTS);
    if (dontSendEnvironments) {
        qDebug("Sending environments suppressed...\n");
        _sendEnvironments = false;
    } else { 
        // should we send environments? Default is yes, but this command line suppresses sending
        const char* MINIMAL_ENVIRONMENT = "--MinimalEnvironment";
        _sendMinimalEnvironment =  getCmdOption(_argc, _argv, MINIMAL_ENVIRONMENT);
        qDebug("Using Minimal Environment=%s\n", debug::valueOf(_sendMinimalEnvironment));
    }
    qDebug("Sending environments=%s\n", debug::valueOf(_sendEnvironments));
    
    NodeList* nodeList = NodeList::getInstance();
    nodeList->setOwnerType(NODE_TYPE_VOXEL_SERVER);
    
    setvbuf(stdout, NULL, _IOLBF, 0);

    // tell our NodeList about our desire to get notifications
    nodeList->addHook(&_nodeWatcher);
    nodeList->linkedDataCreateCallback = &attachVoxelNodeDataToNode;

    nodeList->startSilentNodeRemovalThread();
    srand((unsigned)time(0));
    
    const char* DISPLAY_VOXEL_STATS = "--displayVoxelStats";
    _displayVoxelStats =  getCmdOption(_argc, _argv, DISPLAY_VOXEL_STATS);
    qDebug("displayVoxelStats=%s\n", debug::valueOf(_displayVoxelStats));

    const char* DEBUG_VOXEL_SENDING = "--debugVoxelSending";
    _debugVoxelSending =  getCmdOption(_argc, _argv, DEBUG_VOXEL_SENDING);
    qDebug("debugVoxelSending=%s\n", debug::valueOf(_debugVoxelSending));

    const char* DEBUG_VOXEL_RECEIVING = "--debugVoxelReceiving";
    _debugVoxelReceiving =  getCmdOption(_argc, _argv, DEBUG_VOXEL_RECEIVING);
    qDebug("debugVoxelReceiving=%s\n", debug::valueOf(_debugVoxelReceiving));

    const char* WANT_ANIMATION_DEBUG = "--shouldShowAnimationDebug";
    _shouldShowAnimationDebug =  getCmdOption(_argc, _argv, WANT_ANIMATION_DEBUG);
    qDebug("shouldShowAnimationDebug=%s\n", debug::valueOf(_shouldShowAnimationDebug));

    // By default we will voxel persist, if you want to disable this, then pass in this parameter
    const char* NO_VOXEL_PERSIST = "--NoVoxelPersist";
    if (getCmdOption(_argc, _argv, NO_VOXEL_PERSIST)) {
        _wantVoxelPersist = false;
    }
    qDebug("wantVoxelPersist=%s\n", debug::valueOf(_wantVoxelPersist));

    // if we want Voxel Persistence, load the local file now...
    bool persistantFileRead = false;
    if (_wantVoxelPersist) {

        // Check to see if the user passed in a command line option for setting packet send rate
        const char* VOXELS_PERSIST_FILENAME = "--voxelsPersistFilename";
        const char* voxelsPersistFilenameParameter = getCmdOption(_argc, _argv, VOXELS_PERSIST_FILENAME);
        if (voxelsPersistFilenameParameter) {
            strcpy(_voxelPersistFilename, voxelsPersistFilenameParameter);
        } else {
            //strcpy(voxelPersistFilename, _wantLocalDomain ? LOCAL_VOXELS_PERSIST_FILE : VOXELS_PERSIST_FILE);
            strcpy(_voxelPersistFilename, LOCAL_VOXELS_PERSIST_FILE);
        }

        qDebug("loading voxels from file: %s...\n", _voxelPersistFilename);

        persistantFileRead = _serverTree.readFromSVOFile(_voxelPersistFilename);
        if (persistantFileRead) {
            PerformanceWarning warn(_shouldShowAnimationDebug,
                                    "persistVoxelsWhenDirty() - reaverageVoxelColors()", _shouldShowAnimationDebug);
            
            // after done inserting all these voxels, then reaverage colors
            _serverTree.reaverageVoxelColors(_serverTree.rootNode);
            qDebug("Voxels reAveraged\n");
        }
        
        _serverTree.clearDirtyBit(); // the tree is clean since we just loaded it
        qDebug("DONE loading voxels from file... fileRead=%s\n", debug::valueOf(persistantFileRead));
        unsigned long nodeCount         = _serverTree.rootNode->getSubTreeNodeCount();
        unsigned long internalNodeCount = _serverTree.rootNode->getSubTreeInternalNodeCount();
        unsigned long leafNodeCount     = _serverTree.rootNode->getSubTreeLeafNodeCount();
        qDebug("Nodes after loading scene %lu nodes %lu internal %lu leaves\n", nodeCount, internalNodeCount, leafNodeCount);
        
        // now set up VoxelPersistThread
        _voxelPersistThread = new VoxelPersistThread(&_serverTree, _voxelPersistFilename);
        if (_voxelPersistThread) {
            _voxelPersistThread->initialize(true);
        }
    }

    // Check to see if the user passed in a command line option for loading an old style local
    // Voxel File. If so, load it now. This is not the same as a voxel persist file
    const char* INPUT_FILE = "-i";
    const char* voxelsFilename = getCmdOption(_argc, _argv, INPUT_FILE);
    if (voxelsFilename) {
        _serverTree.readFromSVOFile(voxelsFilename);
    }

    // Check to see if the user passed in a command line option for setting packet send rate
    const char* PACKETS_PER_SECOND = "--packetsPerSecond";
    const char* packetsPerSecond = getCmdOption(_argc, _argv, PACKETS_PER_SECOND);
    if (packetsPerSecond) {
        _packetsPerClientPerInterval = atoi(packetsPerSecond) / INTERVALS_PER_SECOND;
        if (_packetsPerClientPerInterval < 1) {
            _packetsPerClientPerInterval = 1;
        }
        qDebug("packetsPerSecond=%s PACKETS_PER_CLIENT_PER_INTERVAL=%d\n", packetsPerSecond, _packetsPerClientPerInterval);
    }
    
    // for now, initialize the environments with fixed values
    _environmentData[1].setID(1);
    _environmentData[1].setGravity(1.0f);
    _environmentData[1].setAtmosphereCenter(glm::vec3(0.5, 0.5, (0.25 - 0.06125)) * (float)TREE_SCALE);
    _environmentData[1].setAtmosphereInnerRadius(0.030625f * TREE_SCALE);
    _environmentData[1].setAtmosphereOuterRadius(0.030625f * TREE_SCALE * 1.05f);
    _environmentData[2].setID(2);
    _environmentData[2].setGravity(1.0f);
    _environmentData[2].setAtmosphereCenter(glm::vec3(0.5f, 0.5f, 0.5f) * (float)TREE_SCALE);
    _environmentData[2].setAtmosphereInnerRadius(0.1875f * TREE_SCALE);
    _environmentData[2].setAtmosphereOuterRadius(0.1875f * TREE_SCALE * 1.05f);
    _environmentData[2].setScatteringWavelengths(glm::vec3(0.475f, 0.570f, 0.650f)); // swaps red and blue

    sockaddr senderAddress;
    
    unsigned char* packetData = new unsigned char[MAX_PACKET_SIZE];
    ssize_t packetLength;
    
    timeval lastDomainServerCheckIn = {};

    // set up our jurisdiction broadcaster...
    _jurisdictionSender = new JurisdictionSender(_jurisdiction);
    if (_jurisdictionSender) {
        _jurisdictionSender->initialize(true);
    }
    
    // set up our VoxelServerPacketProcessor
    _voxelServerPacketProcessor = new VoxelServerPacketProcessor(this);
    if (_voxelServerPacketProcessor) {
        _voxelServerPacketProcessor->initialize(true);
    }
    
    // loop to send to nodes requesting data
    while (true) {
    
        if (NodeList::getInstance()->getNumNoReplyDomainCheckIns() == MAX_SILENT_DOMAIN_SERVER_CHECK_INS) {
            break;
        }
        
        // send a check in packet to the domain server if DOMAIN_SERVER_CHECK_IN_USECS has elapsed
        if (usecTimestampNow() - usecTimestamp(&lastDomainServerCheckIn) >= DOMAIN_SERVER_CHECK_IN_USECS) {
            gettimeofday(&lastDomainServerCheckIn, NULL);
            NodeList::getInstance()->sendDomainServerCheckIn(_uuid.toRfc4122().constData());
        }
        
        if (nodeList->getNodeSocket()->receive(&senderAddress, packetData, &packetLength) &&
            packetVersionMatch(packetData)) {

            int numBytesPacketHeader = numBytesForPacketHeader(packetData);

            if (packetData[0] == PACKET_TYPE_HEAD_DATA) {
                // If we got a PACKET_TYPE_HEAD_DATA, then we're talking to an NODE_TYPE_AVATAR, and we
                // need to make sure we have it in our nodeList.
                uint16_t nodeID = 0;
                unpackNodeId(packetData + numBytesPacketHeader, &nodeID);
                Node* node = NodeList::getInstance()->addOrUpdateNode(&senderAddress,
                                                       &senderAddress,
                                                       NODE_TYPE_AGENT,
                                                       nodeID);

                NodeList::getInstance()->updateNodeWithData(node, packetData, packetLength);
                
                VoxelNodeData* nodeData = (VoxelNodeData*) node->getLinkedData();
                if (nodeData && !nodeData->isVoxelSendThreadInitalized()) {
                    nodeData->initializeVoxelSendThread(this);
                }
                
            } else if (packetData[0] == PACKET_TYPE_PING) {
                // If the packet is a ping, let processNodeData handle it.
                NodeList::getInstance()->processNodeData(&senderAddress, packetData, packetLength);
            } else if (packetData[0] == PACKET_TYPE_DOMAIN) {
                NodeList::getInstance()->processNodeData(&senderAddress, packetData, packetLength);
            } else if (packetData[0] == PACKET_TYPE_VOXEL_JURISDICTION_REQUEST) {
                if (_jurisdictionSender) {
                    _jurisdictionSender->queueReceivedPacket(senderAddress, packetData, packetLength);
                }
            } else if (_voxelServerPacketProcessor) {
                _voxelServerPacketProcessor->queueReceivedPacket(senderAddress, packetData, packetLength);
            } else {
                qDebug("unknown packet ignored... packetData[0]=%c\n", packetData[0]);
            }
        }
    }
    
    delete _jurisdiction;
    
    if (_jurisdictionSender) {
        _jurisdictionSender->terminate();
        delete _jurisdictionSender;
    }

    if (_voxelServerPacketProcessor) {
        _voxelServerPacketProcessor->terminate();
        delete _voxelServerPacketProcessor;
    }

    if (_voxelPersistThread) {
        _voxelPersistThread->terminate();
        delete _voxelPersistThread;
    }
    
    // tell our NodeList we're done with notifications
    nodeList->removeHook(&_nodeWatcher);
    
    pthread_mutex_destroy(&_treeLock);
}