Add IMateriaSource interface and an implementation
authorLukas Jiriste <ljiriste@student.42prague.com>
Fri, 25 Oct 2024 13:17:27 +0000 (15:17 +0200)
committerLukas Jiriste <ljiriste@student.42prague.com>
Fri, 25 Oct 2024 13:27:35 +0000 (15:27 +0200)
I'm a little torn whether to provide the assignment operator.
The AMateria has const member which forbids any meaningful assignment,
the MateriaSource however does not have any such limitation.
I think the MateriaSource would not by able to be changed "in-game" and
making assignment not possible conveys this idea.
But the assignment could be useful for object reuse...
I left the assignment operator private, but provided implementation to
not make future laziness stand in the way of change.

ex03/IMateriaSource.h [new file with mode: 0644]
ex03/MateriaSource.cpp [new file with mode: 0644]
ex03/MateriaSource.h [new file with mode: 0644]

diff --git a/ex03/IMateriaSource.h b/ex03/IMateriaSource.h
new file mode 100644 (file)
index 0000000..fbd16af
--- /dev/null
@@ -0,0 +1,13 @@
+#ifndef IMATERIASOURCE_H
+# define IMATERIASOURCE_H
+
+class IMateriaSource
+{
+       public:
+               virtual ~IMateriaSource() {}
+
+               virtual void            leanMateria(AMateria *) = 0;
+               virtual AMateria        *createMateria(const std::string &type) = 0;
+};
+
+#endif // IMATERIASOURCE_H
diff --git a/ex03/MateriaSource.cpp b/ex03/MateriaSource.cpp
new file mode 100644 (file)
index 0000000..c97a13f
--- /dev/null
@@ -0,0 +1,48 @@
+#include "MateriaSource.h"
+
+MateriaSource::MateriaSource()
+       : m_num_known(0)
+{
+       for (size_t i(0); i < max_known; ++i)
+               m_known_materia[i] = NULL;
+}
+
+MateriaSource::MateriaSource(const MateriaSource &other)
+       : m_num_known(0)
+{
+       *this = other;
+}
+
+MateriaSource::~MateriaSource()
+{
+       deleteKnown();
+}
+
+void   MateriaSource::deleteKnown()
+{
+       for (; m_num_know > 0;)
+               delete m_known_materia[--m_num_known];
+}
+
+MateriaSource  &MateriaSource::operator=(const MateriaSource &other)
+{
+       deleteKnown();
+       for (; m_num_known < other.m_num_known; ++m_num_known)
+               m_known_materia[m_num_known] = other.m_known_materia[m_num_known]->clone();
+}
+
+void   MateriaSource::learnMateria(AMateria *materia)
+{
+       if (m_num_known == max_known)
+               return ;
+       m_known_materia[m_num_known] = materia->clone();
+       ++m_num_known;
+}
+
+AMateria       *MateriaSource::createMateria(const std::string &type)
+{
+       for (size_t i(0); i < m_num_known; ++i)
+               if (m_known_materia[i] == type)
+                       return (m_known_materia[i]->clone());
+       return (NULL);
+}
diff --git a/ex03/MateriaSource.h b/ex03/MateriaSource.h
new file mode 100644 (file)
index 0000000..72fedf1
--- /dev/null
@@ -0,0 +1,26 @@
+#ifndef MATERIASOURCE_H
+# define MATERIASOURCE_H
+
+# include "AMateria.h"
+# include "IMateriaSource.h"
+
+class MateriaSource : IMateriaSource
+{
+       private:
+               MateriaSource   &operator=(const MateriaSource &other);
+
+               static const size_t     max_known = 4;
+
+               AMateria        *m_known_materia[max_known];
+               size_t          m_num_known;
+
+       public:
+               MateriaSource();
+               MateriaSource(const MateriaSource &other);
+               ~MateriaSource();
+
+               void            learnMateria(AMateria *materia);
+               AMateria        *createMateria(const std::string &type);
+};
+
+#endif // MATERIASOURCE_H