Merge branch 'main' into Atom/dmcdiar/ATOM-15517
commit
d63edf9b84
@ -1,22 +1,35 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="323px" height="98px" viewBox="0 0 323 98" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<title>Group 12</title>
|
||||
<defs>
|
||||
<polygon id="path-1" points="0 97.741 322.084 97.741 322.084 0 0 0"></polygon>
|
||||
</defs>
|
||||
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="Group-12" transform="translate(0.000000, 0.000000)">
|
||||
<path d="M99.7068,20.425 C91.1008,11.686 79.6658,6.841 67.5068,6.782 L67.2838,6.781 C62.9678,6.781 58.7408,7.396 54.6908,8.566 L54.6908,25.339 C58.5158,23.54 62.6988,22.563 67.0218,22.517 C67.1388,22.516 67.2538,22.515 67.3698,22.515 C75.1318,22.515 82.4608,25.519 88.0388,30.996 C93.7828,36.635 96.9708,44.124 97.0168,52.084 C97.0628,60.037 93.9658,67.554 88.2968,73.251 C82.6908,78.884 75.2578,82 67.3558,82.025 L67.2718,82.025 C59.4228,82.025 51.9878,78.959 46.3368,73.393 C40.6918,67.833 37.5578,60.397 37.5108,52.453 C37.4888,48.659 38.1798,44.975 39.5088,41.546 L23.0748,41.546 C19.4908,56.362 23.4348,72.648 34.9328,84.219 C43.5408,92.882 54.9608,97.683 67.0878,97.738 L67.3028,97.738 L67.3058,97.738 C79.3458,97.738 90.7008,93.045 99.2768,84.524 C107.8718,75.984 112.6488,64.62 112.7288,52.524 C112.8088,40.435 108.1838,29.035 99.7068,20.425" id="Fill-1" fill="#FFFFFF"></path>
|
||||
<path d="M175.6326,27.8629 C175.6326,33.3889 173.9586,38.0879 170.6116,41.9599 C167.2646,45.8319 162.5656,48.4939 156.5146,49.9459 L156.5146,50.3089 C163.6536,51.1969 169.0586,53.3629 172.7296,56.8129 C176.3996,60.2619 178.2356,64.9099 178.2356,70.7579 C178.2356,79.2689 175.1496,85.8939 168.9786,90.6319 C162.8076,95.3719 153.9936,97.7409 142.5386,97.7409 C132.9386,97.7409 124.4286,96.1489 117.0076,92.9609 L117.0076,77.0489 C120.4356,78.7839 124.2076,80.1959 128.3216,81.2839 C132.4356,82.3729 136.5096,82.9179 140.5426,82.9179 C146.7146,82.9179 151.2716,81.8699 154.2156,79.7719 C157.1596,77.6749 158.6326,74.3079 158.6326,69.6679 C158.6326,65.5139 156.9386,62.5699 153.5506,60.8349 C150.1626,59.1009 144.7576,58.2329 137.3366,58.2329 L130.6206,58.2329 L130.6206,43.8939 L137.4576,43.8939 C144.3146,43.8939 149.3246,42.9979 152.4916,41.2019 C155.6576,39.4079 157.2406,36.3319 157.2406,31.9759 C157.2406,25.2809 153.0456,21.9329 144.6566,21.9329 C141.7526,21.9329 138.7986,22.4169 135.7936,23.3849 C132.7886,24.3529 129.4506,26.0279 125.7806,28.4069 L117.1306,15.5199 C125.1956,9.7119 134.8166,6.8079 145.9886,6.8079 C155.1446,6.8079 162.3736,8.6639 167.6786,12.3739 C172.9806,16.0869 175.6326,21.2499 175.6326,27.8629" id="Fill-3" fill="#FFFFFF"></path>
|
||||
<path d="M241.8563,51.9425 C241.8563,32.9455 233.4653,23.4465 216.6883,23.4465 L206.7053,23.4465 L206.7053,81.0435 L214.7523,81.0435 C232.8213,81.0435 241.8563,71.3435 241.8563,51.9425 M261.3363,51.4595 C261.3363,66.0195 257.1933,77.1715 248.9043,84.9165 C240.6153,92.6605 228.6463,96.5325 212.9973,96.5325 L187.9503,96.5325 L187.9503,8.0815 L215.7193,8.0815 C230.1593,8.0815 241.3723,11.8925 249.3583,19.5155 C257.3433,27.1365 261.3363,37.7855 261.3363,51.4595" id="Fill-5" fill="#FFFFFF"></path>
|
||||
<mask id="mask-2" fill="white">
|
||||
<use xlink:href="#path-1"></use>
|
||||
</mask>
|
||||
<g id="Clip-8"></g>
|
||||
<polygon id="Fill-7" fill="#FFFFFF" mask="url(#mask-2)" points="23.185 30.421 45.046 30.421 45.046 8.56 23.185 8.56"></polygon>
|
||||
<polygon id="Fill-9" fill="#FFFFFF" mask="url(#mask-2)" points="5.251 9.038 14.289 9.038 14.289 0 5.251 0"></polygon>
|
||||
<polygon id="Fill-10" fill="#FFFFFF" mask="url(#mask-2)" points="0 36.195 14.18 36.195 14.18 22.015 0 22.015"></polygon>
|
||||
<polygon id="Fill-11" fill="#FFFFFF" mask="url(#mask-2)" points="322.0838 96.4337 271.0538 96.4337 271.0538 7.8287 322.0838 7.8287 322.0838 23.2227 289.8418 23.2227 289.8418 42.6767 319.8418 42.6767 319.8418 58.0707 289.8418 58.0707 289.8418 80.9187 322.0838 80.9187"></polygon>
|
||||
<svg width="350px" height="133px" viewBox="0 0 350 133" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<title>Artboard</title>
|
||||
<g id="Artboard" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="O3DE-Logo-with-WorkMark-REV-Mono" transform="translate(-0.060000, 0.000000)" fill="#FFFFFF">
|
||||
<g id="Group-3" transform="translate(25.446000, 117.517000)">
|
||||
<path d="M1.833,7.614 C1.833,9.618 2.262,11.139 3.121,12.175 C3.979,13.211 5.226,13.729 6.863,13.729 C8.511,13.729 9.758,13.212 10.599,12.18 C11.441,11.146 11.862,9.625 11.862,7.614 C11.862,5.623 11.443,4.113 10.604,3.083 C9.766,2.055 8.525,1.539 6.883,1.539 C5.234,1.539 3.979,2.057 3.121,3.093 C2.262,4.129 1.833,5.637 1.833,7.614 Z M13.694,7.614 C13.694,9.983 13.092,11.846 11.887,13.202 C10.683,14.559 9.007,15.237 6.863,15.237 C4.67,15.237 2.979,14.571 1.787,13.237 C0.596,11.904 3.55271368e-15,10.023 3.55271368e-15,7.594 C3.55271368e-15,5.184 0.597,3.315 1.792,1.989 C2.986,0.663 4.683,0 6.883,0 C9.022,0 10.692,0.676 11.892,2.025 C13.095,3.375 13.694,5.238 13.694,7.614 L13.694,7.614 Z" id="Fill-1"></path>
|
||||
</g>
|
||||
<path d="M55.659,125.252 L57.216,125.252 C58.75,125.252 59.86,125.005 60.546,124.513 C61.231,124.02 61.574,123.231 61.574,122.144 C61.574,121.165 61.251,120.436 60.606,119.956 C59.961,119.478 58.958,119.239 57.593,119.239 L55.659,119.239 L55.659,125.252 Z M63.366,122.063 C63.366,123.561 62.852,124.714 61.823,125.521 C60.795,126.327 59.324,126.731 57.41,126.731 L55.659,126.731 L55.659,132.551 L53.927,132.551 L53.927,117.749 L57.786,117.749 C61.506,117.749 63.366,119.188 63.366,122.063 L63.366,122.063 Z" id="Fill-4"></path>
|
||||
<polyline id="Fill-5" points="86.247 132.551 77.949 132.551 77.949 117.749 86.247 117.749 86.247 119.279 79.681 119.279 79.681 124.047 85.849 124.047 85.849 125.566 79.681 125.566 79.681 131.013 86.247 131.013 86.247 132.551"></polyline>
|
||||
<g id="Group-9" transform="translate(101.016000, 117.537000)">
|
||||
<path d="M11.628,15.014 L9.651,15.014 L1.517,2.592 L1.436,2.592 C1.544,4.05 1.599,5.387 1.599,6.602 L1.599,15.014 L-1.42108547e-14,15.014 L-1.42108547e-14,0.212 L1.954,0.212 L10.069,12.584 L10.151,12.584 C10.137,12.403 10.106,11.817 10.059,10.828 C10.011,9.839 9.995,9.133 10.008,8.707 L10.008,0.212 L11.628,0.212 L11.628,15.014" id="Fill-6"></path>
|
||||
<path d="M56.235,3.696 C56.235,4.64 55.968,5.413 55.436,6.014 C54.902,6.616 54.147,7.016 53.169,7.219 L53.169,7.3 C54.364,7.449 55.251,7.827 55.828,8.434 C56.404,9.041 56.693,9.837 56.693,10.823 C56.693,12.234 56.201,13.319 55.216,14.079 C54.232,14.837 52.834,15.217 51.022,15.217 C50.234,15.217 49.513,15.159 48.858,15.039 C48.203,14.922 47.567,14.714 46.949,14.417 L46.949,12.818 C47.594,13.135 48.281,13.376 49.011,13.541 C49.741,13.707 50.431,13.789 51.083,13.789 C53.655,13.789 54.942,12.788 54.942,10.783 C54.942,8.987 53.522,8.089 50.685,8.089 L49.219,8.089 L49.219,6.642 L50.707,6.642 C51.866,6.642 52.787,6.387 53.465,5.877 C54.144,5.369 54.483,4.661 54.483,3.756 C54.483,3.034 54.234,2.467 53.735,2.055 C53.236,1.644 52.559,1.438 51.704,1.438 C51.052,1.438 50.438,1.526 49.861,1.702 C49.284,1.877 48.626,2.201 47.886,2.673 L47.031,1.539 C47.642,1.06 48.345,0.683 49.144,0.411 C49.94,0.136 50.78,1.42108547e-14 51.663,1.42108547e-14 C53.109,1.42108547e-14 54.232,0.33 55.033,0.987 C55.834,1.646 56.235,2.548 56.235,3.696" id="Fill-8"></path>
|
||||
</g>
|
||||
<path d="M182.497,125.07 C182.497,123.14 182.009,121.685 181.035,120.706 C180.061,119.727 178.614,119.239 176.693,119.239 L174.178,119.239 L174.178,131.064 L176.286,131.064 C178.349,131.064 179.9,130.56 180.939,129.55 C181.976,128.541 182.497,127.048 182.497,125.07 Z M184.329,125.009 C184.329,127.452 183.662,129.321 182.329,130.613 C180.995,131.906 179.076,132.551 176.571,132.551 L172.447,132.551 L172.447,117.749 L177.008,117.749 C179.323,117.749 181.122,118.388 182.405,119.663 C183.687,120.94 184.329,122.721 184.329,125.009 L184.329,125.009 Z" id="Fill-10"></path>
|
||||
<polyline id="Fill-11" points="228.264 132.551 219.965 132.551 219.965 117.749 228.264 117.749 228.264 119.279 221.697 119.279 221.697 124.047 227.867 124.047 227.867 125.566 221.697 125.566 221.697 131.013 228.264 131.013 228.264 132.551"></polyline>
|
||||
<g id="Group-15" transform="translate(243.032000, 117.537000)">
|
||||
<path d="M11.629,15.014 L9.652,15.014 L1.517,2.592 L1.436,2.592 C1.545,4.05 1.599,5.387 1.599,6.602 L1.599,15.014 L2.84217094e-14,15.014 L2.84217094e-14,0.212 L1.955,0.212 L10.07,12.584 L10.151,12.584 C10.138,12.403 10.107,11.817 10.059,10.828 C10.011,9.839 9.996,9.133 10.008,8.707 L10.008,0.212 L11.629,0.212 L11.629,15.014" id="Fill-12"></path>
|
||||
<path d="M33.736,7.259 L38.796,7.259 L38.796,14.458 C38.008,14.707 37.208,14.897 36.393,15.025 C35.578,15.154 34.634,15.217 33.563,15.217 C31.309,15.217 29.554,14.551 28.299,13.217 C27.044,11.884 26.415,10.017 26.415,7.614 C26.415,6.076 26.726,4.727 27.346,3.569 C27.968,2.413 28.862,1.528 30.03,0.916 C31.197,0.306 32.564,1.42108547e-14 34.133,1.42108547e-14 C35.721,1.42108547e-14 37.201,0.29 38.573,0.872 L37.9,2.39 C36.555,1.823 35.263,1.539 34.021,1.539 C32.209,1.539 30.794,2.076 29.776,3.149 C28.757,4.222 28.248,5.71 28.248,7.614 C28.248,9.612 28.738,11.126 29.719,12.16 C30.7,13.192 32.14,13.709 34.042,13.709 C35.073,13.709 36.081,13.59 37.066,13.354 L37.066,8.798 L33.736,8.798 L33.736,7.259" id="Fill-14"></path>
|
||||
</g>
|
||||
<polygon id="Fill-16" points="296.871 132.551 298.602 132.551 298.602 117.749 296.871 117.749"></polygon>
|
||||
<path d="M325.781,132.551 L323.805,132.551 L315.67,120.129 L315.588,120.129 C315.698,121.587 315.751,122.924 315.751,124.139 L315.751,132.551 L314.153,132.551 L314.153,117.749 L316.108,117.749 L324.223,130.121 L324.304,130.121 C324.29,129.94 324.259,129.354 324.212,128.365 C324.164,127.376 324.148,126.67 324.162,126.244 L324.162,117.749 L325.781,117.749 L325.781,132.551" id="Fill-17"></path>
|
||||
<polyline id="Fill-18" points="349.64 132.551 341.341 132.551 341.341 117.749 349.64 117.749 349.64 119.279 343.073 119.279 343.073 124.047 349.243 124.047 349.243 125.566 343.073 125.566 343.073 131.013 349.64 131.013 349.64 132.551"></polyline>
|
||||
<path d="M187.562,26.549 C187.562,32.293 185.822,37.178 182.341,41.203 C178.861,45.228 173.977,47.995 167.687,49.505 L167.687,49.882 C175.109,50.805 180.727,53.058 184.543,56.643 C188.358,60.228 190.266,65.061 190.266,71.14 C190.266,79.989 187.059,86.875 180.644,91.801 C174.228,96.728 165.067,99.191 153.159,99.191 C143.18,99.191 134.332,97.535 126.618,94.222 L126.618,77.681 C130.181,79.485 134.102,80.951 138.379,82.083 C142.656,83.216 146.891,83.781 151.083,83.781 C157.498,83.781 162.236,82.693 165.297,80.511 C168.358,78.331 169.889,74.831 169.889,70.008 C169.889,65.69 168.128,62.63 164.606,60.825 C161.083,59.023 155.464,58.121 147.75,58.121 L140.769,58.121 L140.769,43.216 L147.876,43.216 C155.004,43.216 160.213,42.283 163.505,40.417 C166.796,38.551 168.442,35.354 168.442,30.825 C168.442,23.865 164.081,20.385 155.36,20.385 C152.341,20.385 149.269,20.888 146.146,21.894 C143.022,22.901 139.552,24.642 135.737,27.115 L126.744,13.718 C135.129,7.68 145.129,4.661 156.744,4.661 C166.262,4.661 173.777,6.591 179.291,10.448 C184.804,14.305 187.562,19.673 187.562,26.549" id="Fill-19"></path>
|
||||
<path d="M261.093,51.538 C261.093,31.236 252.127,21.084 234.196,21.084 L223.527,21.084 L223.527,82.639 L232.126,82.639 C251.437,82.639 261.093,72.273 261.093,51.538 Z M281.913,51.021 C281.913,66.583 277.484,78.5 268.625,86.777 C259.768,95.053 246.976,99.191 230.251,99.191 L203.483,99.191 L203.483,4.661 L233.162,4.661 C248.592,4.661 260.576,8.735 269.111,16.882 C277.646,25.029 281.913,36.408 281.913,51.021 L281.913,51.021 Z" id="Fill-20"></path>
|
||||
<polyline id="Fill-21" points="349.64 99.191 295.198 99.191 295.198 4.661 349.64 4.661 349.64 21.084 315.242 21.084 315.242 41.84 347.247 41.84 347.247 58.262 315.242 58.262 315.242 82.639 349.64 82.639 349.64 99.191"></polyline>
|
||||
<path d="M72.71,4.661 C68.177,4.661 63.799,5.313 59.648,6.505 L59.648,24.983 C63.596,23.066 68.027,21.988 72.71,21.988 C89.245,21.988 102.648,35.392 102.648,51.926 C102.648,68.46 89.245,81.865 72.71,81.865 C56.176,81.865 42.773,68.46 42.773,51.926 C42.773,47.99 43.539,44.237 44.92,40.794 L26.777,40.794 C25.914,44.365 25.446,48.09 25.446,51.926 C25.446,78.03 46.607,99.191 72.71,99.191 C98.814,99.191 119.976,78.03 119.976,51.926 C119.976,25.823 98.814,4.661 72.71,4.661" id="Fill-22"></path>
|
||||
<g id="Group-27">
|
||||
<polyline id="Fill-23" points="53.023 29.655 30.237 34.445 25.447 11.66 48.232 6.869 53.023 29.655"></polyline>
|
||||
<polygon id="Fill-25" points="11.806 9.313 21.12 9.313 21.12 0 11.806 0"></polygon>
|
||||
<polyline id="Fill-26" points="14.761 31.326 0 27.533 3.793 12.773 18.554 16.566 14.761 31.326"></polyline>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 3.9 KiB After Width: | Height: | Size: 8.9 KiB |
@ -1,113 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>ProjectSettingsClass</class>
|
||||
<widget class="QWidget" name="ProjectSettingsClass">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>782</width>
|
||||
<height>579</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QPushButton" name="projectSettingsButton">
|
||||
<property name="text">
|
||||
<string>Project Settings</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="gemsButton">
|
||||
<property name="text">
|
||||
<string>Gems</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>761</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_4">
|
||||
<item>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Project Name</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="lineEdit"/>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>Project Location</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="lineEdit_2"/>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>Project Image Location</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="lineEdit_3"/>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="text">
|
||||
<string>Project Background Image Location</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="lineEdit_4"/>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
@ -0,0 +1,51 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <UpdateProjectSettingsScreen.h>
|
||||
#include <FormBrowseEditWidget.h>
|
||||
#include <FormLineEditWidget.h>
|
||||
|
||||
#include <QLineEdit>
|
||||
#include <QDir>
|
||||
|
||||
namespace O3DE::ProjectManager
|
||||
{
|
||||
UpdateProjectSettingsScreen::UpdateProjectSettingsScreen(QWidget* parent)
|
||||
: ProjectSettingsScreen(parent)
|
||||
{
|
||||
}
|
||||
|
||||
ProjectManagerScreen UpdateProjectSettingsScreen::GetScreenEnum()
|
||||
{
|
||||
return ProjectManagerScreen::UpdateProjectSettings;
|
||||
}
|
||||
|
||||
void UpdateProjectSettingsScreen::SetProjectInfo(const ProjectInfo& projectInfo)
|
||||
{
|
||||
m_projectName->lineEdit()->setText(projectInfo.m_projectName);
|
||||
m_projectPath->lineEdit()->setText(projectInfo.m_path);
|
||||
}
|
||||
|
||||
bool UpdateProjectSettingsScreen::ValidateProjectPath()
|
||||
{
|
||||
bool projectPathIsValid = true;
|
||||
if (m_projectPath->lineEdit()->text().isEmpty())
|
||||
{
|
||||
projectPathIsValid = false;
|
||||
m_projectPath->setErrorLabelText(tr("Please provide a valid location."));
|
||||
}
|
||||
|
||||
m_projectPath->setErrorLabelVisible(!projectPathIsValid);
|
||||
return projectPathIsValid;
|
||||
}
|
||||
|
||||
} // namespace O3DE::ProjectManager
|
||||
@ -0,0 +1,34 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#if !defined(Q_MOC_RUN)
|
||||
#include <ProjectSettingsScreen.h>
|
||||
#endif
|
||||
|
||||
namespace O3DE::ProjectManager
|
||||
{
|
||||
class UpdateProjectSettingsScreen
|
||||
: public ProjectSettingsScreen
|
||||
{
|
||||
public:
|
||||
explicit UpdateProjectSettingsScreen(QWidget* parent = nullptr);
|
||||
~UpdateProjectSettingsScreen() = default;
|
||||
ProjectManagerScreen GetScreenEnum() override;
|
||||
|
||||
void SetProjectInfo(const ProjectInfo& projectInfo);
|
||||
|
||||
protected:
|
||||
bool ValidateProjectPath() override;
|
||||
};
|
||||
|
||||
} // namespace O3DE::ProjectManager
|
||||
@ -0,0 +1,214 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <Material/MaterialAssignmentSerializer.h>
|
||||
#include <Atom/Feature/Material/MaterialAssignment.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
namespace Render
|
||||
{
|
||||
AZ_CLASS_ALLOCATOR_IMPL(JsonMaterialAssignmentSerializer, AZ::SystemAllocator, 0);
|
||||
|
||||
JsonSerializationResult::Result JsonMaterialAssignmentSerializer::Load(
|
||||
void* outputValue, [[maybe_unused]] const Uuid& outputValueTypeId, const rapidjson::Value& inputValue,
|
||||
JsonDeserializerContext& context)
|
||||
{
|
||||
namespace JSR = JsonSerializationResult;
|
||||
|
||||
AZ_Assert(
|
||||
azrtti_typeid<AZ::Render::MaterialAssignment>() == outputValueTypeId,
|
||||
"Unable to deserialize MaterialAssignment from json because the provided type is %s.",
|
||||
outputValueTypeId.ToString<AZStd::string>().c_str());
|
||||
|
||||
AZ::Render::MaterialAssignment* materialAssignment = reinterpret_cast<AZ::Render::MaterialAssignment*>(outputValue);
|
||||
AZ_Assert(materialAssignment, "Output value for JsonMaterialAssignmentSerializer can't be null.");
|
||||
|
||||
JSR::ResultCode result(JSR::Tasks::ReadField);
|
||||
{
|
||||
result.Combine(ContinueLoadingFromJsonObjectField(
|
||||
&materialAssignment->m_materialAsset, azrtti_typeid<decltype(materialAssignment->m_materialAsset)>(), inputValue,
|
||||
"MaterialAsset", context));
|
||||
}
|
||||
|
||||
if (inputValue.HasMember("PropertyOverrides") && inputValue["PropertyOverrides"].IsObject())
|
||||
{
|
||||
// Attempt to load material property override values for a subset of types
|
||||
for (const auto& inputPropertyPair : inputValue["PropertyOverrides"].GetObject())
|
||||
{
|
||||
const AZ::Name propertyName(inputPropertyPair.name.GetString());
|
||||
if (!propertyName.IsEmpty())
|
||||
{
|
||||
AZStd::any propertyValue;
|
||||
if (LoadAny<bool>(propertyValue, inputPropertyPair.value, context, result) ||
|
||||
LoadAny<AZ::u8>(propertyValue, inputPropertyPair.value, context, result) ||
|
||||
LoadAny<AZ::u16>(propertyValue, inputPropertyPair.value, context, result) ||
|
||||
LoadAny<AZ::u32>(propertyValue, inputPropertyPair.value, context, result) ||
|
||||
LoadAny<AZ::u64>(propertyValue, inputPropertyPair.value, context, result) ||
|
||||
LoadAny<AZ::s8>(propertyValue, inputPropertyPair.value, context, result) ||
|
||||
LoadAny<AZ::s16>(propertyValue, inputPropertyPair.value, context, result) ||
|
||||
LoadAny<AZ::s32>(propertyValue, inputPropertyPair.value, context, result) ||
|
||||
LoadAny<AZ::s64>(propertyValue, inputPropertyPair.value, context, result) ||
|
||||
LoadAny<float>(propertyValue, inputPropertyPair.value, context, result) ||
|
||||
LoadAny<double>(propertyValue, inputPropertyPair.value, context, result) ||
|
||||
LoadAny<AZ::Vector2>(propertyValue, inputPropertyPair.value, context, result) ||
|
||||
LoadAny<AZ::Vector3>(propertyValue, inputPropertyPair.value, context, result) ||
|
||||
LoadAny<AZ::Vector4>(propertyValue, inputPropertyPair.value, context, result) ||
|
||||
LoadAny<AZ::Color>(propertyValue, inputPropertyPair.value, context, result) ||
|
||||
LoadAny<AZStd::string>(propertyValue, inputPropertyPair.value, context, result) ||
|
||||
LoadAny<AZ::Data::AssetId>(propertyValue, inputPropertyPair.value, context, result) ||
|
||||
LoadAny<AZ::Data::Asset<AZ::RPI::ImageAsset>>(propertyValue, inputPropertyPair.value, context, result) ||
|
||||
LoadAny<AZ::Data::Asset<AZ::RPI::StreamingImageAsset>>(propertyValue, inputPropertyPair.value, context, result))
|
||||
{
|
||||
materialAssignment->m_propertyOverrides[propertyName] = propertyValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return context.Report(
|
||||
result,
|
||||
result.GetProcessing() != JSR::Processing::Halted ? "Succesfully loaded MaterialAssignment information."
|
||||
: "Failed to load MaterialAssignment information.");
|
||||
}
|
||||
|
||||
JsonSerializationResult::Result JsonMaterialAssignmentSerializer::Store(
|
||||
rapidjson::Value& outputValue, const void* inputValue, const void* defaultValue, [[maybe_unused]] const Uuid& valueTypeId,
|
||||
JsonSerializerContext& context)
|
||||
{
|
||||
namespace JSR = AZ::JsonSerializationResult;
|
||||
|
||||
AZ_Assert(
|
||||
azrtti_typeid<AZ::Render::MaterialAssignment>() == valueTypeId,
|
||||
"Unable to Serialize MaterialAssignment because the provided type is %s.", valueTypeId.ToString<AZStd::string>().c_str());
|
||||
|
||||
const AZ::Render::MaterialAssignment* materialAssignment = reinterpret_cast<const AZ::Render::MaterialAssignment*>(inputValue);
|
||||
AZ_Assert(materialAssignment, "Input value for JsonMaterialAssignmentSerializer can't be null.");
|
||||
const AZ::Render::MaterialAssignment* defaultMaterialAssignmentInstance =
|
||||
reinterpret_cast<const AZ::Render::MaterialAssignment*>(defaultValue);
|
||||
|
||||
outputValue.SetObject();
|
||||
|
||||
JSR::ResultCode result(JSR::Tasks::WriteValue);
|
||||
{
|
||||
AZ::ScopedContextPath subPathMaterialAsset(context, "m_materialAsset");
|
||||
const AZ::Data::Asset<RPI::MaterialAsset>* materialAsset = &materialAssignment->m_materialAsset;
|
||||
const AZ::Data::Asset<RPI::MaterialAsset>* defaultmaterialAsset =
|
||||
defaultMaterialAssignmentInstance ? &defaultMaterialAssignmentInstance->m_materialAsset : nullptr;
|
||||
|
||||
result.Combine(ContinueStoringToJsonObjectField(
|
||||
outputValue, "MaterialAsset", materialAsset, defaultmaterialAsset,
|
||||
azrtti_typeid<decltype(materialAssignment->m_materialAsset)>(), context));
|
||||
}
|
||||
|
||||
{
|
||||
AZ::ScopedContextPath subPathPropertyOverrides(context, "m_propertyOverrides");
|
||||
if (!materialAssignment->m_propertyOverrides.empty())
|
||||
{
|
||||
rapidjson::Value outputPropertyValueContainer;
|
||||
outputPropertyValueContainer.SetObject();
|
||||
|
||||
// Attempt to extract and store material property override values for a subset of types
|
||||
for (const auto& propertyPair : materialAssignment->m_propertyOverrides)
|
||||
{
|
||||
const AZ::Name& propertyName = propertyPair.first;
|
||||
const AZStd::any& propertyValue = propertyPair.second;
|
||||
if (!propertyName.IsEmpty() && !propertyValue.empty())
|
||||
{
|
||||
rapidjson::Value outputPropertyValue;
|
||||
if (StoreAny<bool>(propertyValue, outputPropertyValue, context, result) ||
|
||||
StoreAny<AZ::u8>(propertyValue, outputPropertyValue, context, result) ||
|
||||
StoreAny<AZ::u16>(propertyValue, outputPropertyValue, context, result) ||
|
||||
StoreAny<AZ::u32>(propertyValue, outputPropertyValue, context, result) ||
|
||||
StoreAny<AZ::u64>(propertyValue, outputPropertyValue, context, result) ||
|
||||
StoreAny<AZ::s8>(propertyValue, outputPropertyValue, context, result) ||
|
||||
StoreAny<AZ::s16>(propertyValue, outputPropertyValue, context, result) ||
|
||||
StoreAny<AZ::s32>(propertyValue, outputPropertyValue, context, result) ||
|
||||
StoreAny<AZ::s64>(propertyValue, outputPropertyValue, context, result) ||
|
||||
StoreAny<float>(propertyValue, outputPropertyValue, context, result) ||
|
||||
StoreAny<double>(propertyValue, outputPropertyValue, context, result) ||
|
||||
StoreAny<AZ::Vector2>(propertyValue, outputPropertyValue, context, result) ||
|
||||
StoreAny<AZ::Vector3>(propertyValue, outputPropertyValue, context, result) ||
|
||||
StoreAny<AZ::Vector4>(propertyValue, outputPropertyValue, context, result) ||
|
||||
StoreAny<AZ::Color>(propertyValue, outputPropertyValue, context, result) ||
|
||||
StoreAny<AZStd::string>(propertyValue, outputPropertyValue, context, result) ||
|
||||
StoreAny<AZ::Data::AssetId>(propertyValue, outputPropertyValue, context, result) ||
|
||||
StoreAny<AZ::Data::Asset<AZ::RPI::ImageAsset>>(propertyValue, outputPropertyValue, context, result) ||
|
||||
StoreAny<AZ::Data::Asset<AZ::RPI::StreamingImageAsset>>(
|
||||
propertyValue, outputPropertyValue, context, result))
|
||||
{
|
||||
outputPropertyValueContainer.AddMember(
|
||||
rapidjson::Value::StringRefType(propertyName.GetCStr()), outputPropertyValue,
|
||||
context.GetJsonAllocator());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (outputPropertyValueContainer.MemberCount() > 0)
|
||||
{
|
||||
outputValue.AddMember("PropertyOverrides", outputPropertyValueContainer, context.GetJsonAllocator());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return context.Report(
|
||||
result,
|
||||
result.GetProcessing() != JSR::Processing::Halted ? "Successfully stored MaterialAssignment information."
|
||||
: "Failed to store MaterialAssignment information.");
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool JsonMaterialAssignmentSerializer::LoadAny(
|
||||
AZStd::any& propertyValue, const rapidjson::Value& inputPropertyValue, AZ::JsonDeserializerContext& context,
|
||||
AZ::JsonSerializationResult::ResultCode& result)
|
||||
{
|
||||
if (inputPropertyValue.IsObject() && inputPropertyValue.HasMember("Value") && inputPropertyValue.HasMember("$type"))
|
||||
{
|
||||
// Requiring explicit type info to differentiate be=tween colors versus vectors and numeric types
|
||||
const AZ::Uuid baseTypeId = azrtti_typeid<T>();
|
||||
AZ::Uuid typeId = AZ::Uuid::CreateNull();
|
||||
result.Combine(LoadTypeId(typeId, inputPropertyValue, context, &baseTypeId));
|
||||
|
||||
if (typeId == azrtti_typeid<T>())
|
||||
{
|
||||
T value = {};
|
||||
result.Combine(ContinueLoadingFromJsonObjectField(&value, azrtti_typeid<T>(), inputPropertyValue, "Value", context));
|
||||
propertyValue = value;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool JsonMaterialAssignmentSerializer::StoreAny(
|
||||
const AZStd::any& propertyValue, rapidjson::Value& outputPropertyValue, AZ::JsonSerializerContext& context,
|
||||
AZ::JsonSerializationResult::ResultCode& result)
|
||||
{
|
||||
if (propertyValue.is<T>())
|
||||
{
|
||||
outputPropertyValue.SetObject();
|
||||
|
||||
// Storing explicit type info to differentiate be=tween colors versus vectors and numeric types
|
||||
rapidjson::Value typeValue;
|
||||
result.Combine(StoreTypeId(typeValue, azrtti_typeid<T>(), context));
|
||||
outputPropertyValue.AddMember("$type", typeValue, context.GetJsonAllocator());
|
||||
|
||||
T value = AZStd::any_cast<T>(propertyValue);
|
||||
result.Combine(
|
||||
ContinueStoringToJsonObjectField(outputPropertyValue, "Value", &value, nullptr, azrtti_typeid<T>(), context));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
} // namespace Render
|
||||
} // namespace AZ
|
||||
@ -0,0 +1,50 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AzCore/Memory/Memory.h>
|
||||
#include <AzCore/Name/Name.h>
|
||||
#include <AzCore/Serialization/Json/BaseJsonSerializer.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
namespace Render
|
||||
{
|
||||
// Custom JSON serializer for material assignment objects containing AZStd::any property overrides,
|
||||
// which aren't supported by the system
|
||||
class JsonMaterialAssignmentSerializer : public BaseJsonSerializer
|
||||
{
|
||||
public:
|
||||
AZ_RTTI(JsonMaterialAssignmentSerializer, "{3D33653E-4582-483F-91F5-BBCC347C3DF0}", BaseJsonSerializer);
|
||||
AZ_CLASS_ALLOCATOR_DECL;
|
||||
|
||||
JsonSerializationResult::Result Load(
|
||||
void* outputValue, const Uuid& outputValueTypeId, const rapidjson::Value& inputValue,
|
||||
JsonDeserializerContext& context) override;
|
||||
|
||||
JsonSerializationResult::Result Store(
|
||||
rapidjson::Value& outputValue, const void* inputValue, const void* defaultValue, const Uuid& valueTypeId,
|
||||
JsonSerializerContext& context) override;
|
||||
|
||||
private:
|
||||
template<typename T>
|
||||
bool LoadAny(
|
||||
AZStd::any& propertyValue, const rapidjson::Value& inputPropertyValue, AZ::JsonDeserializerContext& context,
|
||||
AZ::JsonSerializationResult::ResultCode& result);
|
||||
template<typename T>
|
||||
bool StoreAny(
|
||||
const AZStd::any& propertyValue, rapidjson::Value& outputPropertyValue, AZ::JsonSerializerContext& context,
|
||||
AZ::JsonSerializationResult::ResultCode& result);
|
||||
};
|
||||
} // namespace Render
|
||||
} // namespace AZ
|
||||
@ -0,0 +1,209 @@
|
||||
vulkan.h was generated using a code generator from https://github.com/Dav1dde/glad
|
||||
|
||||
/*
|
||||
** Copyright (c) 2014-2020 The Khronos Group Inc.
|
||||
**
|
||||
** SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
@ -0,0 +1,39 @@
|
||||
All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
its licensors.
|
||||
|
||||
For complete copyright and license terms please see the LICENSE at the root of this
|
||||
distribution (the "License"). All use of this software is governed by the License,
|
||||
or, if provided, by the license below or the license accompanying this file. Do not
|
||||
remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
||||
|
||||
INTRODUCTION
|
||||
------------
|
||||
|
||||
atom_rpi_tools is a Python project that contains a collection of tools
|
||||
developed by the Atom team. The project contains the following tools:
|
||||
|
||||
* Render pipeline merge tool:
|
||||
A library to manipulate .pass asset files and help gems create scripts to update render pipeline
|
||||
|
||||
|
||||
REQUIREMENTS
|
||||
------------
|
||||
|
||||
* Python 3.7.5 (64-bit)
|
||||
|
||||
It is recommended that you completely remove any other versions of Python
|
||||
installed on your system.
|
||||
|
||||
|
||||
INSTALL
|
||||
-----------
|
||||
It is recommended to set up these these tools with Lumberyard's CMake build commands.
|
||||
|
||||
|
||||
UNINSTALLATION
|
||||
--------------
|
||||
|
||||
The preferred way to uninstall the project is:
|
||||
(engine install root)/python/python -m pip uninstall atom_rpi_tools
|
||||
@ -0,0 +1,10 @@
|
||||
"""
|
||||
All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
its licensors.
|
||||
|
||||
For complete copyright and license terms please see the LICENSE at the root of this
|
||||
distribution (the "License"). All use of this software is governed by the License,
|
||||
or, if provided, by the license below or the license accompanying this file. Do not
|
||||
remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
"""
|
||||
@ -0,0 +1,210 @@
|
||||
"""
|
||||
All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
its licensors.
|
||||
|
||||
For complete copyright and license terms please see the LICENSE at the root of this
|
||||
distribution (the "License"). All use of this software is governed by the License,
|
||||
or, if provided, by the license below or the license accompanying this file. Do not
|
||||
remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
||||
"""
|
||||
|
||||
import sys, os
|
||||
import json
|
||||
import shutil
|
||||
|
||||
class PassTemplate:
|
||||
# This class provide necessary functions for insert pass requests and update connections
|
||||
# which are common functions required for adding features.
|
||||
# It doesn't include the remove/delete furnctions since that's not common case for merging render pipeline
|
||||
def __init__(self, filePath: str):
|
||||
self.initialized = False
|
||||
self.file_path: str = filePath
|
||||
#load the json file
|
||||
json_data = open(filePath, "r")
|
||||
self.file_data = json.load(json_data)
|
||||
|
||||
if 'ClassName' not in self.file_data or 'ClassData' not in self.file_data or self.file_data['ClassName']!='PassAsset' or 'PassTemplate' not in self.file_data['ClassData']:
|
||||
raise KeyError('the json file is not a PassAsset file')
|
||||
return
|
||||
|
||||
if 'PassRequests' in self.file_data['ClassData']['PassTemplate']:
|
||||
self.passRequests = self.file_data['ClassData']['PassTemplate']['PassRequests']
|
||||
|
||||
if 'Slots' in self.file_data['ClassData']['PassTemplate']:
|
||||
self.slots = self.file_data['ClassData']['PassTemplate']['Slots']
|
||||
|
||||
self.initialized = True
|
||||
print('PassTemplate is loaded from ', filePath)
|
||||
|
||||
def find_pass(self, passName):
|
||||
# return pass's index in PassRequests if a PassRequest with input passName exists
|
||||
if not hasattr(self, 'passRequests'):
|
||||
return -1
|
||||
index = 0
|
||||
for passRequest in self.passRequests:
|
||||
if passRequest['Name'] == passName:
|
||||
return index
|
||||
index += 1
|
||||
return -1
|
||||
|
||||
def get_pass_count(self):
|
||||
if not hasattr(self, 'passRequests'):
|
||||
return 0
|
||||
return len(self.passRequests)
|
||||
|
||||
def __validate_pass_request_data(self, passRequest):
|
||||
if ('Name' not in passRequest or 'TemplateName' not in passRequest):
|
||||
raise KeyError('invalid pass request data')
|
||||
|
||||
def __ensure_pass_requests_key(self):
|
||||
if not hasattr(self, 'passRequests'):
|
||||
self.file_data['ClassData']['PassTemplate']['PassRequests'] = []
|
||||
self.passRequests = self.file_data['ClassData']['PassTemplate']['PassRequests']
|
||||
|
||||
def __ensure_pass_slots_key(self):
|
||||
if not hasattr(self, 'slots'):
|
||||
self.file_data['ClassData']['PassTemplate']['Slots'] = []
|
||||
self.slots = self.file_data['ClassData']['PassTemplate']['Slots']
|
||||
|
||||
def insert_pass_request(self, location, passRequest):
|
||||
self.__validate_pass_request_data(passRequest)
|
||||
|
||||
if (self.find_pass(passRequest['Name']) >= 0):
|
||||
raise ValueError('pass request ', passRequest['Name'], ' is already exist')
|
||||
# insert a passRequest before the specified location
|
||||
self.__ensure_pass_requests_key()
|
||||
self.passRequests.insert(location, passRequest)
|
||||
|
||||
def replace_references_after(self, startPassRequest, oldPass, oldSlot, newPass, newSlot):
|
||||
if not hasattr(self, 'passRequests'):
|
||||
return 0
|
||||
# from all pass requests after startPassRequest
|
||||
# replace all attachment references which uses oldPass and oldSlot
|
||||
# with newPass and newSlot
|
||||
started = False
|
||||
replaced_count = 0
|
||||
for request in self.passRequests:
|
||||
if started:
|
||||
if ('Connections' in request):
|
||||
for connection in request['Connections']:
|
||||
if connection['AttachmentRef']['Pass'] == oldPass and connection['AttachmentRef']['Attachment'] == oldSlot:
|
||||
connection['AttachmentRef']['Pass'] = newPass
|
||||
connection['AttachmentRef']['Attachment'] = newSlot
|
||||
replaced_count += 1
|
||||
if request['Name'] == startPassRequest and not started:
|
||||
started = True
|
||||
return replaced_count
|
||||
|
||||
def replace_references_for(self, passRequest, oldPass, oldSlot, newPass, newSlot):
|
||||
if not hasattr(self, 'passRequests'):
|
||||
return 0
|
||||
#replace pass reference for the specified passRequest
|
||||
replaced_count = 0
|
||||
for request in self.passRequests:
|
||||
if request['Name'] == passRequest:
|
||||
if ('Connections' in request):
|
||||
for connection in request['Connections']:
|
||||
if connection['AttachmentRef']['Pass'] == oldPass and connection['AttachmentRef']['Attachment'] == oldSlot:
|
||||
connection['AttachmentRef']['Pass'] = newPass
|
||||
connection['AttachmentRef']['Attachment'] = newSlot
|
||||
replaced_count += 1
|
||||
return replaced_count #return when the specified pass request is updated.
|
||||
return replaced_count
|
||||
|
||||
def __validate_slot_data(self, slotData):
|
||||
if ('Name' not in slotData or 'SlotType' not in slotData):
|
||||
raise KeyError('invalid slot data')
|
||||
|
||||
def get_slot_count(self):
|
||||
if not hasattr(self, 'slots'):
|
||||
return 0
|
||||
return len(self.slots)
|
||||
|
||||
def find_slot(self, slotName):
|
||||
# return slot's index in Slots if a PassRequest with input passName exists
|
||||
if not hasattr(self, 'slots'):
|
||||
return -1
|
||||
index = 0
|
||||
for slot in self.slots:
|
||||
if slot['Name'] == slotName:
|
||||
return index
|
||||
index += 1
|
||||
return -1
|
||||
|
||||
def insert_slot(self, location, newSlotData):
|
||||
# insert a new slot at specified location
|
||||
self.__validate_slot_data(newSlotData)
|
||||
# check if the slot already exist
|
||||
if (self.find_slot(newSlotData['Name']) >= 0):
|
||||
raise ValueError('Slot ', newSlotData['Name'], ' is already exist')
|
||||
|
||||
self.__ensure_pass_slots_key()
|
||||
self.slots.insert(location, newSlotData)
|
||||
|
||||
def add_slot(self, newSlotData):
|
||||
# append a new slot to slots
|
||||
self.__validate_slot_data(newSlotData)
|
||||
# check if the slot already exist
|
||||
if (self.find_slot(newSlotData['Name']) >= 0):
|
||||
raise ValueError('Slot ', newSlotData['Name'], ' is already exist')
|
||||
|
||||
self.__ensure_pass_slots_key()
|
||||
self.slots.append(newSlotData)
|
||||
|
||||
def get_pass_request(self, passName):
|
||||
if not hasattr(self, 'passRequests'):
|
||||
return
|
||||
# Get the pass request from PassRequests with matching pass name
|
||||
for passRequest in self.passRequests:
|
||||
if passRequest['Name'] == passName:
|
||||
return passRequest
|
||||
|
||||
def save(self):
|
||||
# backup the original file
|
||||
backupFilePath = self.file_path +'.backup'
|
||||
shutil.copyfile(self.file_path, backupFilePath)
|
||||
# save and overwrite file
|
||||
with open(self.file_path, 'w') as json_file:
|
||||
json.dump(self.file_data, json_file, indent = 4)
|
||||
print('File [', self.file_path, '] is updated. Old version is saved in [', backupFilePath, ']')
|
||||
|
||||
|
||||
class PassRequest:
|
||||
|
||||
def __init__(self, passRequest: object):
|
||||
self.pass_request = passRequest
|
||||
if 'Connections' in passRequest:
|
||||
self.connections = passRequest['Connections']
|
||||
|
||||
def __validate_connection(self, connection):
|
||||
if ('LocalSlot' not in connection or 'AttachmentRef' not in connection):
|
||||
raise KeyError('invalid connection data')
|
||||
|
||||
def __ensure_connections_key(self):
|
||||
if not hasattr(self, 'connections'):
|
||||
self.pass_request['Connections'] = []
|
||||
self.connections = self.pass_request['Connections']
|
||||
|
||||
def get_connection_count(self):
|
||||
if not hasattr(self, 'connections'):
|
||||
return 0
|
||||
return len(self.connections)
|
||||
|
||||
def find_connection(self, localSlotName):
|
||||
if not hasattr(self, 'connections'):
|
||||
return -1
|
||||
index = 0
|
||||
for connection in self.connections:
|
||||
if connection['LocalSlot'] == localSlotName:
|
||||
return index
|
||||
index += 1
|
||||
return -1
|
||||
|
||||
def add_connection(self, newConnection):
|
||||
self.__validate_connection(newConnection)
|
||||
if self.find_connection(newConnection['LocalSlot']) >= 0:
|
||||
raise ValueError('connection ', newConnection['LocalSlot'], ' already exists')
|
||||
self.__ensure_connections_key()
|
||||
self.connections.append(newConnection)
|
||||
@ -0,0 +1,10 @@
|
||||
"""
|
||||
All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
its licensors.
|
||||
|
||||
For complete copyright and license terms please see the LICENSE at the root of this
|
||||
distribution (the "License"). All use of this software is governed by the License,
|
||||
or, if provided, by the license below or the license accompanying this file. Do not
|
||||
remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
"""
|
||||
@ -0,0 +1,303 @@
|
||||
"""
|
||||
All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
its licensors.
|
||||
|
||||
For complete copyright and license terms please see the LICENSE at the root of this
|
||||
distribution (the "License"). All use of this software is governed by the License,
|
||||
or, if provided, by the license below or the license accompanying this file. Do not
|
||||
remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
||||
Unit tests for pass_data.py
|
||||
"""
|
||||
import os
|
||||
import pytest
|
||||
import shutil
|
||||
import json
|
||||
from atom_rpi_tools.pass_data import PassTemplate
|
||||
from atom_rpi_tools.pass_data import PassRequest
|
||||
|
||||
good_pass_requests_file = os.path.join(os.path.dirname(__file__), 'testdata/pass_requests.json')
|
||||
good_pass_slots_file = os.path.join(os.path.dirname(__file__), 'testdata/pass_slots.json')
|
||||
bad_test_data_file = os.path.join(os.path.dirname(__file__), 'testdata/pass_test_bad.json')
|
||||
|
||||
@pytest.fixture
|
||||
def pass_requests_template(tmpdir):
|
||||
filename = 'pass_requests.json'
|
||||
source_path = os.path.join(os.path.dirname(__file__), 'testdata/', filename)
|
||||
destFilePath = os.path.join(tmpdir, 'pass_requests.json')
|
||||
shutil.copyfile(source_path, destFilePath)
|
||||
return PassTemplate(destFilePath)
|
||||
|
||||
@pytest.fixture
|
||||
def pass_slots_template(tmpdir):
|
||||
filename = 'pass_slots.json'
|
||||
source_path = os.path.join(os.path.dirname(__file__), 'testdata/', filename)
|
||||
destFilePath = os.path.join(tmpdir, 'pass_requests.json')
|
||||
shutil.copyfile(source_path, destFilePath)
|
||||
return PassTemplate(destFilePath)
|
||||
|
||||
@pytest.fixture
|
||||
def new_pass_request():
|
||||
pass_request = json.loads('{\"Name\": \"InsertPass\",\"TemplateName\": \"InsertPassTemplate\"}')
|
||||
return pass_request
|
||||
|
||||
@pytest.fixture
|
||||
def new_slot():
|
||||
slot = json.loads('{\"Name\": \"NewSlot\",\"SlotType\": \"Input\"}')
|
||||
return slot
|
||||
|
||||
@pytest.fixture
|
||||
def new_connection():
|
||||
connection = json.loads('{\"LocalSlot\": \"color\", \"AttachmentRef\": { \"Pass\": \"Parent\", \"Attachment\": \"DepthStencil\"}}')
|
||||
return connection
|
||||
|
||||
def test_PassTemplate_Initialize_BadPassTemplateData_ExceptionThrown():
|
||||
with pytest.raises(KeyError):
|
||||
PassTemplate(bad_test_data_file)
|
||||
|
||||
def test_PassTemplate_FindPass_Success(pass_requests_template):
|
||||
assert pass_requests_template.find_pass('OpaquePass') == 0
|
||||
assert pass_requests_template.find_pass('ImGuiPass') == 4
|
||||
assert pass_requests_template.find_pass('NotExistPass') == -1
|
||||
|
||||
def test_PassTemplate_InsertPassRequest_AtBegining_Success(pass_requests_template, new_pass_request):
|
||||
template = pass_requests_template
|
||||
pass_count = template.get_pass_count()
|
||||
template.insert_pass_request(0, new_pass_request)
|
||||
assert template.find_pass(new_pass_request['Name']) == 0
|
||||
assert template.get_pass_count() == pass_count+1
|
||||
|
||||
# verify the change is saved
|
||||
template.save()
|
||||
saved_tamplate = PassTemplate(template.file_path)
|
||||
assert saved_tamplate.find_pass(new_pass_request['Name'])== 0
|
||||
assert saved_tamplate.get_pass_count() == pass_count+1
|
||||
|
||||
def test_PassTemplate_InsertPassRequest_AtEnd_Success(pass_requests_template, new_pass_request):
|
||||
template = pass_requests_template
|
||||
pass_count = template.get_pass_count()
|
||||
template.insert_pass_request(pass_count, new_pass_request)
|
||||
assert template.find_pass(new_pass_request['Name']) == pass_count
|
||||
assert template.get_pass_count() == pass_count+1
|
||||
|
||||
# verify the change is saved
|
||||
template.save()
|
||||
saved_tamplate = PassTemplate(template.file_path)
|
||||
assert saved_tamplate.find_pass(new_pass_request['Name']) == pass_count
|
||||
assert saved_tamplate.get_pass_count() == pass_count+1
|
||||
|
||||
def test_PassTemplate_InsertPassRequest_WithDuplicatedName_ExceptionThrown(pass_requests_template, new_pass_request):
|
||||
template = pass_requests_template
|
||||
# insert new pass request
|
||||
template.insert_pass_request(0, new_pass_request)
|
||||
pass_count = template.get_pass_count()
|
||||
# exception when insert the same pass again
|
||||
with pytest.raises(ValueError):
|
||||
template.insert_pass_request(2, new_pass_request)
|
||||
# pass count doesn't change
|
||||
assert template.get_pass_count() == pass_count
|
||||
|
||||
def test_PassTemplate_InsertPassRequest_WithBadData_ExceptionThrown(pass_requests_template):
|
||||
template = pass_requests_template
|
||||
pass_count = template.get_pass_count()
|
||||
bad_pass_request = json.loads('{\"name\":\"value\"}')
|
||||
with pytest.raises(KeyError):
|
||||
template.insert_pass_request(2, bad_pass_request)
|
||||
assert template.get_pass_count() == pass_count
|
||||
|
||||
def test_PassTemplate_InsertPassRequest_AtOutOfRange_AppendSuccess(pass_requests_template, new_pass_request):
|
||||
template = pass_requests_template
|
||||
pass_count = template.get_pass_count()
|
||||
template.insert_pass_request(pass_count+2, new_pass_request)
|
||||
assert template.find_pass(new_pass_request['Name']) == pass_count
|
||||
assert template.get_pass_count() == pass_count+1
|
||||
|
||||
def test_PassTemplate_ReplaceReferencesAfter_Success(pass_requests_template):
|
||||
# replace OpaquePass.DepthStencil with Parent.DepthStencil'
|
||||
refPass = 'OpaquePass'
|
||||
# there are 2 passes after OpaquePass which use OpaquePass.DepthStencil as attachment reference
|
||||
assert pass_requests_template.replace_references_after(refPass, 'OpaquePass', 'DepthStencil', 'Parent', 'DepthStencil') == 2
|
||||
# after the previous replacement, there it no OpaquePass.DepthStencil reference
|
||||
refPass = 'TransparentPass'
|
||||
assert pass_requests_template.replace_references_after(refPass, 'OpaquePass', 'DepthStencil', 'Parent', 'DepthStencil') == 0
|
||||
|
||||
# verify changes are saved
|
||||
pass_requests_template.save()
|
||||
saved_tamplate = PassTemplate(pass_requests_template.file_path)
|
||||
assert saved_tamplate.replace_references_after('OpaquePass', 'OpaquePass', 'DepthStencil', 'Parent', 'DepthStencil') == 0
|
||||
|
||||
def test_PassTemplate_ReplaceReferencesFor_Success(pass_requests_template):
|
||||
refPass = 'TransparentPass'
|
||||
assert pass_requests_template.replace_references_for(refPass, 'OpaquePass', 'DepthStencil', 'Parent', 'DepthStencil') == 1
|
||||
refPass = '2DPass'
|
||||
assert pass_requests_template.replace_references_for(refPass, 'OpaquePass', 'DepthStencil', 'Parent', 'DepthStencil') == 0
|
||||
|
||||
# verify changes are saved
|
||||
pass_requests_template.save()
|
||||
saved_tamplate = PassTemplate(pass_requests_template.file_path)
|
||||
# no reference of OpaquePass.DepthStencil in TransparentPass
|
||||
assert saved_tamplate.replace_references_for('TransparentPass', 'OpaquePass', 'DepthStencil', 'Parent', 'DepthStencil') == 0
|
||||
|
||||
def test_PassTemplate_FindSlot_Success(pass_slots_template):
|
||||
assert pass_slots_template.find_slot('Color') == -1
|
||||
assert pass_slots_template.find_slot('DepthStencil') == 0
|
||||
assert pass_slots_template.find_slot('ColorInputOutput') == 1
|
||||
|
||||
def test_PassTemplate_InsertSlot_AtBegining_Success(pass_slots_template, new_slot):
|
||||
template = pass_slots_template
|
||||
slot_count = template.get_slot_count()
|
||||
depth_stencil_slot = template.find_slot('DepthStencil')
|
||||
template.insert_slot(0, new_slot)
|
||||
assert template.find_slot(new_slot['Name']) == 0
|
||||
assert template.find_slot('DepthStencil') == depth_stencil_slot+1 # DepthStencil moved back by 1
|
||||
assert template.get_slot_count() == slot_count+1
|
||||
|
||||
# verify the change is saved
|
||||
template.save()
|
||||
saved_tamplate = PassTemplate(template.file_path)
|
||||
assert saved_tamplate.find_slot(new_slot['Name']) == 0
|
||||
assert saved_tamplate.get_slot_count() == slot_count+1
|
||||
|
||||
def test_PassTemplate_InsertSlot_AtEnd_Success(pass_slots_template, new_slot):
|
||||
template = pass_slots_template
|
||||
slot_count = template.get_slot_count()
|
||||
depth_stencil_slot = template.find_slot('DepthStencil')
|
||||
template.insert_slot(slot_count, new_slot)
|
||||
assert template.find_slot(new_slot['Name']) == slot_count
|
||||
assert template.find_slot('DepthStencil') == depth_stencil_slot
|
||||
assert template.get_slot_count() == slot_count+1
|
||||
|
||||
# verify the change is saved
|
||||
template.save()
|
||||
saved_tamplate = PassTemplate(template.file_path)
|
||||
assert saved_tamplate.find_slot(new_slot['Name']) == slot_count
|
||||
assert saved_tamplate.get_slot_count() == slot_count+1
|
||||
|
||||
def test_PassTemplate_AddSlot_GoodSlotData_Success(pass_slots_template, new_slot):
|
||||
template = pass_slots_template
|
||||
slot_count = template.get_slot_count()
|
||||
depth_stencil_slot = template.find_slot('DepthStencil')
|
||||
template.add_slot(new_slot)
|
||||
assert template.find_slot(new_slot['Name']) == slot_count
|
||||
assert template.find_slot('DepthStencil') == depth_stencil_slot
|
||||
assert template.get_slot_count() == slot_count+1
|
||||
|
||||
# verify the change is saved
|
||||
template.save()
|
||||
saved_tamplate = PassTemplate(template.file_path)
|
||||
assert saved_tamplate.find_slot(new_slot['Name']) == slot_count
|
||||
assert saved_tamplate.get_slot_count() == slot_count+1
|
||||
|
||||
def test_PassTemplate_InsertSlot_OutOfRange_AppendSuccess(pass_slots_template, new_slot):
|
||||
template = pass_slots_template
|
||||
slot_count = template.get_slot_count()
|
||||
template.insert_slot(slot_count+3, new_slot)
|
||||
assert template.find_slot(new_slot['Name']) == slot_count
|
||||
assert template.get_slot_count() == slot_count+1
|
||||
|
||||
def test_PassTemplate_AddDuplicateSlot_ExceptionThrown(pass_slots_template, new_slot):
|
||||
template = pass_slots_template
|
||||
slot_count = template.get_slot_count()
|
||||
template.add_slot(new_slot)
|
||||
|
||||
with pytest.raises(ValueError):
|
||||
template.insert_slot(0, new_slot)
|
||||
with pytest.raises(ValueError):
|
||||
template.add_slot(new_slot)
|
||||
|
||||
def test_PassTemplate_InsertOrAddSlot_WithBadSlotData_ExceptionThrown(pass_slots_template):
|
||||
template = pass_slots_template
|
||||
slot_count = template.get_slot_count()
|
||||
bad_slot = json.loads('{\"slot\": \"xxx\"}')
|
||||
|
||||
with pytest.raises(KeyError):
|
||||
template.insert_slot(0, bad_slot)
|
||||
with pytest.raises(KeyError):
|
||||
template.add_slot(bad_slot)
|
||||
|
||||
def test_PassReqeuest_Initialize_WithExistPassReqeuestFromPassTemplate_Success(pass_requests_template):
|
||||
template = pass_requests_template
|
||||
request = PassRequest(template.get_pass_request('OpaquePass'))
|
||||
connection_count = request.get_connection_count()
|
||||
assert connection_count == 2
|
||||
|
||||
def test_PassTemplate_GetPassRequest_NotExist_ReturnNull(pass_requests_template):
|
||||
assert not pass_requests_template.get_pass_request('NotExistPass')
|
||||
|
||||
def test_PassReqeuest_AddConnection_WithExistingConnections_Success(pass_requests_template, new_connection):
|
||||
template = pass_requests_template
|
||||
request = PassRequest(template.get_pass_request('OpaquePass'))
|
||||
connection_count = request.get_connection_count()
|
||||
request.add_connection(new_connection)
|
||||
connection_count += 1
|
||||
assert request.get_connection_count() == connection_count
|
||||
|
||||
# verify changes are saved
|
||||
template.save()
|
||||
saved_tamplate = PassTemplate(template.file_path)
|
||||
saved_request = PassRequest(saved_tamplate.get_pass_request('OpaquePass'))
|
||||
assert saved_request.get_connection_count() == connection_count
|
||||
|
||||
def test_PassReqeuest_AddConnection_WithNoExistingConnections_Success(pass_requests_template, new_connection):
|
||||
template = pass_requests_template
|
||||
request = PassRequest(template.get_pass_request('ImGuiPass'))
|
||||
assert request.get_connection_count() == 0
|
||||
request.add_connection(new_connection)
|
||||
assert request.get_connection_count() == 1
|
||||
|
||||
# verify changes are saved
|
||||
template.save()
|
||||
saved_tamplate = PassTemplate(template.file_path)
|
||||
saved_request = PassRequest(saved_tamplate.get_pass_request('ImGuiPass'))
|
||||
assert saved_request.get_connection_count() == 1
|
||||
|
||||
def test_PassReqeuest_AddConnection_WithDuplicatedName_ExceptionThrown(pass_requests_template, new_connection):
|
||||
template = pass_requests_template
|
||||
request = PassRequest(template.get_pass_request('OpaquePass'))
|
||||
request.add_connection(new_connection)
|
||||
with pytest.raises(ValueError):
|
||||
request.add_connection(new_connection)
|
||||
|
||||
def test_PassReqeuest_AddConnect_BadConnectionData_ExceptionThrown(pass_requests_template, new_connection):
|
||||
template = pass_requests_template
|
||||
request = PassRequest(template.get_pass_request('OpaquePass'))
|
||||
bad_connection = json.loads('{\"xxx\": \"xxx\"}')
|
||||
with pytest.raises(KeyError):
|
||||
request.add_connection(bad_connection)
|
||||
|
||||
def test_PassTemplate_InsertSlot_ToEmptyList_Success(pass_requests_template, new_slot):
|
||||
template = pass_requests_template
|
||||
# test insert slot function to pass template which doesn't have any slots
|
||||
slot_count = template.get_slot_count()
|
||||
assert slot_count == 0
|
||||
|
||||
assert template.find_slot(new_slot['Name'])==-1
|
||||
pass_requests_template.insert_slot(0, new_slot)
|
||||
assert template.find_slot(new_slot['Name']) == 0
|
||||
assert template.get_slot_count() == 1
|
||||
|
||||
# verify changes are saved
|
||||
template.save()
|
||||
saved_tamplate = PassTemplate(template.file_path)
|
||||
assert saved_tamplate.get_slot_count() == 1
|
||||
|
||||
def test_PassTempalte_InsertPassRequest_ToEmptyList_Success(pass_slots_template, new_pass_request):
|
||||
template = pass_slots_template
|
||||
# test insert pass function to pass template which doesn't have any pass requests
|
||||
pass_count = template.get_pass_count()
|
||||
assert pass_count == 0
|
||||
template.insert_pass_request(0, new_pass_request)
|
||||
assert template.find_pass(new_pass_request['Name']) == 0
|
||||
assert template.get_pass_count() == 1
|
||||
|
||||
# verify changes are saved
|
||||
template.save()
|
||||
saved_tamplate = PassTemplate(template.file_path)
|
||||
assert saved_tamplate.get_pass_count() == 1
|
||||
|
||||
def test_PassTemplate_Save_Success(pass_requests_template):
|
||||
pass_requests_template.save()
|
||||
saved_tamplate = PassTemplate(pass_requests_template.file_path)
|
||||
assert os.path.exists(pass_requests_template.file_path)
|
||||
assert os.path.exists(pass_requests_template.file_path +'.backup')
|
||||
@ -0,0 +1,53 @@
|
||||
"""
|
||||
All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
its licensors.
|
||||
|
||||
For complete copyright and license terms please see the LICENSE at the root of this
|
||||
distribution (the "License"). All use of this software is governed by the License,
|
||||
or, if provided, by the license below or the license accompanying this file. Do not
|
||||
remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
||||
Unit tests for utils.py
|
||||
"""
|
||||
import pytest
|
||||
import os
|
||||
import atom_rpi_tools.utils as utils
|
||||
|
||||
|
||||
def test_FindOrCopyFile_DestFileNotExist_CopySuccess(tmpdir):
|
||||
# created dir and copied
|
||||
filename = 'pass_requests.json'
|
||||
source_path = os.path.join(os.path.dirname(__file__), 'testdata/', filename)
|
||||
dest_path = os.path.join(tmpdir, 'testdata/', 'pass_requests.json')
|
||||
assert not os.path.exists(dest_path)
|
||||
utils.find_or_copy_file(dest_path, source_path)
|
||||
assert os.path.exists(dest_path)
|
||||
source_size = os.path.getsize(source_path)
|
||||
dest_size = os.path.getsize(dest_path)
|
||||
assert source_size == dest_size
|
||||
|
||||
def test_FindOrCopyFile_DestFileAlreadyExists_Skip(tmpdir):
|
||||
# copy %cur_dir%/testdata/pass_requests.json to tempdir/testdata/pass_requests.json
|
||||
filename = 'pass_requests.json'
|
||||
source_path = os.path.join(os.path.dirname(__file__), 'testdata/', filename)
|
||||
dest_path = os.path.join(tmpdir, 'testdata/', 'pass_requests.json')
|
||||
utils.find_or_copy_file(dest_path, source_path)
|
||||
|
||||
# skip if dest_path already exists
|
||||
assert os.path.exists(dest_path)
|
||||
before_size = os.path.getsize(dest_path)
|
||||
source_path = os.path.join(os.path.dirname(__file__), 'testdata/', 'pass_slots.json')
|
||||
before_source_size = os.path.getsize(source_path)
|
||||
assert before_size != source_path
|
||||
utils.find_or_copy_file(dest_path, source_path)
|
||||
after_size = os.path.getsize(dest_path)
|
||||
assert before_size == after_size
|
||||
|
||||
|
||||
def test_FindOrCopyFile_SourceFileNotExists_ExceptionThrown(tmpdir):
|
||||
# report error if source doesn't exist
|
||||
bad_source_path = 'notexist.dat'
|
||||
dest_path = os.path.join(tmpdir, 'notexist.dat')
|
||||
with pytest.raises(ValueError):
|
||||
utils.find_or_copy_file(dest_path, bad_source_path)
|
||||
@ -0,0 +1,116 @@
|
||||
{
|
||||
"Type": "JsonSerialization",
|
||||
"Version": 1,
|
||||
"ClassName": "PassAsset",
|
||||
"ClassData": {
|
||||
"PassTemplate": {
|
||||
"Name": "PipelineTemplate",
|
||||
"PassClass": "ParentPass",
|
||||
"PassRequests": [
|
||||
{
|
||||
"Name": "OpaquePass",
|
||||
"TemplateName": "OpaquePassTemplate",
|
||||
"Connections": [
|
||||
{
|
||||
"LocalSlot": "DepthStencil",
|
||||
"AttachmentRef": {
|
||||
"Pass": "Parent",
|
||||
"Attachment": "DepthStencil"
|
||||
}
|
||||
},
|
||||
{
|
||||
"LocalSlot": "ColorInputOutput",
|
||||
"AttachmentRef": {
|
||||
"Pass": "Parent",
|
||||
"Attachment": "ColorInputOutput"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Name": "TransparentPass",
|
||||
"TemplateName": "TransparentPassTemplate",
|
||||
"Enabled": true,
|
||||
"Connections": [
|
||||
{
|
||||
"LocalSlot": "DepthStencil",
|
||||
"AttachmentRef": {
|
||||
"Pass": "OpaquePass",
|
||||
"Attachment": "DepthStencil"
|
||||
}
|
||||
},
|
||||
{
|
||||
"LocalSlot": "ColorInputOutput",
|
||||
"AttachmentRef": {
|
||||
"Pass": "OpaquePass",
|
||||
"Attachment": "Color"
|
||||
}
|
||||
}
|
||||
],
|
||||
"PassData": {
|
||||
"$type": "RasterPassData",
|
||||
"DrawListTag": "transparent",
|
||||
"DrawListSortType": "KeyThenReverseDepth",
|
||||
"PipelineViewTag": "MainCamera",
|
||||
"PassSrgAsset": {
|
||||
"FilePath": "shaderlib/atom/features/pbr/transparentpasssrg.azsli:PassSrg"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"Name": "AuxGeomPass",
|
||||
"TemplateName": "AuxGeomPassTemplate",
|
||||
"Enabled": true,
|
||||
"Connections": [
|
||||
{
|
||||
"LocalSlot": "DepthStencil",
|
||||
"AttachmentRef": {
|
||||
"Pass": "OpaquePass",
|
||||
"Attachment": "DepthStencil"
|
||||
}
|
||||
},
|
||||
{
|
||||
"LocalSlot": "ColorInputOutput",
|
||||
"AttachmentRef": {
|
||||
"Pass": "TransparentPass",
|
||||
"Attachment": "ColorInputOutput"
|
||||
}
|
||||
}
|
||||
],
|
||||
"PassData": {
|
||||
"$type": "RasterPassData",
|
||||
"DrawListTag": "auxgeom",
|
||||
"PipelineViewTag": "MainCamera"
|
||||
}
|
||||
},
|
||||
{
|
||||
"Name": "2DPass",
|
||||
"TemplateName": "UIPassTemplate",
|
||||
"Enabled": true,
|
||||
"Connections": [
|
||||
{
|
||||
"LocalSlot": "ColorInputOutput",
|
||||
"AttachmentRef": {
|
||||
"Pass": "TransparentPass",
|
||||
"Attachment": "ColorInputOutput"
|
||||
}
|
||||
}
|
||||
],
|
||||
"PassData": {
|
||||
"$type": "RasterPassData",
|
||||
"DrawListTag": "2dpass",
|
||||
"PipelineViewTag": "MainCamera"
|
||||
}
|
||||
},
|
||||
{
|
||||
"Name": "ImGuiPass",
|
||||
"TemplateName": "ImGuiPassTemplate",
|
||||
"PassData": {
|
||||
"$type": "ImGuiPassData",
|
||||
"IsDefaultImGui": true
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,21 @@
|
||||
{
|
||||
"Type": "JsonSerialization",
|
||||
"Version": 1,
|
||||
"ClassName": "PassAsset",
|
||||
"ClassData": {
|
||||
"PassTemplate": {
|
||||
"Name": "PipelineTemplate",
|
||||
"PassClass": "ParentPass",
|
||||
"Slots": [
|
||||
{
|
||||
"Name": "DepthStencil",
|
||||
"SlotType": "InputOutput"
|
||||
},
|
||||
{
|
||||
"Name": "ColorInputOutput",
|
||||
"SlotType": "InputOutput"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,6 @@
|
||||
{
|
||||
"Type": "JsonSerialization",
|
||||
"Version": 1,
|
||||
"ClassData": {
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,31 @@
|
||||
"""
|
||||
All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
its licensors.
|
||||
|
||||
For complete copyright and license terms please see the LICENSE at the root of this
|
||||
distribution (the "License"). All use of this software is governed by the License,
|
||||
or, if provided, by the license below or the license accompanying this file. Do not
|
||||
remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
"""
|
||||
import os.path
|
||||
from os import path
|
||||
import shutil
|
||||
import json
|
||||
|
||||
|
||||
def find_or_copy_file(destFilePath, sourceFilePath):
|
||||
if path.exists(destFilePath):
|
||||
return
|
||||
if not path.exists(sourceFilePath):
|
||||
raise ValueError('find_or_copy_file: source file [', sourceFilePath, '] doesn\'t exist')
|
||||
return
|
||||
|
||||
dstDir = path.dirname(destFilePath)
|
||||
if not path.isdir(dstDir):
|
||||
os.makedirs(dstDir)
|
||||
shutil.copyfile(sourceFilePath, destFilePath)
|
||||
|
||||
def load_json_file(filePath):
|
||||
file_stream = open(filePath, "r")
|
||||
return json.load(file_stream)
|
||||
@ -0,0 +1,33 @@
|
||||
"""
|
||||
All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
its licensors.
|
||||
|
||||
For complete copyright and license terms please see the LICENSE at the root of this
|
||||
distribution (the "License"). All use of this software is governed by the License,
|
||||
or, if provided, by the license below or the license accompanying this file. Do not
|
||||
remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
"""
|
||||
import os
|
||||
import platform
|
||||
|
||||
from setuptools import setup, find_packages
|
||||
|
||||
PROJECT_ROOT = os.path.abspath(os.path.dirname(__file__))
|
||||
|
||||
PYTHON_64 = platform.architecture()[0] == '64bit'
|
||||
|
||||
if __name__ == '__main__':
|
||||
if not PYTHON_64:
|
||||
raise RuntimeError("32-bit Python is not a supported platform.")
|
||||
|
||||
with open(os.path.join(PROJECT_ROOT, 'README.txt')) as f:
|
||||
long_description = f.read()
|
||||
|
||||
setup(
|
||||
name="atom_rpi_tools",
|
||||
version="1.0.0",
|
||||
description='Python interface to Atom RPI tools',
|
||||
long_description=long_description,
|
||||
packages=find_packages(exclude=['tests'])
|
||||
)
|
||||
Loading…
Reference in New Issue