BsCmdEditPlainFieldGO.h 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. #pragma once
  2. #include "BsEditorPrerequisites.h"
  3. #include "BsEditorCommand.h"
  4. #include "BsUndoRedo.h"
  5. namespace BansheeEditor
  6. {
  7. // TODO - This is only valid for plain field types. Add something similar for pointers and/or arrays?
  8. template<class T>
  9. class CmdEditPlainFieldGO : public EditorCommand
  10. {
  11. public:
  12. ~CmdEditPlainFieldGO()
  13. {
  14. if(mNewData != nullptr)
  15. cm_free(mNewData);
  16. if(mOldData != nullptr)
  17. cm_free(mOldData);
  18. }
  19. static void execute(const CM::GameObjectHandleBase& gameObject, const CM::String& fieldName, const T& fieldValue)
  20. {
  21. // Register command and commit it
  22. CmdEditPlainFieldGO* command = new (cm_alloc<CmdEditPlainFieldGO>()) CmdEditPlainFieldGO(gameObject, fieldName, fieldValue);
  23. UndoRedo::instance().registerCommand(command);
  24. command->commit();
  25. }
  26. void commit()
  27. {
  28. if(mGameObject.isDestroyed())
  29. return;
  30. T fieldValue;
  31. CM::RTTIPlainType<T>::fromMemory(fieldValue, (char*)mNewData);
  32. CM::RTTITypeBase* rtti = mGameObject->getRTTI();
  33. rtti->setPlainValue(mGameObject.get(), mFieldName, fieldValue);
  34. }
  35. void revert()
  36. {
  37. if(mGameObject.isDestroyed())
  38. return;
  39. T fieldValue;
  40. CM::RTTIPlainType<T>::fromMemory(fieldValue, (char*)mOldData);
  41. CM::RTTITypeBase* rtti = mGameObject->getRTTI();
  42. rtti->setPlainValue(mGameObject.get(), mFieldName, fieldValue);
  43. }
  44. private:
  45. friend class UndoRedo;
  46. CmdEditPlainFieldGO(const CM::GameObjectHandleBase& gameObject, const CM::String& fieldName, const T& fieldValue)
  47. :mGameObject(gameObject), mFieldName(fieldName), mNewData(nullptr), mOldData(nullptr)
  48. {
  49. // Convert new value to bytes
  50. CM::UINT32 newDataNumBytes = CM::RTTIPlainType<T>::getDynamicSize(fieldValue);
  51. mNewData = CM::cm_alloc(newDataNumBytes);
  52. CM::RTTIPlainType<T>::toMemory(fieldValue, (char*)mNewData);
  53. // Get old value and also convert it to bytes
  54. CM::String oldFieldValue;
  55. gameObject->getRTTI()->getPlainValue(gameObject.get(), fieldName, oldFieldValue);
  56. CM::UINT32 oldDataNumBytes = CM::RTTIPlainType<T>::getDynamicSize(oldFieldValue);
  57. mOldData = cm_alloc(oldDataNumBytes);
  58. CM::RTTIPlainType<T>::toMemory(oldFieldValue, (char*)mOldData);
  59. }
  60. CM::GameObjectHandleBase mGameObject;
  61. CM::String mFieldName;
  62. void* mNewData;
  63. void* mOldData;
  64. };
  65. }