当前位置: 首页>>代码示例>>C++>>正文


C++ Timing类代码示例

本文整理汇总了C++中Timing的典型用法代码示例。如果您正苦于以下问题:C++ Timing类的具体用法?C++ Timing怎么用?C++ Timing使用的例子?那么恭喜您, 这里精选的类代码示例或许可以为您提供帮助。


在下文中一共展示了Timing类的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。

示例1: ovr_GetTimeInSeconds

FrameTimeManager::Timing FrameTimeManager::GetFrameTiming(unsigned frameIndex)
{
    Timing frameTiming = LocklessTiming.GetState();

    if (frameTiming.ThisFrameTime != 0.0)
    {
        // If timing hasn't been initialized, starting based on "now" is the best guess.
        frameTiming.InitTimingFromInputs(frameTiming.Inputs, RenderInfo.Shutter.Type,
                                         ovr_GetTimeInSeconds(), frameIndex);
    }
    
    else if (frameIndex > frameTiming.FrameIndex)
    {
        unsigned frameDelta    = frameIndex - frameTiming.FrameIndex;
        double   thisFrameTime = frameTiming.NextFrameTime +
                                 double(frameDelta-1) * frameTiming.Inputs.FrameDelta;
        // Don't run away too far into the future beyond rendering.
        OVR_ASSERT(frameDelta < 6);

        frameTiming.InitTimingFromInputs(frameTiming.Inputs, RenderInfo.Shutter.Type,
                                         thisFrameTime, frameIndex);
    }    
     
    return frameTiming;
}
开发者ID:imclab,项目名称:max_oculus,代码行数:25,代码来源:CAPI_FrameTimeManager.cpp

示例2: arch_dump_summary

void arch_dump_summary(struct arch_t *arch, FILE *f)
{
	Emu *emu = arch->emu;
	Timing *timing = arch->timing;

	/* If no instruction was run for this architecture, skip
	 * statistics summary. */
	if (!emu->instructions)
		return;

	/* Architecture-specific emulation statistics */
	assert(emu->DumpSummary);
	emu->DumpSummary(emu, f);

	/* Timing simulation statistics */
	if (arch->sim_kind == arch_sim_kind_detailed)
	{
		/* Architecture-specific */
		assert(timing->DumpSummary);
		timing->DumpSummary(timing, f);
	}

	/* End */
	fprintf(f, "\n");
}
开发者ID:3upperm2n,项目名称:gpuSimulators,代码行数:25,代码来源:arch.c

示例3: arch_run

void arch_run(int *num_emu_active_ptr, int *num_timing_active_ptr) {
  struct arch_t *arch;
  long long cycle;

  int run;
  int i;

  Emu *emu;
  Timing *timing;

  /* Reset active emulation and timing simulation counters */
  *num_emu_active_ptr = 0;
  *num_timing_active_ptr = 0;

  /* Run one iteration for all architectures */
  for (i = 0; i < arch_list_count; i++) {
    /* Get architecture */
    arch = arch_list[i];
    if (arch->sim_kind == arch_sim_kind_functional) {
      /* Emulation iteration */
      emu = arch->emu;
      assert(emu && emu->Run);
      arch->active = emu->Run(emu);

      /* Increase number of active emulations if the architecture
       * actually performed a useful emulation iteration. */
      *num_emu_active_ptr += arch->active;
    } else {
      /* Check whether the architecture should actually run an
       * iteration. If it is working at a slower frequency than
       * the main simulation loop, we must skip this call. */
      timing = arch->timing;
      assert(timing);
      assert(timing->frequency_domain);
      cycle = esim_domain_cycle(timing->frequency_domain);
      run = cycle != arch->last_timing_cycle;

      /* Timing simulation iteration */
      if (run) {
        /* Do it... */
        arch->active = timing->Run(timing);

        /* ... but only update the last timing
         * simulation cycle if there was an effective
         * execution of the iteration loop. Otherwise,
         * there is a deadlock: 'esim_time' will not
         * advance (no call to 'esim_process_events')
         * because no architecture ran, and no
         * architecture will run because 'esim_time'
         * did not advance. */
        if (arch->active) arch->last_timing_cycle = cycle;
      }

      /* Increase number of active timing simulations if the
       * architecture actually performance a useful iteration. */
      *num_timing_active_ptr += arch->active;
    }
  }
}
开发者ID:xianggong,项目名称:multi2sim42,代码行数:59,代码来源:arch.c

