JsonExpression.cpp 42 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387
  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.getEintragAnzahl())
  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.istGleich("+"))
  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.istGleich("-"))
  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.istGleich("*"))
  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.istGleich("/"))
  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.getEintragAnzahl())
  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.istGleich("&&"))
  625. {
  626. codeBlock.addAnd(Framework::Assembly::RAX,
  627. Framework::Assembly::RCX,
  628. Framework::Assembly::LOWER8);
  629. }
  630. else if (op.istGleich("||"))
  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.istGleich(">"))
  753. {
  754. jumpOp = Framework::Assembly::JBE; // jump if below or equal
  755. }
  756. else if (op.istGleich("<"))
  757. {
  758. jumpOp = Framework::Assembly::JNB; // jump if not below
  759. }
  760. else if (op.istGleich(">="))
  761. {
  762. jumpOp = Framework::Assembly::JB; // jump if below
  763. }
  764. else if (op.istGleich("<="))
  765. {
  766. jumpOp = Framework::Assembly::JA; // jump if above
  767. }
  768. else if (op.istGleich("=="))
  769. {
  770. jumpOp = Framework::Assembly::JNE; // jump if not equal
  771. }
  772. else if (op.istGleich("!="))
  773. {
  774. jumpOp = Framework::Assembly::JE; // jump if equal
  775. }
  776. else
  777. {
  778. needConversion = true;
  779. if (op.istGleich(">i"))
  780. {
  781. jumpOp = Framework::Assembly::JLE; // jump if less or equal
  782. }
  783. else if (op.istGleich("<i"))
  784. {
  785. jumpOp = Framework::Assembly::JGE; // jump if greater or
  786. // equal
  787. }
  788. else if (op.istGleich(">=i"))
  789. {
  790. jumpOp = Framework::Assembly::JL; // jump if less
  791. }
  792. else if (op.istGleich("<=i"))
  793. {
  794. jumpOp = Framework::Assembly::JG; // jump if greater
  795. }
  796. else if (op.istGleich("==i"))
  797. {
  798. jumpOp = Framework::Assembly::JNE; // jump if not equal
  799. }
  800. else if (op.istGleich("!=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. {}
  1129. JFirstBlockAboveBoolExpression::~JFirstBlockAboveBoolExpression()
  1130. {
  1131. if (filter) filter->release();
  1132. }
  1133. Framework::Assembly::AssemblyBlock&
  1134. JFirstBlockAboveBoolExpression::buildAssembly(JExpressionMemory* zMemory)
  1135. {
  1136. // load x into R12
  1137. codeBlock.addLoadValue(
  1138. zMemory->getFloatVariableP("x"), Framework::Assembly::MM0);
  1139. codeBlock.addConversion(Framework::Assembly::R12,
  1140. Framework::Assembly::MM0,
  1141. Framework::Assembly::SINGLE_FLOAT,
  1142. Framework::Assembly::LOWER32,
  1143. 1);
  1144. // load y into R13
  1145. codeBlock.addLoadValue(
  1146. zMemory->getFloatVariableP("y"), Framework::Assembly::MM0);
  1147. codeBlock.addConversion(Framework::Assembly::R13,
  1148. Framework::Assembly::MM0,
  1149. Framework::Assembly::SINGLE_FLOAT,
  1150. Framework::Assembly::LOWER32,
  1151. 1);
  1152. // load z into R14
  1153. codeBlock.addLoadValue(
  1154. zMemory->getFloatVariableP("z"), Framework::Assembly::MM0);
  1155. codeBlock.addConversion(Framework::Assembly::R14,
  1156. Framework::Assembly::MM0,
  1157. Framework::Assembly::SINGLE_FLOAT,
  1158. Framework::Assembly::LOWER32,
  1159. 1);
  1160. // load current chunk into R15
  1161. codeBlock.addLoadValue(
  1162. (__int64*)zMemory->zzCurrentChunk(), Framework::Assembly::R15);
  1163. // begin loop to check above blocks
  1164. codeBlock.defineJumpTarget("loop_start");
  1165. // increment height
  1166. codeBlock.addAddition(Framework::Assembly::R14, (char)1);
  1167. // check if height is above world height
  1168. codeBlock.addCompare(Framework::Assembly::R14, WORLD_HEIGHT);
  1169. codeBlock.addJump(Framework::Assembly::JGE, "end_false");
  1170. // load block type at current position into RAX
  1171. codeBlock.addMoveValue(Framework::Assembly::RCX, Framework::Assembly::R15);
  1172. codeBlock.addMoveValue(Framework::Assembly::RDX, Framework::Assembly::R12);
  1173. codeBlock.addMoveValue(Framework::Assembly::R8, Framework::Assembly::R13);
  1174. codeBlock.addMoveValue(Framework::Assembly::R9, Framework::Assembly::R14);
  1175. codeBlock.addMemberCall<int (Chunk::*)(int, int, int) const>(
  1176. &Chunk::getBlockTypeAtWC,
  1177. Framework::Assembly::INT_VALUE,
  1178. {Framework::Assembly::RCX,
  1179. Framework::Assembly::RDX,
  1180. Framework::Assembly::R8,
  1181. Framework::Assembly::R9},
  1182. {});
  1183. // check if block type is 0 (NO_BLOCK) or 1 (AIR)
  1184. codeBlock.addCompare(Framework::Assembly::RAX, 1);
  1185. codeBlock.addJump(Framework::Assembly::JLE, "loop_start");
  1186. // end of loop
  1187. // load current block into RDX
  1188. codeBlock.addMoveValue(Framework::Assembly::RCX, Framework::Assembly::R15);
  1189. codeBlock.addMoveValue(Framework::Assembly::RDX, Framework::Assembly::R12);
  1190. codeBlock.addMoveValue(Framework::Assembly::R8, Framework::Assembly::R13);
  1191. codeBlock.addMoveValue(Framework::Assembly::R9, Framework::Assembly::R14);
  1192. codeBlock.addMemberCall<const Block* (Chunk::*)(int, int, int) const>(
  1193. &Chunk::zBlockConstWC,
  1194. Framework::Assembly::INT_VALUE,
  1195. {Framework::Assembly::RCX,
  1196. Framework::Assembly::RDX,
  1197. Framework::Assembly::R8,
  1198. Framework::Assembly::R9},
  1199. {});
  1200. codeBlock.addMoveValue(Framework::Assembly::RDX, Framework::Assembly::RAX);
  1201. // load filter into RCX
  1202. codeBlock.addLoadValue((__int64*)&filter, Framework::Assembly::RCX);
  1203. // check filter condition
  1204. codeBlock.addMemberCall<bool (BlockFilter::*)(const Block*) const>(
  1205. &BlockFilter::test,
  1206. Framework::Assembly::INT_VALUE,
  1207. {Framework::Assembly::RCX, Framework::Assembly::RDX},
  1208. {});
  1209. codeBlock.addJump(Framework::Assembly::JMP, "end");
  1210. codeBlock.defineJumpTarget("end_false");
  1211. codeBlock.addMoveValue(Framework::Assembly::RAX, (char)0);
  1212. codeBlock.defineJumpTarget("end");
  1213. return codeBlock;
  1214. }
  1215. void JFirstBlockAboveBoolExpression::setFilter(BlockFilter* filter)
  1216. {
  1217. if (this->filter)
  1218. {
  1219. this->filter->release();
  1220. }
  1221. this->filter = filter;
  1222. }
  1223. BlockFilter* JFirstBlockAboveBoolExpression::zFilter() const
  1224. {
  1225. return filter;
  1226. }
  1227. JFirstBlockAboveBoolExpressionFactory::JFirstBlockAboveBoolExpressionFactory()
  1228. : SubTypeFactory()
  1229. {}
  1230. JFirstBlockAboveBoolExpression* JFirstBlockAboveBoolExpressionFactory::fromJson(
  1231. Framework::JSON::JSONObject* zJson) const
  1232. {
  1233. JFirstBlockAboveBoolExpression* result
  1234. = new JFirstBlockAboveBoolExpression();
  1235. result->setFilter(Game::INSTANCE->zTypeRegistry()->fromJson<BlockFilter>(
  1236. zJson->zValue("condition")));
  1237. return result;
  1238. }
  1239. Framework::JSON::JSONObject*
  1240. JFirstBlockAboveBoolExpressionFactory::toJsonObject(
  1241. JFirstBlockAboveBoolExpression* zObject) const
  1242. {
  1243. Framework::JSON::JSONObject* result = new Framework::JSON::JSONObject();
  1244. result->addValue("condition",
  1245. Game::INSTANCE->zTypeRegistry()->toJson(zObject->zFilter()));
  1246. return result;
  1247. }
  1248. JSONObjectValidationBuilder*
  1249. JFirstBlockAboveBoolExpressionFactory::addToValidator(
  1250. JSONObjectValidationBuilder* builder) const
  1251. {
  1252. return builder->withRequiredAttribute("condition",
  1253. Game::INSTANCE->zTypeRegistry()->getValidator<BlockFilter>());
  1254. }
  1255. const char* JFirstBlockAboveBoolExpressionFactory::getTypeToken() const
  1256. {
  1257. return "firstBlockAboveMatches";
  1258. }