/*
 * This method must be called under interrupt masked.
 * The reaction will demask interrupt and we remask it before leaving this method.
 */ 
void ScheduleEvent(struct TEvent* event) {
	t_reaction reaction = (t_reaction)event->reaction;
	
 	// Set the new THIS
    THIS = (void*)(event->THIS);
 
    // IT are unmasked in the reaction
 	reaction(event); 

	// Mask it, in order to recoming in the scheduler
 	MASK_ALL_ITS();
}
예제 #2
0
int reaction(int idx, bool forced = false) {
	int l = (idx == 0 ? atoms.size() : idx) - 1;
	int r = idx + 1 == atoms.size() ? 0 : idx + 1;
	if (atoms.size() > 2 && (atoms[l]->number == atoms[r]->number && atoms[l]->type == Atom::atype::normal || atoms[idx]->type == Atom::atype::black_plus)) {
		unsigned char number;
		if (atoms[idx]->type == Atom::atype::normal)
			number = atoms[idx]->number > atoms[l]->number ? atoms[idx]->number + 1 : atoms[l]->number + 2;
		else if (atoms[idx]->type == Atom::atype::red_plus)
			number = atoms[l]->number + 1;
		else // black_plus
			number = max(atoms[l]->number, atoms[r]->number) + 3;
		atoms[l] = new Atom(new coord2d(0, 0), number);
		atoms.erase(atoms.begin() + r);
		atoms.erase(atoms.begin() + idx - (r == 0));
		return 1 + reaction(l - (idx < l) - (r < l));
	}
	return 0;
}
예제 #3
0
void KGameComputerIO::advance()
{
  if (d->mPauseCounter > 0)
  {
    d->mPauseCounter--;
    return;
  }
  else if (d->mPauseCounter < 0)
  {
    return;
  }
  d->mAdvanceCounter++;
  if (d->mAdvanceCounter >= d->mReactionPeriod)
  {
    d->mAdvanceCounter = 0;
    reaction();
  }
}
예제 #4
0
TEST (MongoPluginTest2, storeData)
{
  auto storage = new soft::Storage("mongo2", "mongodb://localhost", "db=plugintest;coll=coll");
  ASSERT_TRUE(nullptr != storage);

  soft::Chemkin_reaction reaction(0, 0, 0, 0, 0);
  reaction.third_body = true;
  reaction.b = 1.0;
  reaction.Ea = 1.0E-2;
  reaction.A = 0.2;
  storage->save(&reaction);

  soft::Chemkin_reaction copy(reaction.id());
  storage->load(&copy);
  ASSERT_EQ(copy.third_body, reaction.third_body);
  ASSERT_DOUBLE_EQ(copy.b, reaction.b);
  ASSERT_DOUBLE_EQ(copy.Ea, reaction.Ea);
  ASSERT_DOUBLE_EQ(copy.A, reaction.A);
}
예제 #5
0
	void run()
	{
		// init
		sp::size = convert::init(pipe::fix_list, point_size);

		// populate kmx, tmx
		convert::matrix(pipe::point_list, pipe::element_list, element_size);

		sp::SymetryMatrix K = convert::kmx;

		// populate F
		auto F = convert::force(pipe::force_list, force_size);

		auto begin_time = QTime::currentTime();

		// solve K * dp = F
		sp::Vector dp;

		// steepest_descent
		dp = sp::Vector();
		steepest_descent(dp, K, F);
		Q_ASSERT(sp::Vector::norm2(K * dp, F) < 1e-10);

		// conjagate_gradients
		dp = sp::Vector();
		conjagate_gradients(dp, K, F);
		Q_ASSERT(sp::Vector::norm2(K * dp, F) < 1e-10);

		// solve tensions
		QVector<double> reaction(3 * point_size - sp::size);
		sp::mul(reaction, convert::tmx, dp);

		// convert back to 3D domain
		convert::displace(displace_list, dp);
		convert::reaction(reaction_list, pipe::fix_list, fix_size, reaction);

		QVector<clip::Element> original_elements = clip::make(pipe::point_list, pipe::element_list, element_size, rotate);
		QVector<clip::Element> displace_elements = clip::make(displace_list, pipe::element_list, element_size, rotate);
		store_figure_pipe(original_elements, displace_elements);

		qDebug() << "total time: " << begin_time.msecsTo(QTime::currentTime());
	}
예제 #6
0
//--------------------------------------------------------------
void Rd::step(int numSteps){
	for(int i = 0; i < numSteps; i++){
		diffusion();
		reaction();
	}
}
예제 #7
0
void Game::mouseLeftDown(coord2d c)
{
	++count;
	// calculate inserted atom position in vector
	int pos = 0;
	float theta = 0, ang = c.getRadians();
	if (atoms.size() > 0) {
		theta = circ / atoms.size();
		float start = atoms[0]->center->getRadians();
		if (start > ang)
			start -= circ;
		pos = floor((ang - start) / theta) + 1;
	}

	atoms.insert(atoms.begin() + pos, centralAtom);
	float phase = atoms[0]->center->getRadians();
	ang = pos * theta - theta / 2 + phase;

	// change every atom postion accordingly
	atoms[pos]->center->fromRadians(ang, radius);
	updateAtomsPosition(pos);

	// look for chain reactions
	for (int i = 0; i < atoms.size(); i++)
		if (atoms[i]->type == Atom::atype::red_plus || atoms[i]->type == Atom::atype::black_plus) {
			if (int q = reaction(i)) {
				// if there's a reaction I have to update positions again and check for another one
				pos = (atoms.size() + i - q - (i >= atoms.size() + q ? atoms.size() + q - i + 1 : 0)) % atoms.size();
				ang = i * theta - theta / 2 + phase;
				atoms[pos]->center->fromRadians(ang, radius);
				updateAtomsPosition(pos);
				theta = circ / atoms.size();
				phase = atoms[0]->center->getRadians();
				i = -1; // beware of teh bad wolf
			}
		}

	// Calulate energy particles spawning chance.
	Atom::atype type = Atom::atype::normal;
	// Every time the red plus isn't picked up its chance is doubled and the 5th time (32) is 100%.
	// I think this works quite well but I should RE the game (or ask the dev eh) to know the real algorithm.
	lastRedPlus *= 2;
	if (count % 20 == 0) {
		type = Atom::atype::minus;
	}
	else if (randrange(32) < lastRedPlus) {
		type = Atom::atype::red_plus;
		lastRedPlus = 1;
	}
	else if (score > 750 && randrange(80) == 0) {
		type = Atom::atype::black_plus;
	}
	else if (score > 1500 && randrange(60) == 0) {
		type = Atom::atype::neutrino;
	}

	unsigned char number = 0, startRange = 1 + count / 40;
	if (type == Atom::atype::normal) {
		number = startRange + randrange(4);
		// check if there's an atom below the spawning range
		for (Atom* a : atoms) if (a->type == Atom::atype::normal && a->number < startRange)
			if (randrange(atoms.size() - 1) == 0) {
				number = a->number;
				break;
			}
	}
	centralAtom = new Atom(new coord2d(0, 0), type, number);
}