示例4: WriteDataBin

// TODO: we might want to use multiple buffers at the same time
void Measurement::WriteDataBin(FILE *f, int channel)
{
	Timing t;
	long size_written;
	int i, j;

	const unsigned int length_datachunk = 1000000;
	char data_8bit[1000000];
	// std::vector<char>data_8bit(1000);

	std::cerr << "Write binary data for channel " << (char)('A'+channel) << " ... ";
	t.Start();
	// TODO: test if file exists
	if(channel < 0 || channel >= GetNumberOfChannels()) {
		throw "You can only write data for channels 0 - (N-1).";
	} else {
		if(GetChannel(channel)->IsEnabled()) {

			/*
			size_written = fwrite(data[channel], sizeof(short), GetLengthFetched(), f);
			// make sure the data is written
			fflush(f);
			if(size_written < GetLengthFetched()) {
				FILE_LOG(logERROR) << "Measurement::WriteDataBin didn't manage to write to file.";
			}*/
			// TODO: if only 8 bits
			int length_fetched   = GetLengthFetched();
			// int length_datachunk = data_8bit.size();
			for(i=0; i<length_fetched; i+=length_datachunk) {
				if(GetSeries() == PICO_6000) {
					for(j=0; j<length_datachunk && i+j<length_fetched; j++) {
						data_8bit[j] = data[channel][i+j] >> 8;
					}
					size_written = fwrite(data_8bit, sizeof(char), j, f);
				} else {
					// TODO: test!!!
					size_written = fwrite(data[channel]+1, sizeof(data[0][0]), j, f);
				}
				fflush(f);
				if(size_written < j) {
					FILE_LOG(logERROR) << "Measurement::WriteDataBin didn't manage to write to file.";
				}
			}
			// size_written = fwrite(data[channel], sizeof(short), GetLengthFetched(), f);
			// make sure the data is written
			// fflush(f);
			// if(size_written < GetLengthFetched()) {
			// 	FILE_LOG(logERROR) << "Measurement::WriteDataBin didn't manage to write to file.";
			// }
		} else {
开发者ID:enascimento,项目名称:picoscope,代码行数:51,代码来源:measurement.cpp

示例5: setStartDelay

Timing TimingInput::convert(const Dictionary& timingInputDictionary)
{
    Timing result;

    // FIXME: This method needs to be refactored to handle invalid
    // null, NaN, Infinity values better.
    // See: http://www.w3.org/TR/WebIDL/#es-double
    double startDelay = Timing::defaults().startDelay;
    timingInputDictionary.get("delay", startDelay);
    setStartDelay(result, startDelay);

    double endDelay = Timing::defaults().endDelay;
    timingInputDictionary.get("endDelay", endDelay);
    setEndDelay(result, endDelay);

    String fillMode;
    timingInputDictionary.get("fill", fillMode);
    setFillMode(result, fillMode);

    double iterationStart = Timing::defaults().iterationStart;
    timingInputDictionary.get("iterationStart", iterationStart);
    setIterationStart(result, iterationStart);

    double iterationCount = Timing::defaults().iterationCount;
    timingInputDictionary.get("iterations", iterationCount);
    setIterationCount(result, iterationCount);

    double iterationDuration = 0;
    if (timingInputDictionary.get("duration", iterationDuration)) {
        setIterationDuration(result, iterationDuration);
    }

    double playbackRate = Timing::defaults().playbackRate;
    timingInputDictionary.get("playbackRate", playbackRate);
    setPlaybackRate(result, playbackRate);

    String direction;
    timingInputDictionary.get("direction", direction);
    setPlaybackDirection(result, direction);

    String timingFunctionString;
    timingInputDictionary.get("easing", timingFunctionString);
    setTimingFunction(result, timingFunctionString);

    result.assertValid();

    return result;
}
开发者ID:Drakey83,项目名称:steamlink-sdk,代码行数:48,代码来源:TimingInput.cpp

示例6: convertTimingForCompositor

bool CompositorAnimationsImpl::convertTimingForCompositor(const Timing& timing, double timeOffset, CompositorTiming& out, double playerPlaybackRate)
{
    timing.assertValid();

    // FIXME: Compositor does not know anything about endDelay.
    if (timing.endDelay != 0)
        return false;

    if (std::isnan(timing.iterationDuration) || !timing.iterationCount || !timing.iterationDuration)
        return false;

    if (!std::isfinite(timing.iterationCount)) {
        out.adjustedIterationCount = -1;
    } else {
        out.adjustedIterationCount = timing.iterationCount;
    }

    out.scaledDuration = timing.iterationDuration;
    out.direction = timing.direction;
    // Compositor's time offset is positive for seeking into the animation.
    out.scaledTimeOffset = -timing.startDelay / playerPlaybackRate + timeOffset;
    out.playbackRate = timing.playbackRate * playerPlaybackRate;
    out.fillMode = timing.fillMode == Timing::FillModeAuto ? Timing::FillModeNone : timing.fillMode;
    out.iterationStart = timing.iterationStart;
    out.assertValid();
    return true;
}
开发者ID:kingysu,项目名称:blink-crosswalk,代码行数:27,代码来源:CompositorAnimations.cpp

示例7: arch_dump

void arch_dump(struct arch_t *arch, FILE *f)
{
	double time_in_sec;
	int i;

	Emu *emu;
	Timing *timing;

	/* Get objects */
	emu = arch->emu;
	timing = arch->timing;

	/* Nothing to print if architecture was not active */
	if (!emu->instructions)
		return;

	/* Header */
	for (i = 0; i < 80; i++)
		fprintf(f, "=");
	fprintf(f, "\nArchitecture '%s'\n", arch->name);
	for (i = 0; i < 80; i++)
		fprintf(f, "=");
	fprintf(f, "\n\n");

	/* Emulator */
	time_in_sec = (double) m2s_timer_get_value(emu->timer) / 1.0e6;
	fprintf(f, "SimKind = %s\n", str_map_value(&arch_sim_kind_map, arch->sim_kind));
	fprintf(f, "Time = %.2f\n", time_in_sec);
	fprintf(f, "Instructions = %lld\n", emu->instructions);
	fprintf(f, "\n");
	assert(emu->DumpSummary);
	emu->DumpSummary(emu, f);

	/* Continue with timing simulator only it active */
	if (arch->sim_kind == arch_sim_kind_functional)
		return;

	/* Timing simulator */
	fprintf(f, "Cycles = %lld\n", timing->cycle);
	fprintf(f, "\n");
	assert(timing->DumpSummary);
	timing->DumpSummary(timing, f);
}
开发者ID:3upperm2n,项目名称:gpuSimulators,代码行数:43,代码来源:arch.c

示例8: setInputMatrixToAlgebraDefault

void setInputMatrixToAlgebraDefault(float_tt* dst, size_t numVal) {
    Timing timer;
    memset(dst, 0, sizeof(float_tt) * numVal); // empty cells are implicit zeros for sparse matrices

    enum dummy {DBG_DENSE_ALGEBRA_WITH_NAN_FILL=0};  // won't be correct if empty cells present
    if(DBG_DENSE_ALGEBRA_WITH_NAN_FILL) {
        valsSet(dst, ::nan(""), numVal); // any non-signalling nan will do
        LOG4CXX_WARN(SCALAPACKPHYSICAL_HPP_logger, "@@@@@@@@@@@@@ WARNING: prefill matrix memory with NaN for debug");
    }
    LOG4CXX_DEBUG(SCALAPACKPHYSICAL_HPP_logger, "setInputMatrixToAlgebraDefault took " << timer.stop());
}
开发者ID:Goon83,项目名称:scidb,代码行数:11,代码来源:ScaLAPACKPhysical.hpp

示例9: SolveTheBGIP

void
SolveTheBGIP(BGIP_sharedPtr bgip)
{
    // Specify the solution method.
    // (See above and in BGIP_SolverType.h)
    BGIP_SolverType::BGIP_Solver_t method = BGIP_SolverType::AM;
    try {
        Timing timer;
        timer.Start( SoftPrint(method) );
        BayesianGameIdenticalPayoffSolver * bgip_solver = NewBGIPSolver(bgip, method);
        cout << "running " <<  SoftPrint(method) << "..."<<endl;
        cout << "...value is " << bgip_solver->Solve() << endl;
        timer.Stop(  SoftPrint(method) );
        delete bgip_solver;
    }
    catch(E& e)
    {
        e.Print();
    }
}
开发者ID:heckj,项目名称:MADP,代码行数:20,代码来源:example_RandomBGs.cpp

示例10: ASSERT

bool CompositorAnimationsImpl::convertTimingForCompositor(const Timing& timing, CompositorTiming& out)
{
    timing.assertValid();

    // All fill modes are supported (the calling code handles them).

    // FIXME: Support non-zero iteration start.
    if (timing.iterationStart)
        return false;

    // FIXME: Compositor only supports positive, integer iteration counts.
    // Zero iterations could be converted, but silly.
    if ((std::floor(timing.iterationCount) != timing.iterationCount) || timing.iterationCount <= 0)
        return false;

    if (std::isnan(timing.iterationDuration) || !timing.iterationDuration)
        return false;

    // FIXME: Support other playback rates
    if (timing.playbackRate != 1)
        return false;

    // All directions are supported.

    // Now attempt an actual conversion
    out.scaledDuration = timing.iterationDuration;
    ASSERT(out.scaledDuration > 0);

    double scaledStartDelay = timing.startDelay;
    if (scaledStartDelay > 0 && scaledStartDelay > out.scaledDuration * timing.iterationCount)
        return false;

    out.reverse = (timing.direction == Timing::PlaybackDirectionReverse
        || timing.direction == Timing::PlaybackDirectionAlternateReverse);
    out.alternate = (timing.direction == Timing::PlaybackDirectionAlternate
        || timing.direction == Timing::PlaybackDirectionAlternateReverse);

    if (!std::isfinite(timing.iterationCount)) {
        out.adjustedIterationCount = -1;
    } else {
        out.adjustedIterationCount = std::floor(timing.iterationCount);
        ASSERT(out.adjustedIterationCount > 0);
    }

    // Compositor's time offset is positive for seeking into the animation.
    out.scaledTimeOffset = -scaledStartDelay;
    return true;
}
开发者ID:wangshijun,项目名称:Blink,代码行数:48,代码来源:CompositorAnimations.cpp

示例11: main

int main(){
    Timing timer;
#ifdef _DEBUG
    int size = 4;{
#else
    for(int size=1; size>0; size*=2){
#endif
    
        std::cout << "size: " << size << '\n';
        const int times = 10;
        Matrix a, b;
        a.resize(size);
        b.resize(size);
        a.randomize();
        b.randomize();

    
        timer.setDivisor(times);
    
   

        timer.start();
        for(int i=0; i<times; i++){
            Matrix c = MatrixMultiplication::recursive(a, b);
#ifdef _DEBUG
            c.print();
#endif
        }
        timer.end();
        timer.reportCPUtime();


        timer.start();
        for(int i=0; i<times; i++){
            Matrix c = MatrixMultiplication::strassen(a, b);
#ifdef _DEBUG
            c.print();
#endif
        }
        timer.end();
        timer.reportCPUtime();
    }

    return system("pause");
}
开发者ID:lizy14,项目名称:algorithm-assignments,代码行数:45,代码来源:Source.cpp

示例12: main

int main()
{
	/******************************* [ signal ] ******************************/
	Type a = 0;
	Type b = Ls-1;
	Vector<Type> t = linspace(a,b,Ls) / Type(Fs);
	Vector<Type> s = sin( Type(400*PI) * pow(t,Type(2.0)) );

	/******************************** [ widow ] ******************************/
	a = 0;
	b = Type(Lg-1);
	Type u = (Lg-1)/Type(2);
	Type r = Lg/Type(8);
	t = linspace(a,b,Lg);
	Vector<Type> g = gauss(t,u,r);
	g = g/norm(g);

	/********************************* [ WFT ] *******************************/
	Type runtime = 0;
	Timing cnt;
	cout << "Taking windowed Fourier transform." << endl;
	cnt.start();
    Matrix< complex<Type> > coefs = wft( s, g );
	cnt.stop();
	runtime = cnt.read();
	cout << "The running time = " << runtime << " (ms)" << endl << endl;

	/******************************** [ IWFT ] *******************************/
	cout << "Taking inverse windowed Fourier transform." << endl;
	cnt.start();
	Vector<Type> x = iwft( coefs, g );
	cnt.stop();
	runtime = cnt.read();
	cout << "The running time = " << runtime << " (ms)" << endl << endl;

	cout << "The relative error is : " << "norm(s-x) / norm(s) = "
		 << norm(s-x)/norm(s) << endl << endl;

	return 0;
}
开发者ID:Holdlen2DH,项目名称:tspl,代码行数:40,代码来源:wft_test.cpp

示例13: setOutputMatrixToAlgebraDefault

void setOutputMatrixToAlgebraDefault(float_tt* dst, size_t numVal, log4cxx::LoggerPtr logger) {
    Timing timer;
    valsSet(dst, ::nan(""), numVal); // ScaLAPACK algorithm should provide all entries in matrix
    LOG4CXX_DEBUG(SCALAPACKPHYSICAL_HPP_logger, "setOutputMatrixToAlgebraDefault took " << timer.stop());
}
开发者ID:Goon83,项目名称:scidb,代码行数:5,代码来源:ScaLAPACKPhysical.hpp

示例14: main

int main(int argc, char** argv)
{
	Timing t;
	int i;

	// TODO: debug should be enabled with a command-line option
	// FILELog::ReportingLevel() = FILELog::FromString("DEBUG4");
	// FILELog::ReportingLevel() = FILELog::FromString("DEBUG1");
	FILELog::ReportingLevel() = FILELog::FromString("INFO");
	FILE_LOG(logDEBUG4) << "starting";

	t.Start();
	try {

		Picoscope6000 *pico = new Picoscope6000();
		Measurement   *meas = new Measurement(pico);
		Channel       *ch[4];

		meas->SetTimebaseInPs(400);
		meas->EnableChannels(true,false,false,false);
		for(i=0; i<PICOSCOPE_N_CHANNELS; i++) {
			ch[i] = meas->GetChannel(i);
			FILE_LOG(logDEBUG4) << "main - Channel " << (char)('A'+i) << " has index " << ch[i]->GetIndex();
		}

		Args x;
		x.parse_options(argc, argv, meas);
		if(x.IsJustHelp()) {
			return 0;
		}

		if(x.GetFilename() == NULL) { // TODO: maybe we want to use just text file
			throw("You have to provide some filename using '--name <filename>'.\n");
		}

		// meas->SetTimebaseInPs(10000);

		// TODO: fixme
		for(i=0; i<PICOSCOPE_N_CHANNELS; i++) {
			ch[i]->SetVoltage(x.GetVoltage());
		}

		// a->SetVoltage(U_100mV);
		// a[0]->SetVoltage(x.GetVoltage());
		// meas->SetLength(GIGA(1));
		meas->SetLength(x.GetLength());

		if(x.GetNTraces() > 1) {
			meas->SetNTraces(x.GetNTraces());
			// TODO: fix trigger
			FILE_LOG(logDEBUG4) << "main - checking for triggered events";
			if(x.IsTriggered()) {
				for(i=0; i<PICOSCOPE_N_CHANNELS && !(ch[i]->IsEnabled()); i++);
				FILE_LOG(logDEBUG4) << "main - will trigger on channel " << (char)('A'+i);
				meas->SetTrigger(x.GetTrigger(ch[i]));
			}
			meas->AllocateMemoryRapidBlock(MEGA(50));
		} else {
			meas->AllocateMemoryBlock(MEGA(50));
		}

		// std::cerr << "test w5\n";

		// it only makes sense to measure if we decided to use some positive number of samples
		if(x.GetLength()>0) {

			FILE *f = NULL;
			FILE *fb[4] = {NULL,NULL,NULL,NULL}, *ft[4] = {NULL,NULL,NULL,NULL};

			struct tm *current;
			time_t now;
			time(&now);
			current = localtime(&now);

			for(i=0; i<PICOSCOPE_N_CHANNELS; i++) {
				if(ch[i]->IsEnabled()) {
					if(x.IsTextOutput()) {
						ft[i] = fopen(x.GetFilenameText(i), "wt");
						if(ft[i] == NULL) {
							throw("Unable to open text file.\n"); // TODO: write filename
						}
					}
					if(x.IsBinaryOutput()) {
						fb[i] = fopen(x.GetFilenameBinary(i), "wb");
						if(fb[i] == NULL) {
							throw("Unable to open binary file.\n"); // TODO: write filename
						}
					}
				}
			}

			/************************************************************/
			double tmp_dbl;
			short  tmp_short;
			pico->Open();
			meas->InitializeSignalGenerator();
			meas->RunBlock();

			/* metadata */
			f = fopen(x.GetFilenameMeta(), "wt");
//.........这里部分代码省略.........
开发者ID:enascimento,项目名称:picoscope,代码行数:101,代码来源:run_picoscope.cpp

示例15: main

int main(int argc, char **argv)
{
    DecPOMDPDiscreteInterface* decpomdp;
    try {
        ArgumentHandlers::Arguments args;
        argp_parse (&ArgumentHandlers::theArgpStruc, argc, argv, 0, 0, &args);

        Timing times;
        times.Start("Parsing");
        //DecPOMDPDiscreteInterface* 
        decpomdp = GetDecPOMDPDiscreteInterfaceFromArgs(args);
        TransitionObservationIndependentMADPDiscrete *toi=0;
        if((toi=dynamic_cast<TransitionObservationIndependentMADPDiscrete*>(decpomdp)) &&
           args.qheur==eQMDP &&
           !args.cache_flat_models /* otherwise
                                    * GetDecPOMDPDiscreteInterfaceFromArgs
                                    * already caches the flat
                                    * models */)
        {
            // we don't need a centralized obs model
            toi->CreateCentralizedSparseTransitionModel();
        }

        times.Stop("Parsing");

        if(!args.dryrun)
            directories::MADPCreateResultsDir("GMAA",*decpomdp);
        
        size_t horizon;
        if(args.infiniteHorizon)
            horizon=MAXHORIZON;
        else
            horizon=args.horizon;

        times.Start("Overall");

        PlanningUnitMADPDiscreteParameters params;
#if 0 // Caching doesn't seem worth the trouble if we're computing
      // just one thing (not to mention the memory savings)
        if(Qheur==eQMDP) // don't need any of this for solving the MDP
            params.SetComputeAll(false);
        else
        {
            params.SetComputeAll(true);
            params.SetUseSparseJointBeliefs(true);
        }
#else
        params.SetComputeAll(false);
        if(args.sparse)
            params.SetUseSparseJointBeliefs(true);
#endif

        times.Start("PlanningUnit");
        NullPlanner np(params,horizon,decpomdp);
        times.Stop("PlanningUnit");

        struct timeval tvStart, tvEnd;
        gettimeofday (&tvStart, NULL);

        QFunctionJAOHInterface* q=0;
        for(int restartI = 0; restartI < args.nrRestarts; restartI++)
        {
            // with hybrid heuristics already some computation is done
            // before Compute(), so start timing now
            times.Start("ComputeQ");
            q = GetQheuristicFromArgs(&np, args);
            q->Compute();
            times.Stop("ComputeQ");

            // we want to keep the last q computed
            if(restartI<(args.nrRestarts-1))
                delete q;
        }

        gettimeofday (&tvEnd, NULL);

        clock_t wallclockTime = 
            static_cast<clock_t>(((tvEnd.tv_sec - tvStart.tv_sec) +
                                  static_cast<double>(tvEnd.tv_usec-tvStart.tv_usec)/1e6) * sysconf(_SC_CLK_TCK));

        cout << "Wallclock: from "
             << tvStart.tv_sec << "." << tvStart.tv_usec
             << " until "
             << tvEnd.tv_sec << "." << tvEnd.tv_usec
             << " which took " << wallclockTime << " clock ticks"
             << endl;
        
        times.AddEvent("WallclockTime", wallclockTime);

        if(!args.dryrun)
        {
            times.Start("Save");
            q->Save();
            times.Stop("Save");
            if(args.verbose >= 0)
                cout << "Q saved to " << q->GetCacheFilename() << endl;
        }
        times.Stop("Overall");

        if(args.verbose >= 0)
//.........这里部分代码省略.........
开发者ID:heckj,项目名称:MADP,代码行数:101,代码来源:calculateQheuristic.cpp


注:本文中的Timing类示例由纯净天空整理自Github/MSDocs等开源代码及文档管理平台,相关代码片段筛选自各路编程大神贡献的开源项目,源码版权归原作者所有,传播和使用请参考对应项目的License;未经允许,请勿转载。