JsonExpression.cpp 44 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445
  1. #include "JsonExpression.h"
  2. #include "Chunk.h"
  3. #include "Game.h"
  4. JExpressionMemory::JExpressionMemory()
  5. : ReferenceCounter(),
  6. currentChunk(0)
  7. {}
  8. JExpressionMemory::~JExpressionMemory()
  9. {
  10. if (currentChunk) currentChunk->release();
  11. }
  12. void JExpressionMemory::lock()
  13. {
  14. cs.lock();
  15. }
  16. void JExpressionMemory::unlock()
  17. {
  18. cs.unlock();
  19. }
  20. Noise* JExpressionMemory::zNoiseP(Framework::Text name)
  21. {
  22. return noises.z(name, name.getLength());
  23. }
  24. void JExpressionMemory::setNoise(Framework::Text name, Noise* noise)
  25. {
  26. noises.set(name, name.getLength(), noise);
  27. }
  28. void JExpressionMemory::setCurrentChunk(Chunk* chunk)
  29. {
  30. if (currentChunk) currentChunk->release();
  31. currentChunk = chunk;
  32. }
  33. float* JExpressionMemory::getFloatVariableP(const Framework::Text& name)
  34. {
  35. if (!floatVariables.contains(name, name.getLength()))
  36. {
  37. floatVariables.set(name, name.getLength(), 0.f);
  38. }
  39. return floatVariables.getP(name, name.getLength());
  40. }
  41. bool* JExpressionMemory::getBoolVariableP(const Framework::Text& name)
  42. {
  43. if (!boolVariables.contains(name, name.getLength()))
  44. {
  45. boolVariables.set(name, name.getLength(), 0);
  46. }
  47. return boolVariables.getP(name, name.getLength());
  48. }
  49. Chunk** JExpressionMemory::zzCurrentChunk()
  50. {
  51. return &currentChunk;
  52. }
  53. JFloatExpression::JFloatExpression()
  54. : ReferenceCounter(),
  55. compiled(0)
  56. {}
  57. float JFloatExpression::getValue()
  58. {
  59. return compiled();
  60. }
  61. FloatFunc JFloatExpression::compile(JExpressionMemory* zMemory)
  62. {
  63. if (compiled)
  64. {
  65. if (zMemory != memory)
  66. {
  67. throw "Cannot compile the same expression for different memories";
  68. }
  69. return compiled;
  70. }
  71. memory = zMemory;
  72. return compiled = buildAssembly(zMemory).compileToFunction<FloatFunc>();
  73. }
  74. JBoolExpression::JBoolExpression()
  75. : ReferenceCounter(),
  76. compiled(0)
  77. {}
  78. bool JBoolExpression::getValue()
  79. {
  80. return compiled();
  81. }
  82. BoolFunc JBoolExpression::compile(JExpressionMemory* zMemory)
  83. {
  84. if (compiled)
  85. {
  86. if (zMemory != memory)
  87. {
  88. throw "Cannot compile the same expression for different "
  89. "memories";
  90. }
  91. return compiled;
  92. }
  93. memory = zMemory;
  94. return compiled = buildAssembly(zMemory).compileToFunction<BoolFunc>();
  95. }
  96. JVariableFloatExpression::JVariableFloatExpression()
  97. : JFloatExpression()
  98. {}
  99. Framework::Assembly::AssemblyBlock& JVariableFloatExpression::buildAssembly(
  100. JExpressionMemory* zMemory)
  101. {
  102. codeBlock.addLoadValue(
  103. zMemory->getFloatVariableP(name), Framework::Assembly::MM0);
  104. return codeBlock;
  105. }
  106. void JVariableFloatExpression::setName(Framework::Text name)
  107. {
  108. this->name = name;
  109. }
  110. Framework::Text JVariableFloatExpression::getName() const
  111. {
  112. return name;
  113. }
  114. JVariableFloatExpressionFactory::JVariableFloatExpressionFactory()
  115. : SubTypeFactory()
  116. {}
  117. JVariableFloatExpression* JVariableFloatExpressionFactory::fromJson(
  118. Framework::JSON::JSONObject* zJson) const
  119. {
  120. JVariableFloatExpression* result = new JVariableFloatExpression();
  121. result->setName(zJson->zValue("name")->asString()->getString());
  122. return result;
  123. }
  124. Framework::JSON::JSONObject* JVariableFloatExpressionFactory::toJsonObject(
  125. JVariableFloatExpression* zObject) const
  126. {
  127. Framework::JSON::JSONObject* result = new Framework::JSON::JSONObject();
  128. result->addValue(
  129. "name", new Framework::JSON::JSONString(zObject->getName()));
  130. return result;
  131. }
  132. JSONObjectValidationBuilder* JVariableFloatExpressionFactory::addToValidator(
  133. JSONObjectValidationBuilder* builder) const
  134. {
  135. return builder->withRequiredString("name")->finishString();
  136. }
  137. const char* JVariableFloatExpressionFactory::getTypeToken() const
  138. {
  139. return "variable";
  140. }
  141. JVariableBoolExpression::JVariableBoolExpression()
  142. : JBoolExpression()
  143. {}
  144. Framework::Assembly::AssemblyBlock& JVariableBoolExpression::buildAssembly(
  145. JExpressionMemory* zMemory)
  146. {
  147. codeBlock.addLoadValue(
  148. (char*)zMemory->getBoolVariableP(name), Framework::Assembly::RAX);
  149. return codeBlock;
  150. }
  151. void JVariableBoolExpression::setName(Framework::Text name)
  152. {
  153. this->name = name;
  154. }
  155. Framework::Text JVariableBoolExpression::getName() const
  156. {
  157. return name;
  158. }
  159. JVariableBoolExpressionFactory::JVariableBoolExpressionFactory()
  160. : SubTypeFactory()
  161. {}
  162. JVariableBoolExpression* JVariableBoolExpressionFactory::fromJson(
  163. Framework::JSON::JSONObject* zJson) const
  164. {
  165. JVariableBoolExpression* result = new JVariableBoolExpression();
  166. result->setName(zJson->zValue("name")->asString()->getString());
  167. return result;
  168. }
  169. Framework::JSON::JSONObject* JVariableBoolExpressionFactory::toJsonObject(
  170. JVariableBoolExpression* zObject) const
  171. {
  172. Framework::JSON::JSONObject* result = new Framework::JSON::JSONObject();
  173. result->addValue(
  174. "name", new Framework::JSON::JSONString(zObject->getName()));
  175. return result;
  176. }
  177. JSONObjectValidationBuilder* JVariableBoolExpressionFactory::addToValidator(
  178. JSONObjectValidationBuilder* builder) const
  179. {
  180. return builder->withRequiredString("name")->finishString();
  181. }
  182. const char* JVariableBoolExpressionFactory::getTypeToken() const
  183. {
  184. return "variable";
  185. }
  186. JConstantFloatExpression::JConstantFloatExpression()
  187. : JFloatExpression(),
  188. value(0)
  189. {}
  190. Framework::Assembly::AssemblyBlock& JConstantFloatExpression::buildAssembly(
  191. JExpressionMemory* zMemory)
  192. {
  193. codeBlock.addLoadValue(&value, Framework::Assembly::MM0);
  194. return codeBlock;
  195. }
  196. void JConstantFloatExpression::setValue(float value)
  197. {
  198. this->value = value;
  199. }
  200. float JConstantFloatExpression::getValue() const
  201. {
  202. return value;
  203. }
  204. JConstantFloatExpressionFactory::JConstantFloatExpressionFactory()
  205. : SubTypeFactory()
  206. {}
  207. JConstantFloatExpression* JConstantFloatExpressionFactory::fromJson(
  208. Framework::JSON::JSONObject* zJson) const
  209. {
  210. JConstantFloatExpression* result = new JConstantFloatExpression();
  211. result->setValue((float)zJson->zValue("value")->asNumber()->getNumber());
  212. return result;
  213. }
  214. Framework::JSON::JSONObject* JConstantFloatExpressionFactory::toJsonObject(
  215. JConstantFloatExpression* zObject) const
  216. {
  217. Framework::JSON::JSONObject* result = new Framework::JSON::JSONObject();
  218. result->addValue(
  219. "value", new Framework::JSON::JSONNumber(zObject->getValue()));
  220. return result;
  221. }
  222. JSONObjectValidationBuilder* JConstantFloatExpressionFactory::addToValidator(
  223. JSONObjectValidationBuilder* builder) const
  224. {
  225. return builder->withRequiredNumber("value")->finishNumber();
  226. }
  227. const char* JConstantFloatExpressionFactory::getTypeToken() const
  228. {
  229. return "constant";
  230. }
  231. JConstantBoolExpression::JConstantBoolExpression()
  232. : JBoolExpression()
  233. {}
  234. Framework::Assembly::AssemblyBlock& JConstantBoolExpression::buildAssembly(
  235. JExpressionMemory* zMemory)
  236. {
  237. codeBlock.addMoveValue(Framework::Assembly::RAX, (char)(value ? 1 : 0));
  238. return codeBlock;
  239. }
  240. void JConstantBoolExpression::setValue(bool value)
  241. {
  242. this->value = value;
  243. }
  244. bool JConstantBoolExpression::getValue() const
  245. {
  246. return value;
  247. }
  248. JConstantBoolExpressionFactory::JConstantBoolExpressionFactory()
  249. : SubTypeFactory()
  250. {}
  251. JConstantBoolExpression* JConstantBoolExpressionFactory::fromJson(
  252. Framework::JSON::JSONObject* zJson) const
  253. {
  254. JConstantBoolExpression* result = new JConstantBoolExpression();
  255. result->setValue(zJson->zValue("value")->asBool()->getBool());
  256. return result;
  257. }
  258. Framework::JSON::JSONObject* JConstantBoolExpressionFactory::toJsonObject(
  259. JConstantBoolExpression* zObject) const
  260. {
  261. Framework::JSON::JSONObject* zResult = new Framework::JSON::JSONObject();
  262. zResult->addValue(
  263. "value", new Framework::JSON::JSONBool(zObject->getValue()));
  264. return zResult;
  265. }
  266. JSONObjectValidationBuilder* JConstantBoolExpressionFactory::addToValidator(
  267. JSONObjectValidationBuilder* builder) const
  268. {
  269. return builder->withRequiredBool("value")->finishBool();
  270. }
  271. const char* JConstantBoolExpressionFactory::getTypeToken() const
  272. {
  273. return "constant";
  274. }
  275. JNoiseFloatExpression::JNoiseFloatExpression()
  276. : JFloatExpression(),
  277. x(0),
  278. y(0),
  279. z(0)
  280. {}
  281. JNoiseFloatExpression::~JNoiseFloatExpression()
  282. {
  283. if (x) x->release();
  284. if (y) y->release();
  285. if (z) z->release();
  286. }
  287. Framework::Assembly::AssemblyBlock& JNoiseFloatExpression::buildAssembly(
  288. JExpressionMemory* zMemory)
  289. {
  290. Noise* noise = zMemory->zNoiseP(name);
  291. if (!noise)
  292. {
  293. Framework::Logging::error() << "no noise with name '" << name.getText()
  294. << "' found, behavior is undefined\n";
  295. return codeBlock;
  296. }
  297. Framework::Assembly::AssemblyBlock& xBlock = x->buildAssembly(zMemory);
  298. Framework::Assembly::AssemblyBlock& yBlock = y->buildAssembly(zMemory);
  299. Framework::Assembly::AssemblyBlock& zBlock = z->buildAssembly(zMemory);
  300. Framework::Assembly::FPRegister xTarget = Framework::Assembly::MM0;
  301. if (xBlock.isReplacementPossible(
  302. Framework::Assembly::MM0, Framework::Assembly::MM1))
  303. {
  304. xBlock.replaceRegister(
  305. Framework::Assembly::MM0, Framework::Assembly::MM1);
  306. xTarget = Framework::Assembly::MM1;
  307. }
  308. Framework::Assembly::FPRegister yTarget = Framework::Assembly::MM0;
  309. if (yBlock.isReplacementPossible(
  310. Framework::Assembly::MM0, Framework::Assembly::MM2))
  311. {
  312. yBlock.replaceRegister(
  313. Framework::Assembly::MM0, Framework::Assembly::MM2);
  314. yTarget = Framework::Assembly::MM2;
  315. }
  316. Framework::Assembly::FPRegister zTarget = Framework::Assembly::MM0;
  317. if (zBlock.isReplacementPossible(
  318. Framework::Assembly::MM0, Framework::Assembly::MM3))
  319. {
  320. zBlock.replaceRegister(
  321. Framework::Assembly::MM0, Framework::Assembly::MM3);
  322. zTarget = Framework::Assembly::MM3;
  323. }
  324. codeBlock.addBlock(&zBlock, {}, {}, {}, 0, &zTarget);
  325. if (zTarget != Framework::Assembly::MM3)
  326. {
  327. codeBlock.addMoveValue(Framework::Assembly::MM3,
  328. zTarget,
  329. Framework::Assembly::SINGLE_FLOAT,
  330. Framework::Assembly::X);
  331. }
  332. codeBlock.addBlock(&yBlock,
  333. {},
  334. {Framework::Assembly::MM3},
  335. {Framework::Assembly::SINGLE_FLOAT},
  336. 0,
  337. &yTarget);
  338. if (yTarget != Framework::Assembly::MM2)
  339. {
  340. codeBlock.addMoveValue(Framework::Assembly::MM2,
  341. yTarget,
  342. Framework::Assembly::SINGLE_FLOAT,
  343. Framework::Assembly::X);
  344. }
  345. codeBlock.addBlock(&xBlock,
  346. {},
  347. {Framework::Assembly::MM2, Framework::Assembly::MM3},
  348. {Framework::Assembly::SINGLE_FLOAT, Framework::Assembly::SINGLE_FLOAT},
  349. 0,
  350. &xTarget);
  351. if (xTarget != Framework::Assembly::MM1)
  352. {
  353. codeBlock.addMoveValue(Framework::Assembly::MM1,
  354. xTarget,
  355. Framework::Assembly::SINGLE_FLOAT,
  356. Framework::Assembly::X);
  357. }
  358. codeBlock.addLoadAddress(noise, Framework::Assembly::RCX);
  359. codeBlock.addMemberCall<float (Noise::*)(float, float, float)>(
  360. &Noise::getNoise,
  361. Framework::Assembly::FLOAT_VALUE,
  362. {Framework::Assembly::RCX},
  363. {Framework::Assembly::MM1,
  364. Framework::Assembly::MM2,
  365. Framework::Assembly::MM3});
  366. return codeBlock;
  367. }
  368. void JNoiseFloatExpression::setName(Framework::Text name)
  369. {
  370. this->name = name;
  371. }
  372. Framework::Text JNoiseFloatExpression::getName() const
  373. {
  374. return name;
  375. }
  376. void JNoiseFloatExpression::setX(JFloatExpression* x)
  377. {
  378. if (this->x) this->x->release();
  379. this->x = x;
  380. }
  381. JFloatExpression* JNoiseFloatExpression::zX() const
  382. {
  383. return x;
  384. }
  385. void JNoiseFloatExpression::setY(JFloatExpression* y)
  386. {
  387. if (this->y) this->y->release();
  388. this->y = y;
  389. }
  390. JFloatExpression* JNoiseFloatExpression::zY() const
  391. {
  392. return y;
  393. }
  394. void JNoiseFloatExpression::setZ(JFloatExpression* z)
  395. {
  396. if (this->z) this->z->release();
  397. this->z = z;
  398. }
  399. JFloatExpression* JNoiseFloatExpression::zZ() const
  400. {
  401. return z;
  402. }
  403. JNoiseFloatExpressionFactory::JNoiseFloatExpressionFactory()
  404. : SubTypeFactory()
  405. {}
  406. JNoiseFloatExpression* JNoiseFloatExpressionFactory::fromJson(
  407. Framework::JSON::JSONObject* zJson) const
  408. {
  409. JNoiseFloatExpression* result = new JNoiseFloatExpression();
  410. result->setName(zJson->zValue("name")->asString()->getString());
  411. result->setX(Game::INSTANCE->zTypeRegistry()->fromJson<JFloatExpression>(
  412. zJson->zValue("x")));
  413. result->setY(Game::INSTANCE->zTypeRegistry()->fromJson<JFloatExpression>(
  414. zJson->zValue("y")));
  415. result->setZ(Game::INSTANCE->zTypeRegistry()->fromJson<JFloatExpression>(
  416. zJson->zValue("z")));
  417. return result;
  418. }
  419. Framework::JSON::JSONObject* JNoiseFloatExpressionFactory::toJsonObject(
  420. JNoiseFloatExpression* zObject) const
  421. {
  422. Framework::JSON::JSONObject* result = new Framework::JSON::JSONObject();
  423. result->addValue(
  424. "name", new Framework::JSON::JSONString(zObject->getName()));
  425. result->addValue(
  426. "x", Game::INSTANCE->zTypeRegistry()->toJson(zObject->zX()));
  427. result->addValue(
  428. "y", Game::INSTANCE->zTypeRegistry()->toJson(zObject->zY()));
  429. result->addValue(
  430. "z", Game::INSTANCE->zTypeRegistry()->toJson(zObject->zZ()));
  431. return result;
  432. }
  433. JSONObjectValidationBuilder* JNoiseFloatExpressionFactory::addToValidator(
  434. JSONObjectValidationBuilder* builder) const
  435. {
  436. return builder->withRequiredString("name")
  437. ->finishString()
  438. ->withRequiredAttribute("x",
  439. Game::INSTANCE->zTypeRegistry()->getValidator<JFloatExpression>())
  440. ->withRequiredAttribute("y",
  441. Game::INSTANCE->zTypeRegistry()->getValidator<JFloatExpression>())
  442. ->withRequiredAttribute("z",
  443. Game::INSTANCE->zTypeRegistry()->getValidator<JFloatExpression>());
  444. }
  445. const char* JNoiseFloatExpressionFactory::getTypeToken() const
  446. {
  447. return "noise";
  448. }
  449. JOperatorFloatExpression::JOperatorFloatExpression()
  450. : JFloatExpression()
  451. {}
  452. Framework::Assembly::AssemblyBlock& JOperatorFloatExpression::buildAssembly(
  453. JExpressionMemory* zMemory)
  454. {
  455. bool first = 1;
  456. if (!values.getEntryCount())
  457. {
  458. codeBlock.addMoveValue(Framework::Assembly::MM0, 0.f);
  459. }
  460. for (JFloatExpression* expression : values)
  461. {
  462. if (first)
  463. {
  464. first = 0;
  465. codeBlock.addBlock(
  466. &expression->buildAssembly(zMemory), {}, {}, {}, 0, 0);
  467. }
  468. else
  469. {
  470. Framework::Assembly::AssemblyBlock& exprBlock
  471. = expression->buildAssembly(zMemory);
  472. if (exprBlock.isReplacementPossible(
  473. Framework::Assembly::MM0, Framework::Assembly::MM1))
  474. {
  475. exprBlock.replaceRegister(
  476. Framework::Assembly::MM0, Framework::Assembly::MM1);
  477. }
  478. else
  479. {
  480. exprBlock.addMoveValue(Framework::Assembly::MM1,
  481. Framework::Assembly::MM0,
  482. Framework::Assembly::SINGLE_FLOAT,
  483. Framework::Assembly::X);
  484. }
  485. codeBlock.addBlock(&exprBlock,
  486. {},
  487. {Framework::Assembly::MM0},
  488. {Framework::Assembly::SINGLE_FLOAT},
  489. 0,
  490. 0);
  491. if (op.isEqual("+"))
  492. {
  493. codeBlock.addAddition(Framework::Assembly::MM0,
  494. Framework::Assembly::MM1,
  495. Framework::Assembly::SINGLE_FLOAT,
  496. Framework::Assembly::X);
  497. }
  498. else if (op.isEqual("-"))
  499. {
  500. codeBlock.addSubtraction(Framework::Assembly::MM0,
  501. Framework::Assembly::MM1,
  502. Framework::Assembly::SINGLE_FLOAT,
  503. Framework::Assembly::X);
  504. }
  505. else if (op.isEqual("*"))
  506. {
  507. codeBlock.addMultiplication(Framework::Assembly::MM0,
  508. Framework::Assembly::MM1,
  509. Framework::Assembly::SINGLE_FLOAT,
  510. Framework::Assembly::X);
  511. }
  512. else if (op.isEqual("/"))
  513. {
  514. codeBlock.addDivision(Framework::Assembly::MM0,
  515. Framework::Assembly::MM1,
  516. Framework::Assembly::SINGLE_FLOAT,
  517. Framework::Assembly::X);
  518. }
  519. }
  520. }
  521. return codeBlock;
  522. }
  523. void JOperatorFloatExpression::setOperator(Framework::Text op)
  524. {
  525. this->op = op;
  526. }
  527. Framework::Text JOperatorFloatExpression::getOperator()
  528. {
  529. return op;
  530. }
  531. void JOperatorFloatExpression::addValue(JFloatExpression* value)
  532. {
  533. values.add(value);
  534. }
  535. const Framework::RCArray<JFloatExpression>&
  536. JOperatorFloatExpression::getValues() const
  537. {
  538. return values;
  539. }
  540. JOperatorFloatExpressionFactory::JOperatorFloatExpressionFactory()
  541. : SubTypeFactory()
  542. {}
  543. JOperatorFloatExpression* JOperatorFloatExpressionFactory::fromJson(
  544. Framework::JSON::JSONObject* zJson) const
  545. {
  546. JOperatorFloatExpression* result = new JOperatorFloatExpression();
  547. result->setOperator(zJson->zValue("operator")->asString()->getString());
  548. for (Framework::JSON::JSONValue* value :
  549. *zJson->zValue("values")->asArray())
  550. {
  551. result->addValue(
  552. Game::INSTANCE->zTypeRegistry()->fromJson<JFloatExpression>(value));
  553. }
  554. return result;
  555. }
  556. Framework::JSON::JSONObject* JOperatorFloatExpressionFactory::toJsonObject(
  557. JOperatorFloatExpression* zObject) const
  558. {
  559. Framework::JSON::JSONObject* result = new Framework::JSON::JSONObject();
  560. result->addValue(
  561. "operator", new Framework::JSON::JSONString(zObject->getOperator()));
  562. Framework::JSON::JSONArray* values = new Framework::JSON::JSONArray();
  563. for (JFloatExpression* expression : zObject->getValues())
  564. {
  565. values->addValue(
  566. Game::INSTANCE->zTypeRegistry()->toJson<JFloatExpression>(
  567. expression));
  568. }
  569. result->addValue("values", values);
  570. return result;
  571. }
  572. JSONObjectValidationBuilder* JOperatorFloatExpressionFactory::addToValidator(
  573. JSONObjectValidationBuilder* builder) const
  574. {
  575. return builder->withRequiredString("operator")
  576. ->whichIsOneOf({"+", "-", "*", "/"})
  577. ->finishString()
  578. ->withRequiredArray("values")
  579. ->addAcceptedTypeInArray(
  580. Game::INSTANCE->zTypeRegistry()->getValidator<JFloatExpression>())
  581. ->finishArray();
  582. }
  583. const char* JOperatorFloatExpressionFactory::getTypeToken() const
  584. {
  585. return "operator";
  586. }
  587. JBoolOperatorBoolExpression::JBoolOperatorBoolExpression()
  588. : JBoolExpression()
  589. {}
  590. Framework::Assembly::AssemblyBlock& JBoolOperatorBoolExpression::buildAssembly(
  591. JExpressionMemory* zMemory)
  592. {
  593. bool first = 1;
  594. if (!values.getEntryCount())
  595. {
  596. codeBlock.addMoveValue(Framework::Assembly::RAX, (char)0);
  597. }
  598. for (JBoolExpression* expression : values)
  599. {
  600. if (first)
  601. {
  602. first = 0;
  603. codeBlock.addBlock(
  604. &expression->buildAssembly(zMemory), {}, {}, {}, 0, 0);
  605. }
  606. else
  607. {
  608. Framework::Assembly::AssemblyBlock& exprBlock
  609. = expression->buildAssembly(zMemory);
  610. if (exprBlock.isReplacementPossible(
  611. Framework::Assembly::RAX, Framework::Assembly::RCX))
  612. {
  613. exprBlock.replaceRegister(
  614. Framework::Assembly::RAX, Framework::Assembly::RCX);
  615. }
  616. else
  617. {
  618. exprBlock.addMoveValue(Framework::Assembly::RCX,
  619. Framework::Assembly::RAX,
  620. Framework::Assembly::LOWER8);
  621. }
  622. codeBlock.addBlock(
  623. &exprBlock, {Framework::Assembly::RAX}, {}, {}, 0, 0);
  624. if (op.isEqual("&&"))
  625. {
  626. codeBlock.addAnd(Framework::Assembly::RAX,
  627. Framework::Assembly::RCX,
  628. Framework::Assembly::LOWER8);
  629. }
  630. else if (op.isEqual("||"))
  631. {
  632. codeBlock.addOr(Framework::Assembly::RAX,
  633. Framework::Assembly::RCX,
  634. Framework::Assembly::LOWER8);
  635. }
  636. }
  637. }
  638. return codeBlock;
  639. }
  640. void JBoolOperatorBoolExpression::setOperator(Framework::Text op)
  641. {
  642. this->op = op;
  643. }
  644. Framework::Text JBoolOperatorBoolExpression::getOperator()
  645. {
  646. return op;
  647. }
  648. void JBoolOperatorBoolExpression::addValue(JBoolExpression* value)
  649. {
  650. values.add(value);
  651. }
  652. const Framework::RCArray<JBoolExpression>&
  653. JBoolOperatorBoolExpression::getValues() const
  654. {
  655. return values;
  656. }
  657. JBoolOperatorBoolExpressionFactory::JBoolOperatorBoolExpressionFactory()
  658. : SubTypeFactory()
  659. {}
  660. JBoolOperatorBoolExpression* JBoolOperatorBoolExpressionFactory::fromJson(
  661. Framework::JSON::JSONObject* zJson) const
  662. {
  663. JBoolOperatorBoolExpression* result = new JBoolOperatorBoolExpression();
  664. for (Framework::JSON::JSONValue* value :
  665. *zJson->zValue("values")->asArray())
  666. {
  667. result->addValue(
  668. Game::INSTANCE->zTypeRegistry()->fromJson<JBoolExpression>(value));
  669. }
  670. result->setOperator(zJson->zValue("operator")->asString()->getString());
  671. return result;
  672. }
  673. Framework::JSON::JSONObject* JBoolOperatorBoolExpressionFactory::toJsonObject(
  674. JBoolOperatorBoolExpression* zObject) const
  675. {
  676. Framework::JSON::JSONObject* zResult = new Framework::JSON::JSONObject();
  677. Framework::JSON::JSONArray* values = new Framework::JSON::JSONArray();
  678. for (JBoolExpression* expression : zObject->getValues())
  679. {
  680. values->addValue(
  681. Game::INSTANCE->zTypeRegistry()->toJson<JBoolExpression>(
  682. expression));
  683. }
  684. zResult->addValue("values", values);
  685. zResult->addValue(
  686. "operator", new Framework::JSON::JSONString(zObject->getOperator()));
  687. return zResult;
  688. }
  689. JSONObjectValidationBuilder* JBoolOperatorBoolExpressionFactory::addToValidator(
  690. JSONObjectValidationBuilder* builder) const
  691. {
  692. return builder->withRequiredString("operator")
  693. ->whichIsOneOf({"&&", "||"})
  694. ->finishString()
  695. ->withRequiredArray("values")
  696. ->addAcceptedTypeInArray(
  697. Game::INSTANCE->zTypeRegistry()->getValidator<JBoolExpression>())
  698. ->finishArray();
  699. }
  700. const char* JBoolOperatorBoolExpressionFactory::getTypeToken() const
  701. {
  702. return "operator";
  703. }
  704. JFloatOperatorBoolExpression::JFloatOperatorBoolExpression()
  705. : JBoolExpression()
  706. {}
  707. Framework::Assembly::AssemblyBlock& JFloatOperatorBoolExpression::buildAssembly(
  708. JExpressionMemory* zMemory)
  709. {
  710. bool first = 1;
  711. Framework::Assembly::FPRegister lastResultSorage = Framework::Assembly::MM0;
  712. for (JFloatExpression* expression : values)
  713. {
  714. if (first)
  715. {
  716. first = 0;
  717. codeBlock.addBlock(
  718. &expression->buildAssembly(zMemory), {}, {}, {}, 0, 0);
  719. }
  720. else
  721. {
  722. Framework::Assembly::FPRegister currentResultSorage
  723. = lastResultSorage == Framework::Assembly::MM0
  724. ? Framework::Assembly::MM1
  725. : Framework::Assembly::MM0;
  726. Framework::Assembly::AssemblyBlock& exprBlock
  727. = expression->buildAssembly(zMemory);
  728. if (currentResultSorage != Framework::Assembly::MM0)
  729. {
  730. if (exprBlock.isReplacementPossible(
  731. Framework::Assembly::MM0, currentResultSorage))
  732. {
  733. exprBlock.replaceRegister(
  734. Framework::Assembly::MM0, currentResultSorage);
  735. }
  736. else
  737. {
  738. exprBlock.addMoveValue(currentResultSorage,
  739. Framework::Assembly::MM0,
  740. Framework::Assembly::SINGLE_FLOAT,
  741. Framework::Assembly::X);
  742. }
  743. }
  744. codeBlock.addBlock(&exprBlock,
  745. {},
  746. {lastResultSorage},
  747. {Framework::Assembly::SINGLE_FLOAT},
  748. 0,
  749. 0);
  750. Framework::Assembly::Operation jumpOp = Framework::Assembly::NOP;
  751. bool needConversion = false;
  752. if (op.isEqual(">"))
  753. {
  754. jumpOp = Framework::Assembly::JBE; // jump if below or equal
  755. }
  756. else if (op.isEqual("<"))
  757. {
  758. jumpOp = Framework::Assembly::JNB; // jump if not below
  759. }
  760. else if (op.isEqual(">="))
  761. {
  762. jumpOp = Framework::Assembly::JB; // jump if below
  763. }
  764. else if (op.isEqual("<="))
  765. {
  766. jumpOp = Framework::Assembly::JA; // jump if above
  767. }
  768. else if (op.isEqual("=="))
  769. {
  770. jumpOp = Framework::Assembly::JNE; // jump if not equal
  771. }
  772. else if (op.isEqual("!="))
  773. {
  774. jumpOp = Framework::Assembly::JE; // jump if equal
  775. }
  776. else
  777. {
  778. needConversion = true;
  779. if (op.isEqual(">i"))
  780. {
  781. jumpOp = Framework::Assembly::JLE; // jump if less or equal
  782. }
  783. else if (op.isEqual("<i"))
  784. {
  785. jumpOp = Framework::Assembly::JGE; // jump if greater or
  786. // equal
  787. }
  788. else if (op.isEqual(">=i"))
  789. {
  790. jumpOp = Framework::Assembly::JL; // jump if less
  791. }
  792. else if (op.isEqual("<=i"))
  793. {
  794. jumpOp = Framework::Assembly::JG; // jump if greater
  795. }
  796. else if (op.isEqual("==i"))
  797. {
  798. jumpOp = Framework::Assembly::JNE; // jump if not equal
  799. }
  800. else if (op.isEqual("!=i"))
  801. {
  802. jumpOp = Framework::Assembly::JE; // jump if equal
  803. }
  804. }
  805. if (needConversion)
  806. {
  807. codeBlock.addConversion(Framework::Assembly::RAX,
  808. lastResultSorage,
  809. Framework::Assembly::SINGLE_FLOAT,
  810. Framework::Assembly::LOWER32);
  811. codeBlock.addConversion(Framework::Assembly::RCX,
  812. currentResultSorage,
  813. Framework::Assembly::SINGLE_FLOAT,
  814. Framework::Assembly::LOWER32);
  815. codeBlock.addCompare(Framework::Assembly::RAX,
  816. Framework::Assembly::RCX,
  817. Framework::Assembly::LOWER32);
  818. }
  819. else
  820. {
  821. codeBlock.addCompare(lastResultSorage,
  822. currentResultSorage,
  823. Framework::Assembly::SINGLE_FLOAT);
  824. }
  825. codeBlock.addJump(jumpOp, "end_false");
  826. lastResultSorage = currentResultSorage;
  827. }
  828. }
  829. codeBlock.addMoveValue(Framework::Assembly::RAX, (char)1);
  830. codeBlock.addJump(Framework::Assembly::JMP, "end");
  831. codeBlock.defineJumpTarget("end_false");
  832. codeBlock.addMoveValue(Framework::Assembly::RAX, (char)0);
  833. codeBlock.defineJumpTarget("end");
  834. return codeBlock;
  835. }
  836. void JFloatOperatorBoolExpression::setOperator(Framework::Text op)
  837. {
  838. this->op = op;
  839. }
  840. Framework::Text JFloatOperatorBoolExpression::getOperator()
  841. {
  842. return op;
  843. }
  844. void JFloatOperatorBoolExpression::addValue(JFloatExpression* value)
  845. {
  846. values.add(value);
  847. }
  848. const Framework::RCArray<JFloatExpression>&
  849. JFloatOperatorBoolExpression::getValues() const
  850. {
  851. return values;
  852. }
  853. JFloatOperatorBoolExpressionFactory::JFloatOperatorBoolExpressionFactory()
  854. : SubTypeFactory()
  855. {}
  856. JFloatOperatorBoolExpression* JFloatOperatorBoolExpressionFactory::fromJson(
  857. Framework::JSON::JSONObject* zJson) const
  858. {
  859. JFloatOperatorBoolExpression* result = new JFloatOperatorBoolExpression();
  860. result->setOperator(zJson->zValue("operator")->asString()->getString());
  861. for (Framework::JSON::JSONValue* value :
  862. *zJson->zValue("values")->asArray())
  863. {
  864. result->addValue(
  865. Game::INSTANCE->zTypeRegistry()->fromJson<JFloatExpression>(value));
  866. }
  867. return result;
  868. }
  869. Framework::JSON::JSONObject* JFloatOperatorBoolExpressionFactory::toJsonObject(
  870. JFloatOperatorBoolExpression* zObject) const
  871. {
  872. Framework::JSON::JSONObject* result = new Framework::JSON::JSONObject();
  873. result->addValue(
  874. "operator", new Framework::JSON::JSONString(zObject->getOperator()));
  875. Framework::JSON::JSONArray* values = new Framework::JSON::JSONArray();
  876. for (JFloatExpression* expression : zObject->getValues())
  877. {
  878. values->addValue(
  879. Game::INSTANCE->zTypeRegistry()->toJson<JFloatExpression>(
  880. expression));
  881. }
  882. result->addValue("values", values);
  883. return result;
  884. }
  885. JSONObjectValidationBuilder*
  886. JFloatOperatorBoolExpressionFactory::addToValidator(
  887. JSONObjectValidationBuilder* builder) const
  888. {
  889. return builder->withRequiredString("operator")
  890. ->whichIsOneOf({">",
  891. "<",
  892. ">=",
  893. "<=",
  894. "==",
  895. "!=",
  896. "<i",
  897. ">i",
  898. ">=i",
  899. "<=i",
  900. "==i",
  901. "!=i"})
  902. ->finishString()
  903. ->withRequiredArray("values")
  904. ->addAcceptedTypeInArray(
  905. Game::INSTANCE->zTypeRegistry()->getValidator<JFloatExpression>())
  906. ->finishArray();
  907. }
  908. const char* JFloatOperatorBoolExpressionFactory::getTypeToken() const
  909. {
  910. return "comparsion";
  911. }
  912. JSpecificBlockBoolExpression::JSpecificBlockBoolExpression()
  913. : JBoolExpression(),
  914. filter(0),
  915. x(0),
  916. y(0),
  917. z(0)
  918. {}
  919. JSpecificBlockBoolExpression::~JSpecificBlockBoolExpression()
  920. {
  921. if (filter) filter->release();
  922. if (x) x->release();
  923. if (y) y->release();
  924. if (z) z->release();
  925. }
  926. bool JSpecificBlockBoolExpression::isValidPosition(
  927. int x, int y, Chunk* currentChunk)
  928. {
  929. return currentChunk
  930. && Game::getChunkCenter(x, y) == currentChunk->getCenter();
  931. }
  932. Framework::Assembly::AssemblyBlock& JSpecificBlockBoolExpression::buildAssembly(
  933. JExpressionMemory* zMemory)
  934. {
  935. Framework::Assembly::AssemblyBlock& xBlock = x->buildAssembly(zMemory);
  936. Framework::Assembly::AssemblyBlock& yBlock = y->buildAssembly(zMemory);
  937. Framework::Assembly::AssemblyBlock& zBlock = z->buildAssembly(zMemory);
  938. Framework::Assembly::FPRegister xTarget = Framework::Assembly::MM0;
  939. if (xBlock.isReplacementPossible(
  940. Framework::Assembly::MM0, Framework::Assembly::MM1))
  941. {
  942. xBlock.replaceRegister(
  943. Framework::Assembly::MM0, Framework::Assembly::MM1);
  944. xTarget = Framework::Assembly::MM1;
  945. }
  946. Framework::Assembly::FPRegister yTarget = Framework::Assembly::MM0;
  947. if (yBlock.isReplacementPossible(
  948. Framework::Assembly::MM0, Framework::Assembly::MM2))
  949. {
  950. yBlock.replaceRegister(
  951. Framework::Assembly::MM0, Framework::Assembly::MM2);
  952. yTarget = Framework::Assembly::MM2;
  953. }
  954. Framework::Assembly::FPRegister zTarget = Framework::Assembly::MM0;
  955. if (zBlock.isReplacementPossible(
  956. Framework::Assembly::MM0, Framework::Assembly::MM3))
  957. {
  958. zBlock.replaceRegister(
  959. Framework::Assembly::MM0, Framework::Assembly::MM3);
  960. zTarget = Framework::Assembly::MM3;
  961. }
  962. codeBlock.addBlock(&zBlock, {}, {}, {}, 0, &zTarget);
  963. codeBlock.addConversion(Framework::Assembly::R9,
  964. zTarget,
  965. Framework::Assembly::SINGLE_FLOAT,
  966. Framework::Assembly::LOWER32,
  967. 1);
  968. codeBlock.addTest(Framework::Assembly::R9,
  969. Framework::Assembly::R9,
  970. Framework::Assembly::LOWER32);
  971. codeBlock.addJump(Framework::Assembly::JL, "end_false");
  972. codeBlock.addCompare(Framework::Assembly::R9, WORLD_HEIGHT);
  973. codeBlock.addJump(Framework::Assembly::JGE, "end_false");
  974. codeBlock.addBlock(&yBlock, {Framework::Assembly::R9}, {}, {}, 0, &yTarget);
  975. codeBlock.addConversion(Framework::Assembly::R8,
  976. yTarget,
  977. Framework::Assembly::SINGLE_FLOAT,
  978. Framework::Assembly::LOWER32,
  979. 1);
  980. codeBlock.addBlock(&xBlock,
  981. {Framework::Assembly::R8, Framework::Assembly::R9},
  982. {},
  983. {},
  984. 0,
  985. &xTarget);
  986. codeBlock.addConversion(Framework::Assembly::RDX,
  987. xTarget,
  988. Framework::Assembly::SINGLE_FLOAT,
  989. Framework::Assembly::LOWER32,
  990. 1);
  991. codeBlock.addLoadAddress(this, Framework::Assembly::RCX);
  992. codeBlock.addPush(Framework::Assembly::RDX, Framework::Assembly::LOWER32);
  993. codeBlock.addPush(Framework::Assembly::R8, Framework::Assembly::LOWER32);
  994. codeBlock.addPush(Framework::Assembly::R9, Framework::Assembly::LOWER32);
  995. codeBlock.addLoadValue(
  996. (__int64*)zMemory->zzCurrentChunk(), Framework::Assembly::R9);
  997. codeBlock.addMemberCall<bool (JSpecificBlockBoolExpression::*)(
  998. int, int, Chunk*)>(&JSpecificBlockBoolExpression::isValidPosition,
  999. Framework::Assembly::INT_VALUE,
  1000. {Framework::Assembly::R9},
  1001. {});
  1002. codeBlock.addPop(Framework::Assembly::R9, Framework::Assembly::LOWER32);
  1003. codeBlock.addPop(Framework::Assembly::R8, Framework::Assembly::LOWER32);
  1004. codeBlock.addPop(Framework::Assembly::RDX, Framework::Assembly::LOWER32);
  1005. codeBlock.addTest(Framework::Assembly::RAX,
  1006. Framework::Assembly::RAX,
  1007. Framework::Assembly::LOWER8);
  1008. codeBlock.addJump(Framework::Assembly::JZ, "end");
  1009. codeBlock.addLoadValue(
  1010. (__int64*)zMemory->zzCurrentChunk(), Framework::Assembly::RCX);
  1011. codeBlock.addMemberCall<const Block* (Chunk::*)(int, int, int) const>(
  1012. &Chunk::zBlockConstWC,
  1013. Framework::Assembly::INT_VALUE,
  1014. {Framework::Assembly::RCX,
  1015. Framework::Assembly::RDX,
  1016. Framework::Assembly::R8,
  1017. Framework::Assembly::R9},
  1018. {});
  1019. codeBlock.addMoveValue(Framework::Assembly::RDX, Framework::Assembly::RAX);
  1020. codeBlock.addLoadValue((__int64*)&filter, Framework::Assembly::RCX);
  1021. codeBlock.addMemberCall<bool (BlockFilter::*)(const Block*) const>(
  1022. &BlockFilter::test,
  1023. Framework::Assembly::INT_VALUE,
  1024. {Framework::Assembly::RCX, Framework::Assembly::RDX},
  1025. {});
  1026. codeBlock.addTest(Framework::Assembly::RAX,
  1027. Framework::Assembly::RAX,
  1028. Framework::Assembly::LOWER8);
  1029. codeBlock.addJump(Framework::Assembly::JZ, "end");
  1030. codeBlock.addMoveValue(Framework::Assembly::RAX, (char)1);
  1031. codeBlock.addJump(Framework::Assembly::JMP, "end");
  1032. codeBlock.defineJumpTarget("end_false");
  1033. codeBlock.addMoveValue(Framework::Assembly::RAX, (char)0);
  1034. codeBlock.defineJumpTarget("end");
  1035. return codeBlock;
  1036. }
  1037. void JSpecificBlockBoolExpression::setFilter(BlockFilter* filter)
  1038. {
  1039. if (this->filter)
  1040. {
  1041. this->filter->release();
  1042. }
  1043. this->filter = filter;
  1044. }
  1045. BlockFilter* JSpecificBlockBoolExpression::zFilter() const
  1046. {
  1047. return filter;
  1048. }
  1049. void JSpecificBlockBoolExpression::setX(JFloatExpression* x)
  1050. {
  1051. if (this->x) this->x->release();
  1052. this->x = x;
  1053. }
  1054. JFloatExpression* JSpecificBlockBoolExpression::zX() const
  1055. {
  1056. return x;
  1057. }
  1058. void JSpecificBlockBoolExpression::setY(JFloatExpression* y)
  1059. {
  1060. if (this->y) this->y->release();
  1061. this->y = y;
  1062. }
  1063. JFloatExpression* JSpecificBlockBoolExpression::zY() const
  1064. {
  1065. return y;
  1066. }
  1067. void JSpecificBlockBoolExpression::setZ(JFloatExpression* z)
  1068. {
  1069. if (this->z) this->z->release();
  1070. this->z = z;
  1071. }
  1072. JFloatExpression* JSpecificBlockBoolExpression::zZ() const
  1073. {
  1074. return z;
  1075. }
  1076. JSpecificBlockBoolExpressionFactory::JSpecificBlockBoolExpressionFactory()
  1077. : SubTypeFactory()
  1078. {}
  1079. JSpecificBlockBoolExpression* JSpecificBlockBoolExpressionFactory::fromJson(
  1080. Framework::JSON::JSONObject* zJson) const
  1081. {
  1082. JSpecificBlockBoolExpression* result = new JSpecificBlockBoolExpression();
  1083. result->setFilter(Game::INSTANCE->zTypeRegistry()->fromJson<BlockFilter>(
  1084. zJson->zValue("condition")));
  1085. result->setX(Game::INSTANCE->zTypeRegistry()->fromJson<JFloatExpression>(
  1086. zJson->zValue("x")));
  1087. result->setY(Game::INSTANCE->zTypeRegistry()->fromJson<JFloatExpression>(
  1088. zJson->zValue("y")));
  1089. result->setZ(Game::INSTANCE->zTypeRegistry()->fromJson<JFloatExpression>(
  1090. zJson->zValue("z")));
  1091. return result;
  1092. }
  1093. Framework::JSON::JSONObject* JSpecificBlockBoolExpressionFactory::toJsonObject(
  1094. JSpecificBlockBoolExpression* zObject) const
  1095. {
  1096. Framework::JSON::JSONObject* result = new Framework::JSON::JSONObject();
  1097. result->addValue("condition",
  1098. Game::INSTANCE->zTypeRegistry()->toJson(zObject->zFilter()));
  1099. result->addValue(
  1100. "x", Game::INSTANCE->zTypeRegistry()->toJson(zObject->zX()));
  1101. result->addValue(
  1102. "y", Game::INSTANCE->zTypeRegistry()->toJson(zObject->zY()));
  1103. result->addValue(
  1104. "z", Game::INSTANCE->zTypeRegistry()->toJson(zObject->zZ()));
  1105. return result;
  1106. }
  1107. JSONObjectValidationBuilder*
  1108. JSpecificBlockBoolExpressionFactory::addToValidator(
  1109. JSONObjectValidationBuilder* builder) const
  1110. {
  1111. return builder
  1112. ->withRequiredAttribute("condition",
  1113. Game::INSTANCE->zTypeRegistry()->getValidator<BlockFilter>())
  1114. ->withRequiredAttribute("x",
  1115. Game::INSTANCE->zTypeRegistry()->getValidator<JFloatExpression>())
  1116. ->withRequiredAttribute("y",
  1117. Game::INSTANCE->zTypeRegistry()->getValidator<JFloatExpression>())
  1118. ->withRequiredAttribute("z",
  1119. Game::INSTANCE->zTypeRegistry()->getValidator<JFloatExpression>());
  1120. }
  1121. const char* JSpecificBlockBoolExpressionFactory::getTypeToken() const
  1122. {
  1123. return "specificBlockMatches";
  1124. }
  1125. JFirstBlockAboveBoolExpression::JFirstBlockAboveBoolExpression()
  1126. : JBoolExpression(),
  1127. filter(0),
  1128. maxDistance(0)
  1129. {}
  1130. JFirstBlockAboveBoolExpression::~JFirstBlockAboveBoolExpression()
  1131. {
  1132. if (filter) filter->release();
  1133. }
  1134. Framework::Assembly::AssemblyBlock&
  1135. JFirstBlockAboveBoolExpression::buildAssembly(JExpressionMemory* zMemory)
  1136. {
  1137. // load x into R12
  1138. codeBlock.addLoadValue(
  1139. zMemory->getFloatVariableP("x"), Framework::Assembly::MM0);
  1140. codeBlock.addConversion(Framework::Assembly::R12,
  1141. Framework::Assembly::MM0,
  1142. Framework::Assembly::SINGLE_FLOAT,
  1143. Framework::Assembly::LOWER32,
  1144. 1);
  1145. // load y into R13
  1146. codeBlock.addLoadValue(
  1147. zMemory->getFloatVariableP("y"), Framework::Assembly::MM0);
  1148. codeBlock.addConversion(Framework::Assembly::R13,
  1149. Framework::Assembly::MM0,
  1150. Framework::Assembly::SINGLE_FLOAT,
  1151. Framework::Assembly::LOWER32,
  1152. 1);
  1153. // load z into R14
  1154. codeBlock.addLoadValue(
  1155. zMemory->getFloatVariableP("z"), Framework::Assembly::MM0);
  1156. codeBlock.addConversion(Framework::Assembly::R14,
  1157. Framework::Assembly::MM0,
  1158. Framework::Assembly::SINGLE_FLOAT,
  1159. Framework::Assembly::LOWER32,
  1160. 1);
  1161. // load current chunk into R15
  1162. codeBlock.addLoadValue(
  1163. (__int64*)zMemory->zzCurrentChunk(), Framework::Assembly::R15);
  1164. if (maxDistance)
  1165. {
  1166. // calculate loop end
  1167. codeBlock.addMoveValue(
  1168. Framework::Assembly::RBX, Framework::Assembly::R14);
  1169. codeBlock.addAddition(Framework::Assembly::RBX, maxDistance + 1);
  1170. codeBlock.addCompare(Framework::Assembly::RBX, WORLD_HEIGHT);
  1171. codeBlock.addJump(Framework::Assembly::JL, "continue");
  1172. codeBlock.addMoveValue(Framework::Assembly::RBX, WORLD_HEIGHT);
  1173. codeBlock.defineJumpTarget("continue");
  1174. }
  1175. // begin loop to check above blocks
  1176. codeBlock.defineJumpTarget("loop_start");
  1177. // increment height
  1178. codeBlock.addAddition(
  1179. Framework::Assembly::R14, (char)1, Framework::Assembly::LOWER32);
  1180. // check if height is above loop end
  1181. if (maxDistance)
  1182. {
  1183. codeBlock.addCompare(Framework::Assembly::R14,
  1184. Framework::Assembly::RBX,
  1185. Framework::Assembly::LOWER32);
  1186. }
  1187. else
  1188. {
  1189. codeBlock.addCompare(Framework::Assembly::R14, WORLD_HEIGHT);
  1190. }
  1191. codeBlock.addJump(Framework::Assembly::JGE, "end_false");
  1192. // load block type at current position into RAX
  1193. codeBlock.addMoveValue(Framework::Assembly::RCX, Framework::Assembly::R15);
  1194. codeBlock.addMoveValue(Framework::Assembly::RDX, Framework::Assembly::R12);
  1195. codeBlock.addMoveValue(Framework::Assembly::R8, Framework::Assembly::R13);
  1196. codeBlock.addMoveValue(Framework::Assembly::R9, Framework::Assembly::R14);
  1197. if (maxDistance)
  1198. { // save loop end in RBX for later comparison
  1199. codeBlock.addPush(
  1200. Framework::Assembly::RBX, Framework::Assembly::LOWER32);
  1201. }
  1202. codeBlock.addMemberCall<int (Chunk::*)(int, int, int) const>(
  1203. &Chunk::getBlockTypeAtWC,
  1204. Framework::Assembly::INT_VALUE,
  1205. {Framework::Assembly::RCX,
  1206. Framework::Assembly::RDX,
  1207. Framework::Assembly::R8,
  1208. Framework::Assembly::R9},
  1209. {});
  1210. if (maxDistance)
  1211. {
  1212. // restore loop end from stack
  1213. codeBlock.addPop(
  1214. Framework::Assembly::RBX, Framework::Assembly::LOWER32);
  1215. }
  1216. // check if block type is 0 (NO_BLOCK) or 1 (AIR)
  1217. codeBlock.addCompare(Framework::Assembly::RAX, 1);
  1218. codeBlock.addJump(Framework::Assembly::JLE, "loop_start");
  1219. // end of loop
  1220. // load current block into RDX
  1221. codeBlock.addMoveValue(Framework::Assembly::RCX, Framework::Assembly::R15);
  1222. codeBlock.addMoveValue(Framework::Assembly::RDX, Framework::Assembly::R12);
  1223. codeBlock.addMoveValue(Framework::Assembly::R8, Framework::Assembly::R13);
  1224. codeBlock.addMoveValue(Framework::Assembly::R9, Framework::Assembly::R14);
  1225. codeBlock.addMemberCall<const Block* (Chunk::*)(int, int, int) const>(
  1226. &Chunk::zBlockConstWC,
  1227. Framework::Assembly::INT_VALUE,
  1228. {Framework::Assembly::RCX,
  1229. Framework::Assembly::RDX,
  1230. Framework::Assembly::R8,
  1231. Framework::Assembly::R9},
  1232. {});
  1233. codeBlock.addMoveValue(Framework::Assembly::RDX, Framework::Assembly::RAX);
  1234. // load filter into RCX
  1235. codeBlock.addLoadValue((__int64*)&filter, Framework::Assembly::RCX);
  1236. // check filter condition
  1237. codeBlock.addMemberCall<bool (BlockFilter::*)(const Block*) const>(
  1238. &BlockFilter::test,
  1239. Framework::Assembly::INT_VALUE,
  1240. {Framework::Assembly::RCX, Framework::Assembly::RDX},
  1241. {});
  1242. codeBlock.addJump(Framework::Assembly::JMP, "end");
  1243. codeBlock.defineJumpTarget("end_false");
  1244. codeBlock.addMoveValue(Framework::Assembly::RAX, (char)0);
  1245. codeBlock.defineJumpTarget("end");
  1246. return codeBlock;
  1247. }
  1248. void JFirstBlockAboveBoolExpression::setFilter(BlockFilter* filter)
  1249. {
  1250. if (this->filter)
  1251. {
  1252. this->filter->release();
  1253. }
  1254. this->filter = filter;
  1255. }
  1256. BlockFilter* JFirstBlockAboveBoolExpression::zFilter() const
  1257. {
  1258. return filter;
  1259. }
  1260. void JFirstBlockAboveBoolExpression::setMaxDistance(short maxDistance)
  1261. {
  1262. this->maxDistance = maxDistance;
  1263. }
  1264. short JFirstBlockAboveBoolExpression::getMaxDistance() const
  1265. {
  1266. return maxDistance;
  1267. }
  1268. JFirstBlockAboveBoolExpressionFactory::JFirstBlockAboveBoolExpressionFactory()
  1269. : SubTypeFactory()
  1270. {}
  1271. JFirstBlockAboveBoolExpression* JFirstBlockAboveBoolExpressionFactory::fromJson(
  1272. Framework::JSON::JSONObject* zJson) const
  1273. {
  1274. JFirstBlockAboveBoolExpression* result
  1275. = new JFirstBlockAboveBoolExpression();
  1276. result->setFilter(Game::INSTANCE->zTypeRegistry()->fromJson<BlockFilter>(
  1277. zJson->zValue("condition")));
  1278. if (zJson->hasValue("maxDistance"))
  1279. {
  1280. result->setMaxDistance(
  1281. (short)zJson->zValue("maxDistance")->asNumber()->getNumber());
  1282. }
  1283. return result;
  1284. }
  1285. Framework::JSON::JSONObject*
  1286. JFirstBlockAboveBoolExpressionFactory::toJsonObject(
  1287. JFirstBlockAboveBoolExpression* zObject) const
  1288. {
  1289. Framework::JSON::JSONObject* result = new Framework::JSON::JSONObject();
  1290. result->addValue("condition",
  1291. Game::INSTANCE->zTypeRegistry()->toJson(zObject->zFilter()));
  1292. if (zObject->getMaxDistance())
  1293. {
  1294. result->addValue("maxDistance",
  1295. new Framework::JSON::JSONNumber(zObject->getMaxDistance()));
  1296. }
  1297. return result;
  1298. }
  1299. JSONObjectValidationBuilder*
  1300. JFirstBlockAboveBoolExpressionFactory::addToValidator(
  1301. JSONObjectValidationBuilder* builder) const
  1302. {
  1303. return builder
  1304. ->withRequiredAttribute("condition",
  1305. Game::INSTANCE->zTypeRegistry()->getValidator<BlockFilter>())
  1306. ->withOptionalNumber("maxDistance")
  1307. ->whichIsGreaterThen(0)
  1308. ->whichIsLessThen(WORLD_HEIGHT)
  1309. ->finishNumber();
  1310. }
  1311. const char* JFirstBlockAboveBoolExpressionFactory::getTypeToken() const
  1312. {
  1313. return "firstBlockAboveMatches";
  1314. }